diff --git a/test/test_model/test_solid_mechanics_model/patch_tests/data/bar_hexahedron.geo b/test/test_model/test_solid_mechanics_model/patch_tests/data/bar_hexahedron.geo
index cd7c6a709..6ca6ce290 100644
--- a/test/test_model/test_solid_mechanics_model/patch_tests/data/bar_hexahedron.geo
+++ b/test/test_model/test_solid_mechanics_model/patch_tests/data/bar_hexahedron.geo
@@ -1,79 +1,76 @@
 h = .6;
 Point(1) = {0, 0, 0, h};
 Point(2) = {10, 0, 0, h};
 
 Point(3) = {0, 1., 0, h};
 Point(4) = {10, 1., 0, h};
 
 Point(5) = {0, 0, 1., h};
 Point(6) = {10, 0, 1., h};
 
 Point(7) = {0, 1., 1., h};
 Point(8) = {10, 1., 1., h};
 
 
 
 Mesh.SecondOrderIncomplete = 1;//+
 Line(1) = {7, 8};
 //+
 Line(2) = {8, 6};
 //+
 Line(3) = {6, 5};
 //+
 Line(4) = {5, 7};
 //+
 Line(5) = {3, 7};
 //+
 Line(6) = {3, 1};
 //+
 Line(7) = {1, 5};
 //+
 Line(8) = {4, 2};
 //+
 Line(9) = {4, 8};
 //+
 Line(10) = {2, 6};
 //+
 Line(11) = {4, 3};
 //+
 Line(12) = {1, 2};
 //+
 Line Loop(1) = {2, -10, -8, 9};
 //+
 Plane Surface(1) = {1};
 //+
 Line Loop(2) = {7, 4, -5, 6};
 //+
 Plane Surface(2) = {2};
 //+
 Line Loop(3) = {12, 10, 3, -7};
 //+
 Plane Surface(3) = {3};
 //+
 Line Loop(4) = {3, 4, 1, 2};
 //+
 Plane Surface(4) = {4};
 //+
 Line Loop(5) = {1, -9, 11, 5};
 //+
 Plane Surface(5) = {5};
 //+
 Line Loop(6) = {11, 6, 12, -8};
 //+
 Plane Surface(6) = {6};
 //+
 Surface Loop(1) = {3, 6, 5, 4, 2, 1};
 //+
 Volume(1) = {1};
 //+
-Physical Surface("Left") = {2};
-//+
-Physical Surface("Right") = {1};
-//+
+Physical Surface("BC") = {1, 2, 3, 4, 5, 6};
 Physical Volume("bulk") = {1};
 
 Transfinite Surface "*";
 Transfinite Volume "*";
 
 Recombine Surface "*";
 Mesh.SecondOrderIncomplete = 1;
\ No newline at end of file
diff --git a/test/test_model/test_solid_mechanics_model/patch_tests/data/bar_quadrangle.geo b/test/test_model/test_solid_mechanics_model/patch_tests/data/bar_quadrangle.geo
index 4826d400d..f47d77171 100644
--- a/test/test_model/test_solid_mechanics_model/patch_tests/data/bar_quadrangle.geo
+++ b/test/test_model/test_solid_mechanics_model/patch_tests/data/bar_quadrangle.geo
@@ -1,27 +1,26 @@
-h = .4;
+h = .6;
 Point(1) = {0, 0, 0, h};
 Point(2) = {10, 0, 0, h};
 
 Point(3) = {0, 1., 0, h};
 Point(4) = {10, 1., 0, h};
 
 Line(1) = {1, 2};
 //+
 Line(2) = {4, 3};
 //+
 Line(3) = {2, 4};
 //+
 Line(4) = {3, 1};
 //+
 Line Loop(1) = {1, 3, 2, 4};
 //+
 Plane Surface(1) = {1};
 
 
-Physical Line("Left") = {4};
-Physical Line("Right") = {3};
-//+
+Physical Line("BC") = {4, 3, 1, 2};
 Physical Surface("bulk") = {1};
-//+
+
+Transfinite Surface "*";
 Recombine Surface {1};
 Mesh.SecondOrderIncomplete = 1;
\ No newline at end of file
diff --git a/test/test_model/test_solid_mechanics_model/patch_tests/data/bar_segment.geo b/test/test_model/test_solid_mechanics_model/patch_tests/data/bar_segment.geo
index 7aa27ae0a..ab49b3850 100644
--- a/test/test_model/test_solid_mechanics_model/patch_tests/data/bar_segment.geo
+++ b/test/test_model/test_solid_mechanics_model/patch_tests/data/bar_segment.geo
@@ -1,8 +1,7 @@
 h = .6;
 Point(1) = {0, 0, 0, h};
 Point(2) = {10, 0, 0, h};
 Line(1) = {1, 2};
-Physical Point("Left") = {1};
-Physical Point("Right") = {2};
-//+
+
+Physical Point("BC") = {1, 2};
 Physical Line("bulk") = {1};
diff --git a/test/test_model/test_solid_mechanics_model/patch_tests/data/bar_tetrahedron.geo b/test/test_model/test_solid_mechanics_model/patch_tests/data/bar_tetrahedron.geo
index 1df0b9749..fbcfb6e33 100644
--- a/test/test_model/test_solid_mechanics_model/patch_tests/data/bar_tetrahedron.geo
+++ b/test/test_model/test_solid_mechanics_model/patch_tests/data/bar_tetrahedron.geo
@@ -1,73 +1,70 @@
 h = .6;
 Point(1) = {0, 0, 0, h};
 Point(2) = {10, 0, 0, h};
 
 Point(3) = {0, 1., 0, h};
 Point(4) = {10, 1., 0, h};
 
 Point(5) = {0, 0, 1., h};
 Point(6) = {10, 0, 1., h};
 
 Point(7) = {0, 1., 1., h};
 Point(8) = {10, 1., 1., h};
 
 
 
 Mesh.SecondOrderIncomplete = 1;//+
 Line(1) = {7, 8};
 //+
 Line(2) = {8, 6};
 //+
 Line(3) = {6, 5};
 //+
 Line(4) = {5, 7};
 //+
 Line(5) = {3, 7};
 //+
 Line(6) = {3, 1};
 //+
 Line(7) = {1, 5};
 //+
 Line(8) = {4, 2};
 //+
 Line(9) = {4, 8};
 //+
 Line(10) = {2, 6};
 //+
 Line(11) = {4, 3};
 //+
 Line(12) = {1, 2};
 //+
 Line Loop(1) = {2, -10, -8, 9};
 //+
 Plane Surface(1) = {1};
 //+
 Line Loop(2) = {7, 4, -5, 6};
 //+
 Plane Surface(2) = {2};
 //+
 Line Loop(3) = {12, 10, 3, -7};
 //+
 Plane Surface(3) = {3};
 //+
 Line Loop(4) = {3, 4, 1, 2};
 //+
 Plane Surface(4) = {4};
 //+
 Line Loop(5) = {1, -9, 11, 5};
 //+
 Plane Surface(5) = {5};
 //+
 Line Loop(6) = {11, 6, 12, -8};
 //+
 Plane Surface(6) = {6};
 //+
 Surface Loop(1) = {3, 6, 5, 4, 2, 1};
 //+
 Volume(1) = {1};
 //+
-Physical Surface("Left") = {2};
-//+
-Physical Surface("Right") = {1};
-//+
+Physical Surface("BC") = {1, 2, 3, 4, 5, 6};
 Physical Volume("bulk") = {1};
diff --git a/test/test_model/test_solid_mechanics_model/patch_tests/data/bar_triangle.geo b/test/test_model/test_solid_mechanics_model/patch_tests/data/bar_triangle.geo
index 240c54287..6fa5be9e8 100644
--- a/test/test_model/test_solid_mechanics_model/patch_tests/data/bar_triangle.geo
+++ b/test/test_model/test_solid_mechanics_model/patch_tests/data/bar_triangle.geo
@@ -1,24 +1,23 @@
 h = .6;
 Point(1) = {0, 0, 0, h};
 Point(2) = {10, 0, 0, h};
 
 Point(3) = {0, 1., 0, h};
 Point(4) = {10, 1., 0, h};
 
 Line(1) = {1, 2};
 //+
 Line(2) = {4, 3};
 //+
 Line(3) = {2, 4};
 //+
 Line(4) = {3, 1};
 //+
 Line Loop(1) = {1, 3, 2, 4};
 //+
 Plane Surface(1) = {1};
 
 
-Physical Line("Left") = {4};
-Physical Line("Right") = {3};
-//+
+Physical Line("BC") = {4, 3, 1 , 2};
+
 Physical Surface("bulk") = {1};
diff --git a/test/test_model/test_solid_mechanics_model/test_solid_mechanics_model_dynamics.cc b/test/test_model/test_solid_mechanics_model/test_solid_mechanics_model_dynamics.cc
index 9744e0d8e..a099bbd09 100644
--- a/test/test_model/test_solid_mechanics_model/test_solid_mechanics_model_dynamics.cc
+++ b/test/test_model/test_solid_mechanics_model/test_solid_mechanics_model_dynamics.cc
@@ -1,243 +1,314 @@
 /**
  * @file   test_solid_mechanics_model_cube3d.cc
  *
  * @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
  *
  * @date creation: Wed Aug 04 2010
  * @date last modification: Thu Aug 06 2015
  *
  * @brief  test of the class SolidMechanicsModel on the 3d cube
  *
  * @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 <http://www.gnu.org/licenses/>.
  *
  */
 
 /* -------------------------------------------------------------------------- */
 #include "boundary_condition_functor.hh"
 #include "test_solid_mechanics_model_fixture.hh"
 /* -------------------------------------------------------------------------- */
 
 using namespace akantu;
 
 namespace {
 
 template <typename type_>
 class TestSMMFixtureDynamics : public TestSMMFixture<type_> {
 
 public:
   static constexpr ElementType type = type_::value;
 
   void SetUp() override {
     if (this->type == _pentahedron_6 || this->type == _pentahedron_15)
       return;
 
     std::cout << "testing type " << this->type << std::endl;
 
     TestSMMFixture<type_>::SetUp();
   }
 
   std::string makeMeshName() override {
     std::stringstream element_type;
     element_type << type;
     SCOPED_TRACE(element_type.str().c_str());
     return std::string("bar") + element_type.str() + ".msh";
   }
 };
 
-template <UInt spatial_dimension>
-auto solution_disp =
+constexpr Real A = 1e-1;
+constexpr Real E = 1.;
+constexpr Real poisson = .3;
+constexpr Real lambda = E * poisson / (1. + poisson) / (1. - 2. * poisson);
+constexpr Real mu = E / 2 / (1. + poisson);
+constexpr Real rho = 1.;
+const Real cp = std::sqrt((lambda + 2 * mu) / rho);
+const Real cs = std::sqrt(mu / rho);
+const Real c = std::sqrt(E / rho);
+
+const Vector<Real> k = {.5, 0., 0.};
+const Vector<Real> psi1 = {0., 0., 1.};
+const Vector<Real> psi2 = {0., 1., 0.};
+const Real knorm = k.norm();
+
+template <UInt spatial_dimension> auto solution_disp = 1;
+template <UInt spatial_dimension> auto solution_vel = 1;
+
+template <>
+auto solution_disp<1> =
     [](Vector<Real> & disp, const Vector<Real> & coord, Real current_time) {
       const auto & x = coord(_x);
-      constexpr Real k = .5;
-      constexpr Real omega = k;
-      disp(_x) = cos(k * x - omega * current_time);
+      const Real omega = c * k[0];
+      disp(_x) = A * cos(k[0] * x - omega * current_time);
     };
 
-template <UInt spatial_dimension>
-auto solution_vel =
+template <>
+auto solution_vel<1> =
     [](Vector<Real> & vel, const Vector<Real> & coord, Real current_time) {
-
       const auto & x = coord(_x);
-      constexpr Real k = .5;
-      constexpr Real omega = k;
-      vel(_x) = omega * sin(k * x - omega * current_time);
+      const Real omega = c * k[0];
+      vel(_x) = omega * A * sin(k[0] * x - omega * current_time);
     };
 
-template <ElementType _type> struct DimensionHelper {
-  static constexpr int dim = -1;
-};
+template <>
+auto solution_disp<2> =
+    [](Vector<Real> & disp, const Vector<Real> & coord, Real current_time) {
+
+      const auto & X = coord;
+      Vector<Real> kshear = {k[1], k[0]};
+      Vector<Real> kpush = {k[0], k[1]};
+
+      const Real omega_p = knorm * cp;
+      const Real omega_s = knorm * cs;
+
+      Real phase_p = X.dot(kpush) - omega_p * current_time;
+      Real phase_s = X.dot(kpush) - omega_s * current_time;
+
+      disp = A * (kpush * cos(phase_p) + kshear * cos(phase_s));
+    };
+
+template <>
+auto solution_vel<2> = [](Vector<Real> & vel, const Vector<Real> & coord,
+                          Real current_time) {
+
+  const auto & X = coord;
+  Vector<Real> kshear = {k[1], k[0]};
+  Vector<Real> kpush = {k[0], k[1]};
+
+  const Real omega_p = knorm * cp;
+  const Real omega_s = knorm * cs;
+
+  Real phase_p = X.dot(kpush) - omega_p * current_time;
+  Real phase_s = X.dot(kpush) - omega_s * current_time;
+
+  vel = A * (kpush * omega_p * cos(phase_p) + kshear * omega_s * cos(phase_s));
 
-template <> struct DimensionHelper<_segment_2> {
-  static constexpr UInt dim = 1;
-};
-template <> struct DimensionHelper<_segment_3> {
-  static constexpr UInt dim = 1;
-};
-template <> struct DimensionHelper<_triangle_3> {
-  static constexpr UInt dim = 2;
-};
-template <> struct DimensionHelper<_triangle_6> {
-  static constexpr UInt dim = 2;
-};
-template <> struct DimensionHelper<_quadrangle_4> {
-  static constexpr UInt dim = 2;
 };
-template <> struct DimensionHelper<_quadrangle_8> {
-  static constexpr UInt dim = 2;
+
+template <>
+auto solution_disp<3> =
+    [](Vector<Real> & disp, const Vector<Real> & coord, Real current_time) {
+
+      const auto & X = coord;
+      Vector<Real> kpush = k;
+      Vector<Real> kshear1(3);
+      Vector<Real> kshear2(3);
+      kshear1.crossProduct(k, psi1);
+      kshear2.crossProduct(k, psi2);
+
+      const Real omega_p = knorm * cp;
+      const Real omega_s = knorm * cs;
+
+      Real phase_p = X.dot(kpush) - omega_p * current_time;
+      Real phase_s = X.dot(kpush) - omega_s * current_time;
+
+      disp = A * (kpush * cos(phase_p) + kshear1 * cos(phase_s) +
+                  kshear2 * cos(phase_s));
+
+    };
+
+template <>
+auto solution_vel<3> = [](Vector<Real> & vel, const Vector<Real> & coord,
+                          Real current_time) {
+
+  const auto & X = coord;
+  Vector<Real> kpush = k;
+  Vector<Real> kshear1(3);
+  Vector<Real> kshear2(3);
+  kshear1.crossProduct(k, psi1);
+  kshear2.crossProduct(k, psi2);
+
+  const Real omega_p = knorm * cp;
+  const Real omega_s = knorm * cs;
+
+  Real phase_p = X.dot(kpush) - omega_p * current_time;
+  Real phase_s = X.dot(kpush) - omega_s * current_time;
+
+  vel = A * (kpush * omega_p * cos(phase_p) + kshear1 * omega_s * cos(phase_s) +
+             kshear2 * omega_s * cos(phase_s));
 };
 
 template <ElementType _type>
 class SolutionFunctor : public BC::Dirichlet::DirichletFunctor {
 public:
   SolutionFunctor(Real current_time, SolidMechanicsModel & model)
       : current_time(current_time), model(model) {}
 
 public:
   // static constexpr UInt dim = DimensionHelper<_type>::dim;
   static constexpr UInt dim = ElementClass<_type>::getSpatialDimension();
 
   inline void operator()(UInt node, Vector<bool> & flags, Vector<Real> & primal,
                          const Vector<Real> & coord) const {
 
     flags(0) = true;
     auto & vel = model.getVelocity();
     auto itVel = vel.begin(model.getSpatialDimension());
     Vector<Real> v = itVel[node];
     solution_disp<dim>(primal, coord, current_time);
     solution_vel<dim>(v, coord, current_time);
   }
 
 private:
   Real current_time;
   SolidMechanicsModel & model;
 };
 
 template <ElementType _type, typename AM>
 void test_body(SolidMechanicsModel & model, AM analysis_method) {
 
   // constexpr UInt dim = DimensionHelper<_type>::dim;
   static constexpr UInt dim = ElementClass<_type>::getSpatialDimension();
 
   getStaticParser().parse("test_solid_mechanics_model_"
                           "dynamics_material.dat");
 
   model.initFull(SolidMechanicsModelOptions(analysis_method));
 
-  bool dump_paraview = false;
+  bool dump_paraview = true;
 
   if (dump_paraview) {
     std::stringstream base_name;
     base_name << "bar" << analysis_method << _type;
     model.setBaseName(base_name.str());
     model.addDumpFieldVector("displacement");
     model.addDumpField("mass");
     model.addDumpField("velocity");
     model.addDumpField("acceleration");
     model.addDumpFieldVector("external_force");
     model.addDumpFieldVector("internal_force");
     model.addDumpField("stress");
     model.addDumpField("strain");
   }
 
   Real time_step = model.getStableTimeStep() / 10.;
   model.setTimeStep(time_step);
   std::cout << "timestep: " << time_step << std::endl;
 
   UInt nb_nodes = model.getMesh().getNbNodes();
   UInt spatial_dimension = model.getSpatialDimension();
 
   auto & nodes = model.getMesh().getNodes();
   auto & disp = model.getDisplacement();
   auto & vel = model.getVelocity();
 
   Array<Real> disp_solution(nb_nodes, spatial_dimension);
 
   Real current_time = 0;
 
   auto itNodes = nodes.begin(spatial_dimension);
   auto itDisp = disp.begin(spatial_dimension);
   auto itVel = vel.begin(spatial_dimension);
   for (UInt n = 0; n < nb_nodes; ++n, ++itNodes, ++itDisp, ++itVel) {
     solution_disp<dim>(*itDisp, *itNodes, current_time);
     solution_vel<dim>(*itVel, *itNodes, current_time);
   }
 
   if (dump_paraview)
     model.dump();
 
   /// boundary conditions
-  model.applyBC(SolutionFunctor<_type>(current_time, model), "Left");
-  model.applyBC(SolutionFunctor<_type>(current_time, model), "Right");
+  model.applyBC(SolutionFunctor<_type>(current_time, model), "BC");
 
   Real max_error = 0.;
   Real wave_velocity = 1.; // sqrt(E/rho) = sqrt(1/1) = 1
   Real simulation_time = 5 / wave_velocity;
 
   UInt max_steps = simulation_time / time_step; // 100
+  UInt ndump = 50;
+  UInt dump_freq = max_steps / ndump;
+
   std::cout << "max_steps: " << max_steps << std::endl;
 
   for (UInt s = 0; s < max_steps; ++s, current_time += time_step) {
 
-    if (dump_paraview)
+    if (s % dump_freq == 0 && dump_paraview)
       model.dump();
 
     /// boundary conditions
-    model.applyBC(SolutionFunctor<_type>(current_time, model), "Left");
-    model.applyBC(SolutionFunctor<_type>(current_time, model), "Right");
+    model.applyBC(SolutionFunctor<_type>(current_time, model), "BC");
 
     // compute the disp solution
     auto itDispSolution = disp_solution.begin(spatial_dimension);
     itNodes = nodes.begin(spatial_dimension);
     for (UInt n = 0; n < nb_nodes; ++n, ++itNodes, ++itDispSolution) {
       solution_disp<dim>(*itDispSolution, *itNodes, current_time);
     }
     // compute the error solution
     itDispSolution = disp_solution.begin(spatial_dimension);
     itDisp = disp.begin(spatial_dimension);
     Real disp_error = 0.;
     for (UInt n = 0; n < nb_nodes; ++n, ++itDispSolution, ++itDisp) {
       auto diff = *itDispSolution - *itDisp;
 
       for (UInt i = 0; i < spatial_dimension; ++i) {
         disp_error += diff(i) * diff(i);
       }
     }
     disp_error = sqrt(disp_error) / nb_nodes;
     max_error = std::max(disp_error, max_error);
-    ASSERT_NEAR(disp_error, 0., 1e-1);
+    ASSERT_NEAR(disp_error, 0., 1e-3);
     model.solveStep();
   }
   std::cout << "max error: " << max_error << std::endl;
 }
 
 TYPED_TEST_CASE(TestSMMFixtureDynamics, types);
 
 #ifdef AKANTU_IMPLICIT
 TYPED_TEST(TestSMMFixture, DynamicsImplicit) {
   if (this->type != _pentahedron_6 && this->type != _pentahedron_15)
     test_body<this->type>(*(this->model), _implicit_dynamic);
 }
 #endif
 
 TYPED_TEST(TestSMMFixtureDynamics, DynamicsExplicit) {
   if (this->type != _pentahedron_6 && this->type != _pentahedron_15)
     test_body<this->type>(*(this->model), _explicit_lumped_mass);
 }
 }