diff --git a/src/fe_engine/element_classes/element_class_bernoulli_beam_inline_impl.cc b/src/fe_engine/element_classes/element_class_bernoulli_beam_inline_impl.cc index 511eb3d9b..407cb0af0 100644 --- a/src/fe_engine/element_classes/element_class_bernoulli_beam_inline_impl.cc +++ b/src/fe_engine/element_classes/element_class_bernoulli_beam_inline_impl.cc @@ -1,225 +1,222 @@ /** * @file element_class_bernoulli_beam_inline_impl.cc * * @author Fabian Barras * * @date creation: Fri Jul 15 2011 * @date last modification: Sun Oct 19 2014 * * @brief Specialization of the element_class class for the type _bernoulli_beam_2 * * @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 . * * @section DESCRIPTION * * @verbatim --x-----q1----|----q2-----x---> x -1 0 1 @endverbatim * */ /* -------------------------------------------------------------------------- */ #include "aka_static_if.hh" #include "element_class_structural.hh" //#include "aka_element_classes_info.hh" /* -------------------------------------------------------------------------- */ #ifndef __AKANTU_ELEMENT_CLASS_BERNOULLI_BEAM_INLINE_IMPL_CC__ #define __AKANTU_ELEMENT_CLASS_BERNOULLI_BEAM_INLINE_IMPL_CC__ namespace akantu { /* -------------------------------------------------------------------------- */ AKANTU_DEFINE_STRUCTURAL_INTERPOLATION_TYPE_PROPERTY(_itp_bernoulli_beam_2, _itp_lagrange_segment_2, 3, 2, 6); AKANTU_DEFINE_STRUCTURAL_INTERPOLATION_TYPE_PROPERTY(_itp_bernoulli_beam_3, _itp_lagrange_segment_2, 6, 4, 6); AKANTU_DEFINE_STRUCTURAL_ELEMENT_CLASS_PROPERTY(_bernoulli_beam_2, _gt_segment_2, _itp_bernoulli_beam_2, _segment_2, _ek_structural, 2, _git_segment, 3); AKANTU_DEFINE_STRUCTURAL_ELEMENT_CLASS_PROPERTY(_bernoulli_beam_3, _gt_segment_2, _itp_bernoulli_beam_3, _segment_2, _ek_structural, 3, _git_segment, 3); /* -------------------------------------------------------------------------- */ template <> inline void InterpolationElement<_itp_bernoulli_beam_2, _itk_structural>::computeShapes( const Vector & natural_coords, const Matrix & real_coord, Matrix & N) { Vector L(2); InterpolationElement<_itp_lagrange_segment_2, _itk_lagrangian>::computeShapes( natural_coords, L); Matrix H(2, 4); InterpolationElement<_itp_hermite_2, _itk_structural>::computeShapes( natural_coords, real_coord, H); // clang-format off // u1 v1 t1 u2 v2 t2 N = {{L(0), 0 , 0 , L(1), 0 , 0 }, // u {0 , H(0, 0), H(0, 1), 0 , H(0, 2), H(0, 3)}, // v {0 , H(1, 0), H(1, 1), 0 , H(1, 2), H(1, 3)}}; // theta // clang-format on } template <> inline void InterpolationElement<_itp_bernoulli_beam_3, _itk_structural>::computeShapes( const Vector & natural_coords, const Matrix & real_coord, Matrix & N) { Vector L(2); InterpolationElement<_itp_lagrange_segment_2, _itk_lagrangian>::computeShapes( natural_coords, L); Matrix H(2, 4); InterpolationElement<_itp_hermite_2, _itk_structural>::computeShapes( natural_coords, real_coord, H); // clang-format off // u1 v1 w1 x1 y1 z1 u2 v2 w2 x2 y2 z2 N = {{L(0), 0 , 0 , 0 , 0 , 0 , L(1), 0 , 0 , 0 , 0 , 0 }, // u {0 , H(0, 0), 0 , 0 , H(0, 1), 0 , 0 , H(0, 2), 0 , 0 , H(0, 3), 0 }, // v {0 , 0 , H(0, 0), 0 , 0 , H(0, 1), 0 , 0 , H(0, 2), 0 , 0 , H(0, 3)}, // w {0 , 0 , 0 , L(0), 0 , 0 , 0 , 0 , 0 , L(1), 0 , 0 }, // thetax {0 , H(1, 0), 0 , 0 , H(1, 1), 0 , 0 , H(1, 2), 0 , 0 , H(1, 3), 0 }, // thetay {0 , 0 , H(1, 0), 0 , 0 , H(1, 1), 0 , 0 , H(1, 2), 0 , 0 , H(1, 3)}}; // thetaz // clang-format on } /* -------------------------------------------------------------------------- */ template <> inline void InterpolationElement<_itp_bernoulli_beam_2, _itk_structural>::computeDNDS( const Vector & natural_coords, const Matrix & real_coord, Matrix & dnds) { Matrix L(1, 2); InterpolationElement<_itp_lagrange_segment_2, _itk_lagrangian>::computeDNDS( natural_coords, L); Matrix H(1, 4); InterpolationElement<_itp_hermite_2, _itk_structural>::computeDNDS( natural_coords, real_coord, H); - Matrix deriv(1, 6); - // Storing the derivatives in dnds - deriv.block(L, 0, 0); - deriv.block(H, 0, 2); - dnds.deepCopy(deriv); + dnds.block(L, 0, 0); + dnds.block(H, 0, 2); } /* -------------------------------------------------------------------------- */ template <> inline void InterpolationElement<_itp_bernoulli_beam_2, _itk_structural>::arrangeInVoigt( const Matrix & dnds, Matrix & B) { auto L = dnds.block(0, 0, 1, 2); // Lagrange shape derivatives auto H = dnds.block(0, 2, 1, 4); // Hermite shape derivatives // clang-format off // u1 v1 t1 u2 v2 t2 B = {{L(0, 0), 0, 0, L(0, 1), 0, 0 }, {0, H(0, 0), H(0, 1), 0, H(0, 2), H(0, 3)}}; // clang-format on } /* -------------------------------------------------------------------------- */ template <> inline void InterpolationElement<_itp_bernoulli_beam_3, _itk_structural>::computeDNDS( const Vector & natural_coords, const Matrix & real_coord, Matrix & dnds) { InterpolationElement<_itp_bernoulli_beam_2, _itk_structural>::computeDNDS( natural_coords, real_coord, dnds); } /* -------------------------------------------------------------------------- */ template <> inline void InterpolationElement<_itp_bernoulli_beam_3, _itk_structural>::arrangeInVoigt( const Matrix & dnds, Matrix & B) { auto L = dnds.block(0, 0, 1, 2); // Lagrange shape derivatives auto H = dnds.block(0, 2, 1, 4); // Hermite shape derivatives // clang-format off // u1 v1 w1 x1 y1 z1 u2 v2 w2 x2 y2 z2 B = {{L(0, 0), 0 , 0 , 0 , 0 , 0 , L(0, 1), 0 , 0 , 0 , 0 , 0 }, // eps {0 , H(0, 0), 0 , 0 , 0 , H(0, 1), 0 , H(0, 2), 0 , 0 , 0 , H(0, 3)}, // chi strong axis {0 , 0 ,-H(0, 0), 0 , H(0, 1), 0 , 0 , 0 ,-H(0, 2), 0 , H(0, 3), 0 }, // chi weak axis {0 , 0 , 0 , L(0, 0), 0 , 0 , 0 , 0 , 0 , L(0, 1), 0 , 0 }}; // chi torsion // clang-format on } /* -------------------------------------------------------------------------- */ template <> inline void ElementClass<_bernoulli_beam_2>::computeRotationMatrix( Matrix & R, const Matrix & X, const Vector &) { Vector x2 = X(1); // X2 Vector x1 = X(0); // X1 auto cs = (x2 - x1); cs.normalize(); auto c = cs(0); auto s = cs(1); // clang-format off /// Definition of the rotation matrix R = {{ c, s, 0.}, {-s, c, 0.}, { 0., 0., 1.}}; // clang-format on } /* -------------------------------------------------------------------------- */ template <> inline void ElementClass<_bernoulli_beam_3>::computeRotationMatrix( Matrix & R, const Matrix & X, const Vector & n) { Vector x2 = X(1); // X2 Vector x1 = X(0); // X1 auto dim = X.rows(); auto x = (x2 - x1); x.normalize(); auto x_n = x.crossProduct(n); Matrix Pe = {{1., 0., 0.}, {0., -1., 0.}, {0., 0., 1.}}; Matrix Pg(dim, dim); Pg(0) = x; Pg(1) = x_n; Pg(2) = n; Pe *= Pg.inverse(); R.clear(); /// Definition of the rotation matrix for (UInt i = 0; i < dim; ++i) for (UInt j = 0; j < dim; ++j) R(i + dim, j + dim) = R(i, j) = Pe(i, j); } } // namespace akantu #endif /* __AKANTU_ELEMENT_CLASS_BERNOULLI_BEAM_INLINE_IMPL_CC__ */ diff --git a/src/fe_engine/element_classes/element_class_kirchhoff_shell_inline_impl.cc b/src/fe_engine/element_classes/element_class_kirchhoff_shell_inline_impl.cc index 260364a96..6818c8ddc 100644 --- a/src/fe_engine/element_classes/element_class_kirchhoff_shell_inline_impl.cc +++ b/src/fe_engine/element_classes/element_class_kirchhoff_shell_inline_impl.cc @@ -1,209 +1,211 @@ /** * @file element_class_kirchhoff_shell_inline_impl.cc * * @author Damien Spielmann * * @date creation: Fri Jul 04 2014 * @date last modification: Sun Oct 19 2014 * * @brief Element class Kirchhoff Shell * * @section LICENSE * * Copyright (©) 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 "element_class_structural.hh" /* -------------------------------------------------------------------------- */ #ifndef __AKANTU_ELEMENT_CLASS_KIRCHHOFF_SHELL_INLINE_IMPL_CC__ #define __AKANTU_ELEMENT_CLASS_KIRCHHOFF_SHELL_INLINE_IMPL_CC__ namespace akantu { /* -------------------------------------------------------------------------- */ AKANTU_DEFINE_STRUCTURAL_INTERPOLATION_TYPE_PROPERTY( _itp_discrete_kirchhoff_triangle_18, _itp_lagrange_triangle_3, 6, 6, 21); AKANTU_DEFINE_STRUCTURAL_ELEMENT_CLASS_PROPERTY( _discrete_kirchhoff_triangle_18, _gt_triangle_3, _itp_discrete_kirchhoff_triangle_18, _triangle_3, _ek_structural, 3, _git_triangle, 2); /* -------------------------------------------------------------------------- */ namespace detail { inline void computeBasisChangeMatrix(Matrix & P, const Matrix & X) { Vector X1 = X(0); Vector X2 = X(1); Vector X3 = X(2); Vector a1 = X2 - X1; Vector a2 = X3 - X1; a1.normalize(); Vector e3 = a1.crossProduct(a2); e3.normalize(); Vector e2 = e3.crossProduct(a1); P(0) = a1; P(1) = e2; P(2) = e3; } } /* -------------------------------------------------------------------------- */ template <> inline void ElementClass<_discrete_kirchhoff_triangle_18>::computeRotationMatrix( Matrix & R, const Matrix & X, const Vector &) { auto dim = X.rows(); Matrix P(dim, dim); detail::computeBasisChangeMatrix(P, X); R.clear(); for (UInt i = 0; i < dim; ++i) for (UInt j = 0; j < dim; ++j) R(i + dim, j + dim) = R(i, j) = P(j, i); } /* -------------------------------------------------------------------------- */ template <> inline void InterpolationElement<_itp_discrete_kirchhoff_triangle_18>::computeShapes( const Vector & /*natural_coords*/, const Matrix & /*real_coord*/, Matrix & /*N*/) {} /* -------------------------------------------------------------------------- */ template <> inline void InterpolationElement<_itp_discrete_kirchhoff_triangle_18>::computeDNDS( const Vector & natural_coords, const Matrix & real_coordinates, Matrix & B) { auto dim = real_coordinates.cols(); Matrix P(dim, dim); detail::computeBasisChangeMatrix(P, real_coordinates); auto X = P * real_coordinates; Vector X1 = X(0); Vector X2 = X(1); Vector X3 = X(2); std::array, 3> A = {X2 - X1, X3 - X2, X1 - X3}; std::array L, C, S; // Setting all last coordinates to 0 std::for_each(A.begin(), A.end(), [](auto & a) { a(2) = 0; }); // Computing lengths std::transform(A.begin(), A.end(), L.begin(), [](Vector & a) { return a.norm(); }); // Computing cosines std::transform(A.begin(), A.end(), L.begin(), C.begin(), [](Vector & a, Real & l) { return a(0) / l; }); // Computing sines std::transform(A.begin(), A.end(), L.begin(), S.begin(), [](Vector & a, Real & l) { return a(1) / l; }); // Natural coordinates Real xi = natural_coords(0); Real eta = natural_coords(1); // Derivative of quadratic interpolation functions Matrix dP = {{4 * (1 - 2 * xi - eta), 4 * eta, -4 * eta}, {-4 * xi, 4 * xi, 4 * (1 - xi - 2 * eta)}}; Matrix dNx1 = { {3. / 2 * (dP(0, 0) * C[0] / L[0] - dP(0, 2) * C[2] / L[2]), 3. / 2 * (dP(0, 1) * C[1] / L[1] - dP(0, 0) * C[0] / L[0]), 3. / 2 * (dP(0, 2) * C[2] / L[2] - dP(0, 1) * C[1] / L[1])}, {3. / 2 * (dP(1, 0) * C[0] / L[0] - dP(1, 2) * C[2] / L[2]), 3. / 2 * (dP(1, 1) * C[1] / L[1] - dP(1, 0) * C[0] / L[0]), 3. / 2 * (dP(1, 2) * C[2] / L[2] - dP(1, 1) * C[1] / L[1])}}; Matrix dNx2 = { // clang-format off {-1 - 3. / 4 * (dP(0, 0) * C[0] * C[0] + dP(0, 2) * C[2] * C[2]), 1 - 3. / 4 * (dP(0, 1) * C[1] * C[1] + dP(0, 0) * C[0] * C[0]), -3. / 4 * (dP(0, 2) * C[2] * C[2] + dP(0, 1) * C[1] * C[1])}, {-1 - 3. / 4 * (dP(1, 0) * C[0] * C[0] + dP(1, 2) * C[2] * C[2]), -3. / 4 * (dP(1, 1) * C[1] * C[1] + dP(1, 0) * C[0] * C[0]), 1 - 3. / 4 * (dP(1, 2) * C[2] * C[2] + dP(1, 1) * C[1] * C[1])}}; // clang-format on Matrix dNx3 = { {-3. / 4 * (dP(0, 0) * C[0] * S[0] + dP(0, 2) * C[2] * S[2]), -3. / 4 * (dP(0, 1) * C[1] * S[1] + dP(0, 0) * C[0] * S[0]), -3. / 4 * (dP(0, 2) * C[2] * S[2] + dP(0, 1) * C[1] * S[1])}, {-3. / 4 * (dP(1, 0) * C[0] * S[0] + dP(1, 2) * C[2] * S[2]), -3. / 4 * (dP(1, 1) * C[1] * S[1] + dP(1, 0) * C[0] * S[0]), -3. / 4 * (dP(1, 2) * C[2] * S[2] + dP(1, 1) * C[1] * S[1])}}; Matrix dNy1 = { {3. / 2 * (dP(0, 0) * S[0] / L[0] - dP(0, 2) * S[2] / L[2]), 3. / 2 * (dP(0, 1) * S[1] / L[1] - dP(0, 0) * S[0] / L[0]), 3. / 2 * (dP(0, 2) * S[2] / L[2] - dP(0, 1) * S[1] / L[1])}, {3. / 2 * (dP(1, 0) * S[0] / L[0] - dP(1, 2) * S[2] / L[2]), 3. / 2 * (dP(1, 1) * S[1] / L[1] - dP(1, 0) * S[0] / L[0]), 3. / 2 * (dP(1, 2) * S[2] / L[2] - dP(1, 1) * S[1] / L[1])}}; Matrix dNy2 = dNx3; Matrix dNy3 = { // clang-format off {-1 - 3. / 4 * (dP(0, 0) * S[0] * S[0] + dP(0, 2) * S[2] * S[2]), 1 - 3. / 4 * (dP(0, 1) * S[1] * S[1] + dP(0, 0) * S[0] * S[0]), -3. / 4 * (dP(0, 2) * S[2] * S[2] + dP(0, 1) * S[1] * S[1])}, {-1 - 3. / 4 * (dP(1, 0) * S[0] * S[0] + dP(1, 2) * S[2] * S[2]), -3. / 4 * (dP(1, 1) * S[1] * S[1] + dP(1, 0) * S[0] * S[0]), 1 - 3. / 4 * (dP(1, 2) * S[2] * S[2] + dP(1, 1) * S[1] * S[1])}}; // clang-format on // Derivative of linear (membrane mode) functions Matrix dNm(2, 3); InterpolationElement<_itp_lagrange_triangle_3, _itk_lagrangian>::computeDNDS( natural_coords, dNm); UInt i = 0; for (const Matrix & mat : {dNm, dNx1, dNx2, dNx3, dNy1, dNy2, dNy3}) { B.block(mat, 0, i); i += mat.cols(); } } /* -------------------------------------------------------------------------- */ template <> inline void -InterpolationElement<_itp_discrete_kirchhoff_triangle_18, _itk_structural>:: - arrangeInVoigt(const Matrix & dnds, Matrix & B) { - // clang-format off - Matrix dNm(2, 3), dNx1(2, 3), dNx2(2, 3), dNx3(2, 3), dNy1(2, 3), dNy2(2, 3), dNy3(2, 3); +InterpolationElement<_itp_discrete_kirchhoff_triangle_18, + _itk_structural>::arrangeInVoigt(const Matrix & dnds, + Matrix & B) { + Matrix dNm(2, 3), dNx1(2, 3), dNx2(2, 3), dNx3(2, 3), dNy1(2, 3), + dNy2(2, 3), dNy3(2, 3); UInt i = 0; for (Matrix * mat : {&dNm, &dNx1, &dNx2, &dNx3, &dNy1, &dNy2, &dNy3}) { *mat = dnds.block(0, i, 2, 3); i += mat->cols(); } + // clang-format off B = { // Membrane shape functions; TODO use the triangle_3 shapes {dNm(0, 0), 0, 0, 0, 0, 0, dNm(0, 1), 0, 0, 0, 0, 0, dNm(0, 2), 0, 0, 0, 0, 0, }, {0, dNm(1, 0), 0, 0, 0, 0, 0, dNm(1, 1), 0, 0, 0, 0, 0, dNm(1, 2), 0, 0, 0, 0, }, {dNm(1, 0), dNm(0, 0), 0, 0, 0, 0, dNm(1, 1), dNm(0, 1), 0, 0, 0, 0, dNm(1, 2), dNm(0, 2), 0, 0, 0, 0, }, // Bending shape functions {0, 0, dNx1(0, 0), -dNx3(0, 0), dNx2(0, 0), 0, 0, 0, dNx1(0, 1), -dNx3(0, 1), dNx2(0, 1), 0, 0, 0, dNx1(0, 2), -dNx3(0, 2), dNx2(0, 2), 0}, {0, 0, dNy1(1, 0), -dNy3(1, 0), dNy2(1, 0), 0, 0, 0, dNy1(1, 1), -dNy3(1, 1), dNy2(1, 1), 0, 0, 0, dNy1(1, 2), -dNy3(1, 2), dNy2(1, 2), 0}, {0, 0, dNx1(1, 0) + dNy1(0, 0), -dNx3(1, 0) - dNy3(0, 0), dNx2(1, 0) + dNy2(1, 0), 0, 0, 0, dNx1(1, 1) + dNy1(0, 1), -dNx3(1, 1) - dNy3(0, 0), dNx2(1, 1) + dNy2(1, 1), 0, 0, 0, dNx1(1, 2) + dNy1(0, 2), -dNx3(1, 2) - dNy3(0, 2), dNx2(1, 2) + dNy2(1, 2), 0}}; // clang-format on } } // namespace akantu #endif /* __AKANTU_ELEMENT_CLASS_KIRCHHOFF_SHELL_INLINE_IMPL_CC__ */ diff --git a/test/test_model/test_structural_mechanics_model/test_structural_mechanics_model_discrete_kirchhoff_triangle_18.cc b/test/test_model/test_structural_mechanics_model/test_structural_mechanics_model_discrete_kirchhoff_triangle_18.cc index bac1f8c70..b2d1070d9 100644 --- a/test/test_model/test_structural_mechanics_model/test_structural_mechanics_model_discrete_kirchhoff_triangle_18.cc +++ b/test/test_model/test_structural_mechanics_model/test_structural_mechanics_model_discrete_kirchhoff_triangle_18.cc @@ -1,101 +1,99 @@ /** * @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 TestStructDKT18 : public TestStructuralFixture> { using parent = TestStructuralFixture>; public: void addMaterials() override { mat.E = 1; mat.t = 1; mat.nu = 0.3; this->model->addMaterial(mat); } void assignMaterials() override { auto & materials = this->model->getElementMaterial(parent::type); std::fill(materials.begin(), materials.end(), 0); } void setDirichlets() override { - std::fill(this->model->getBlockedDOFs().begin(), - this->model->getBlockedDOFs().end(), true); + this->model->getBlockedDOFs().set(true); auto center_node = this->model->getBlockedDOFs().end(parent::ndof) - 1; - // clang-format off *center_node = {false, false, false, false, false, true}; - // clang-format on 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 + // 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 + // clang-format on } void setNeumanns() override {} protected: StructuralMaterial mat; }; /* -------------------------------------------------------------------------- */ // 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}; + auto nb_nodes = this->model->getDisplacement().size(); Vector center_node_disp = - model->getDisplacement().end(model->getSpatialDimension())[-1]; + model->getDisplacement().begin(solution.size())[nb_nodes - 1]; auto error = solution - center_node_disp; + std::cout << center_node_disp << std::endl; Real tol = Math::getTolerance(); EXPECT_NEAR(error.norm(), 0., tol); }