diff --git a/test/test_model/test_structural_mechanics_model/CMakeLists.txt b/test/test_model/test_structural_mechanics_model/CMakeLists.txt index 46000bf54..856cd66ea 100644 --- a/test/test_model/test_structural_mechanics_model/CMakeLists.txt +++ b/test/test_model/test_structural_mechanics_model/CMakeLists.txt @@ -1,63 +1,68 @@ #=============================================================================== # @file CMakeLists.txt # # @author Fabian Barras # # @date creation: Fri Sep 03 2010 # @date last modification: Mon Dec 07 2015 # # @brief Structural Mechanics Model Tests # # @section LICENSE # # Copyright (©) 2010-2012, 2014, 2015 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 . # #=============================================================================== # Adding sources register_gtest_sources( SOURCES test_structural_mechanics_model_bernoulli_beam_2.cc PACKAGE implicit structural_mechanics ) register_gtest_sources( SOURCES test_structural_mechanics_model_bernoulli_beam_3.cc PACKAGE implicit structural_mechanics ) +register_gtest_sources( + SOURCES test_structural_mechanics_model_discrete_kirchhoff_triangle_18.cc + PACKAGE implicit structural_mechanics +) + #=============================================================================== # Adding meshes for element types package_get_element_types(structural_mechanics _types) foreach(_type ${_types}) if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${_type}.msh) list(APPEND _meshes ${_type}.msh) #register_fem_test(fe_engine_precomputation ${_type }) else() if(NOT ${_type} STREQUAL _point_1) message("The mesh ${_type}.msh is missing, the fe_engine test cannot be activated without it") endif() endif() endforeach() #=============================================================================== # Registering google test register_gtest_test(test_structural_mechanics FILES_TO_COPY ${_meshes}) diff --git a/test/test_model/test_structural_mechanics_model/_discrete_kirchhoff_triangle_18.msh b/test/test_model/test_structural_mechanics_model/_discrete_kirchhoff_triangle_18.msh index 741047074..03e36a496 100644 --- a/test/test_model/test_structural_mechanics_model/_discrete_kirchhoff_triangle_18.msh +++ b/test/test_model/test_structural_mechanics_model/_discrete_kirchhoff_triangle_18.msh @@ -1,50 +1,18 @@ $MeshFormat 2.2 0 8 $EndMeshFormat $Nodes -13 +5 1 0 0 0 -2 1 0 0 -3 1 1 0 -4 0 1 0 -5 0.4999999999990217 0 0 -6 1 0.4999999999990217 0 -7 0.5000000000013878 1 0 -8 0 0.5000000000013878 0 -9 0.5000000000000262 0.5000000000000762 0 -10 0.2500000000004626 0.7500000000004626 0 -11 0.7500000000004626 0.7499999999996739 0 -12 0.7499999999996739 0.2499999999996739 0 -13 0.24999999999961 0.2500000000004752 0 +2 40 0 0 +3 40 20 0 +4 0 20 0 +5 15 15 0 $EndNodes $Elements -28 -1 15 2 0 101 1 -2 15 2 0 102 2 -3 15 2 0 103 3 -4 15 2 0 104 4 -5 1 2 0 101 1 5 -6 1 2 0 101 5 2 -7 1 2 0 102 2 6 -8 1 2 0 102 6 3 -9 1 2 0 103 3 7 -10 1 2 0 103 7 4 -11 1 2 0 104 4 8 -12 1 2 0 104 8 1 -13 2 2 0 101 4 10 7 -14 2 2 0 101 1 13 8 -15 2 2 0 101 3 11 6 -16 2 2 0 101 2 12 5 -17 2 2 0 101 8 9 10 -18 2 2 0 101 7 10 9 -19 2 2 0 101 7 9 11 -20 2 2 0 101 8 13 9 -21 2 2 0 101 6 11 9 -22 2 2 0 101 5 9 13 -23 2 2 0 101 5 12 9 -24 2 2 0 101 6 9 12 -25 2 2 0 101 1 5 13 -26 2 2 0 101 4 8 10 -27 2 2 0 101 2 6 12 -28 2 2 0 101 3 7 11 +4 +1 2 2 1 1 1 5 2 +2 2 2 1 2 2 5 3 +3 2 2 1 3 3 4 5 +4 2 2 1 4 1 4 5 $EndElements diff --git a/test/test_model/test_structural_mechanics_model/test_structural_mechanics_model_bernoulli_beam_2.cc b/test/test_model/test_structural_mechanics_model/test_structural_mechanics_model_bernoulli_beam_2.cc index 0883df322..8337bb9c2 100644 --- a/test/test_model/test_structural_mechanics_model/test_structural_mechanics_model_bernoulli_beam_2.cc +++ b/test/test_model/test_structural_mechanics_model/test_structural_mechanics_model_bernoulli_beam_2.cc @@ -1,113 +1,114 @@ /** * @file test_structural_mechanics_model_bernoulli_beam_2.cc * * @author Fabian Barras * @author Lucas Frérot * * @date creation: Fri Jul 15 2011 * @date last modification: Sun Oct 19 2014 * * @brief Computation of the analytical exemple 1.1 in the TGC vol 6 * * @section LICENSE * * Copyright (©) 2010-2012, 2014, 2015 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_structural_mechanics_model_fixture.hh" /* -------------------------------------------------------------------------- */ #include using namespace akantu; /* -------------------------------------------------------------------------- */ class TestStructBernoulli2 : public TestStructuralFixture> { using parent = TestStructuralFixture>; public: void addMaterials() override { mat.E = 3e10; mat.I = 0.0025; mat.A = 0.01; this->model->addMaterial(mat); mat.E = 3e10; mat.I = 0.00128; mat.A = 0.01; this->model->addMaterial(mat); } void assignMaterials() override { auto & materials = this->model->getElementMaterial(parent::type); materials(0) = 0; materials(1) = 1; } void setDirichlets() override { auto boundary = this->model->getBlockedDOFs().begin(parent::ndof); // clang-format off *boundary = {true, true, true}; ++boundary; *boundary = {false, true, false}; ++boundary; *boundary = {false, true, false}; ++boundary; // clang-format on } void setNeumanns() override { Real M = 3600; // Nm Real q = -6000; // kN/m Real L = 10; // m auto & forces = this->model->getExternalForce(); forces(2, 2) = -M; // moment on last node #if 1 // as long as integration is not available forces(0, 1) = q * L / 2; forces(0, 2) = q * L * L / 12; forces(1, 1) = q * L / 2; forces(1, 2) = -q * L * L / 12; #else auto & group = mesh.createElementGroup("lin_force"); group.add({type, 0, _not_ghost}); Vector lin_force = {0, q, 0}; // a linear force is not actually a *boundary* condition // it is equivalent to a volume force model.applyBC(BC::Neumann::FromSameDim(lin_force), group); #endif forces(2, 0) = mat.E * mat.A / 18; } protected: StructuralMaterial mat; }; /* -------------------------------------------------------------------------- */ TEST_F(TestStructBernoulli2, TestDisplacements) { + model->solveStep(); auto d1 = model->getDisplacement()(1, 2); auto d2 = model->getDisplacement()(2, 2); auto d3 = model->getDisplacement()(1, 0); Real tol = Math::getTolerance(); EXPECT_NEAR(d1, 5.6 / 4800, tol); // first rotation EXPECT_NEAR(d2, -3.7 / 4800, tol); // second rotation EXPECT_NEAR(d3, 10. / 18, tol); // axial deformation } diff --git a/test/test_model/test_structural_mechanics_model/test_structural_mechanics_model_bernoulli_beam_3.cc b/test/test_model/test_structural_mechanics_model/test_structural_mechanics_model_bernoulli_beam_3.cc index 7e522852a..b3e649e5e 100644 --- a/test/test_model/test_structural_mechanics_model/test_structural_mechanics_model_bernoulli_beam_3.cc +++ b/test/test_model/test_structural_mechanics_model/test_structural_mechanics_model_bernoulli_beam_3.cc @@ -1,99 +1,100 @@ /** * @file test_structural_mechanics_model_bernoulli_beam_3.cc * * @author Lucas Frérot * * @date creation: Mon Jan 22 2018 * * @brief Computation of the analytical exemple 1.1 in the TGC vol 6 * * @section LICENSE * * Copyright (©) 2010-2012, 2014, 2015 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_structural_mechanics_model_fixture.hh" /* -------------------------------------------------------------------------- */ #include /* -------------------------------------------------------------------------- */ using namespace akantu; class TestStructBernoulli3 : public TestStructuralFixture> { using parent = TestStructuralFixture>; public: void readMesh(std::string filename) override { parent::readMesh(filename); auto & normals = this->mesh->registerData("extra_normal") .alloc(0, parent::spatial_dimension, parent::type, _not_ghost); Vector normal = {0, 0, 1}; normals.push_back(normal); normal = {0, 0, 1}; normals.push_back(normal); } void addMaterials() override { StructuralMaterial mat; mat.E = 1; mat.Iz = 1; mat.Iy = 1; mat.A = 1; mat.GJ = 1; this->model->addMaterial(mat); } void setDirichlets() { // Boundary conditions (blocking all DOFs of nodes 2 & 3) auto boundary = ++this->model->getBlockedDOFs().begin(parent::ndof); // clang-format off *boundary = {true, true, true, true, true, true}; ++boundary; *boundary = {true, true, true, true, true, true}; ++boundary; // clang-format on } void setNeumanns() override { // Forces Real P = 1; // N auto & forces = this->model->getExternalForce(); forces.clear(); forces(0, 2) = -P; // vertical force on first node } void assignMaterials() override { model->getElementMaterial(parent::type).set(0); } }; /* -------------------------------------------------------------------------- */ TEST_F(TestStructBernoulli3, TestDisplacements) { + model->solveStep(); auto vz = model->getDisplacement()(0, 2); auto thy = model->getDisplacement()(0, 4); auto thx = model->getDisplacement()(0, 3); auto thz = model->getDisplacement()(0, 5); Real tol = Math::getTolerance(); EXPECT_NEAR(vz, -5. / 48, tol); EXPECT_NEAR(thy, -std::sqrt(2) / 8, tol); EXPECT_NEAR(thz, 0, tol); EXPECT_NEAR(thx, 0, tol); } diff --git a/test/test_model/test_structural_mechanics_model/test_structural_mechanics_model_bernoulli_beam_2.cc b/test/test_model/test_structural_mechanics_model/test_structural_mechanics_model_discrete_kirchhoff_triangle_18.cc similarity index 54% copy from test/test_model/test_structural_mechanics_model/test_structural_mechanics_model_bernoulli_beam_2.cc copy to test/test_model/test_structural_mechanics_model/test_structural_mechanics_model_discrete_kirchhoff_triangle_18.cc index 0883df322..bac1f8c70 100644 --- a/test/test_model/test_structural_mechanics_model/test_structural_mechanics_model_bernoulli_beam_2.cc +++ b/test/test_model/test_structural_mechanics_model/test_structural_mechanics_model_discrete_kirchhoff_triangle_18.cc @@ -1,113 +1,101 @@ /** * @file test_structural_mechanics_model_bernoulli_beam_2.cc * * @author Fabian Barras * @author Lucas Frérot * * @date creation: Fri Jul 15 2011 * @date last modification: Sun Oct 19 2014 * * @brief Computation of the analytical exemple 1.1 in the TGC vol 6 * * @section LICENSE * * Copyright (©) 2010-2012, 2014, 2015 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_structural_mechanics_model_fixture.hh" /* -------------------------------------------------------------------------- */ #include using namespace akantu; /* -------------------------------------------------------------------------- */ -class TestStructBernoulli2 - : public TestStructuralFixture> { - using parent = TestStructuralFixture>; +class TestStructDKT18 + : public TestStructuralFixture> { + using parent = TestStructuralFixture>; public: void addMaterials() override { - mat.E = 3e10; - mat.I = 0.0025; - mat.A = 0.01; - - this->model->addMaterial(mat); - - mat.E = 3e10; - mat.I = 0.00128; - mat.A = 0.01; + mat.E = 1; + mat.t = 1; + mat.nu = 0.3; this->model->addMaterial(mat); } void assignMaterials() override { auto & materials = this->model->getElementMaterial(parent::type); - materials(0) = 0; - materials(1) = 1; + std::fill(materials.begin(), materials.end(), 0); } void setDirichlets() override { - auto boundary = this->model->getBlockedDOFs().begin(parent::ndof); + std::fill(this->model->getBlockedDOFs().begin(), + this->model->getBlockedDOFs().end(), true); + auto center_node = this->model->getBlockedDOFs().end(parent::ndof) - 1; // clang-format off - *boundary = {true, true, true}; ++boundary; - *boundary = {false, true, false}; ++boundary; - *boundary = {false, true, false}; ++boundary; + *center_node = {false, false, false, false, false, true}; // clang-format on - } - void setNeumanns() override { - Real M = 3600; // Nm - Real q = -6000; // kN/m - Real L = 10; // m - auto & forces = this->model->getExternalForce(); - forces(2, 2) = -M; // moment on last node -#if 1 // as long as integration is not available - forces(0, 1) = q * L / 2; - forces(0, 2) = q * L * L / 12; - forces(1, 1) = q * L / 2; - forces(1, 2) = -q * L * L / 12; -#else - auto & group = mesh.createElementGroup("lin_force"); - group.add({type, 0, _not_ghost}); - Vector lin_force = {0, q, 0}; - // a linear force is not actually a *boundary* condition - // it is equivalent to a volume force - model.applyBC(BC::Neumann::FromSameDim(lin_force), group); -#endif - forces(2, 0) = mat.E * mat.A / 18; + this->model->getDisplacement().clear(); + auto disp = ++this->model->getDisplacement().begin(parent::ndof); + + // Displacement field from Batoz Vol. 2 p. 392 + // with theta to beta correction from discrete Kirchhoff condition + //clang-format off + *disp = {40, 20, -800 , -20, 40, 0}; ++disp; + *disp = {50, 40, -1400, -40, 50, 0}; ++disp; + *disp = {10, 20, -200 , -20, 10, 0}; ++disp; + //clang-format on } + void setNeumanns() override {} + protected: StructuralMaterial mat; }; /* -------------------------------------------------------------------------- */ -TEST_F(TestStructBernoulli2, TestDisplacements) { - auto d1 = model->getDisplacement()(1, 2); - auto d2 = model->getDisplacement()(2, 2); - auto d3 = model->getDisplacement()(1, 0); +// Batoz Vol 2. patch test, ISBN 2-86601-259-3 + +TEST_F(TestStructDKT18, TestDisplacements) { + model->solveStep(); + Vector solution = {22.5, 22.5, -337.5, -22.5, 22.5, 0}; + + Vector center_node_disp = + model->getDisplacement().end(model->getSpatialDimension())[-1]; + + auto error = solution - center_node_disp; Real tol = Math::getTolerance(); - EXPECT_NEAR(d1, 5.6 / 4800, tol); // first rotation - EXPECT_NEAR(d2, -3.7 / 4800, tol); // second rotation - EXPECT_NEAR(d3, 10. / 18, tol); // axial deformation + EXPECT_NEAR(error.norm(), 0., tol); } diff --git a/test/test_model/test_structural_mechanics_model/test_structural_mechanics_model_fixture.hh b/test/test_model/test_structural_mechanics_model/test_structural_mechanics_model_fixture.hh index cd92c3e5d..a1f5f221e 100644 --- a/test/test_model/test_structural_mechanics_model/test_structural_mechanics_model_fixture.hh +++ b/test/test_model/test_structural_mechanics_model/test_structural_mechanics_model_fixture.hh @@ -1,76 +1,75 @@ /* -------------------------------------------------------------------------- */ #include "element_class_structural.hh" #include "structural_mechanics_model.hh" #include "test_gtest_utils.hh" /* -------------------------------------------------------------------------- */ #include #include /* -------------------------------------------------------------------------- */ #ifndef __AKANTU_TEST_STRUCTURAL_MECHANICS_MODEL_FIXTURE_HH__ #define __AKANTU_TEST_STRUCTURAL_MECHANICS_MODEL_FIXTURE_HH__ using namespace akantu; template class TestStructuralFixture : public ::testing::Test { public: static constexpr const ElementType type = type_::value; static constexpr const size_t spatial_dimension = ElementClass::getSpatialDimension(); static const UInt ndof = ElementClass::getNbDegreeOfFreedom(); void SetUp() override { const auto spatial_dimension = this->spatial_dimension; mesh = std::make_unique(spatial_dimension); readMesh(makeMeshName()); std::stringstream element_type; element_type << this->type; model = std::make_unique(*mesh, _all_dimensions, element_type.str()); addMaterials(); model->initFull(); assignMaterials(); setDirichlets(); setNeumanns(); - model->solveStep(); } virtual void readMesh(std::string filename) { mesh->read(filename, _miot_gmsh_struct); } virtual std::string makeMeshName() { std::stringstream element_type; element_type << type; SCOPED_TRACE(element_type.str().c_str()); return element_type.str() + ".msh"; } void TearDown() override { model.reset(nullptr); mesh.reset(nullptr); } virtual void addMaterials() = 0; virtual void assignMaterials() = 0; virtual void setDirichlets() = 0; virtual void setNeumanns() = 0; protected: std::unique_ptr mesh; std::unique_ptr model; }; template constexpr ElementType TestStructuralFixture::type; template constexpr size_t TestStructuralFixture::spatial_dimension; template const UInt TestStructuralFixture::ndof; // using types = gtest_list_t; // TYPED_TEST_CASE(TestStructuralFixture, types); #endif /* __AKANTU_TEST_STRUCTURAL_MECHANICS_MODEL_FIXTURE_HH__ */