void LinearElasticityWithContact::move_mesh (MeshBase & input_mesh,
                                             const NumericVector<Number> & input_solution)
{
  // Maintain a set of node ids that we've encountered.
  LIBMESH_BEST_UNORDERED_SET<dof_id_type> encountered_node_ids;

  // Localize input_solution so that we have the data to move all
  // elements (not just elements local to this processor).
  UniquePtr< NumericVector<Number> > localized_input_solution =
    NumericVector<Number>::build(input_solution.comm());

  localized_input_solution->init (input_solution.size(), false, SERIAL);
  input_solution.localize(*localized_input_solution);

  MeshBase::const_element_iterator       el     = input_mesh.active_elements_begin();
  const MeshBase::const_element_iterator end_el = input_mesh.active_elements_end();

  for ( ; el != end_el; ++el)
    {
      Elem * elem = *el;
      Elem * orig_elem = _sys.get_mesh().elem_ptr(elem->id());

      for (unsigned int node_id=0; node_id<elem->n_nodes(); node_id++)
        {
          Node & node = elem->node_ref(node_id);

          if (encountered_node_ids.find(node.id()) != encountered_node_ids.end())
            continue;

          encountered_node_ids.insert(node.id());

          std::vector<std::string> uvw_names(3);
          uvw_names[0] = "u";
          uvw_names[1] = "v";
          uvw_names[2] = "w";

          {
            const Point master_point = elem->master_point(node_id);

            Point uvw;
            for (unsigned int index=0; index<uvw_names.size(); index++)
              {
                const unsigned int var = _sys.variable_number(uvw_names[index]);
                const FEType & fe_type = _sys.get_dof_map().variable_type(var);

                FEComputeData data (_sys.get_equation_systems(), master_point);

                FEInterface::compute_data(elem->dim(),
                                          fe_type,
                                          elem,
                                          data);

                std::vector<dof_id_type> dof_indices_var;
                _sys.get_dof_map().dof_indices (orig_elem, dof_indices_var, var);

                for (unsigned int i=0; i<dof_indices_var.size(); i++)
                  {
                    Number value = (*localized_input_solution)(dof_indices_var[i]) * data.shape[i];

#ifdef LIBMESH_USE_COMPLEX_NUMBERS
                    // We explicitly store the real part in uvw
                    uvw(index) += value.real();
#else
                    uvw(index) += value;
#endif
                  }
              }

            // Update the node's location
            node += uvw;
          }
        }
    }
}
  void setUp() {
    mesh.reset(new Mesh(*TestCommWorld));
    MeshTools::Generation::build_cube(*mesh, 1, 1, 1);
    es.reset(new EquationSystems(*mesh));
    sys = &(es->add_system<System> ("SimpleSystem"));
    sys->add_variable("x2");
    sys->add_variable("x3");
    sys->add_variable("c05");
    sys->add_variable("y4");
    sys->add_variable("xy");
    sys->add_variable("yz");
    sys->add_variable("xyz");

    es->init();

    NumericVector<Number> & sol = *sys->solution;
    Elem *elem = mesh->query_elem_ptr(0);

    if (elem && elem->processor_id() == TestCommWorld->rank())
      {
        // Set x2 = 2*x
        sol.set(elem->node_ref(1).dof_number(0,0,0), 2);
        sol.set(elem->node_ref(2).dof_number(0,0,0), 2);
        sol.set(elem->node_ref(5).dof_number(0,0,0), 2);
        sol.set(elem->node_ref(6).dof_number(0,0,0), 2);

        // Set x3 = 3*x
        sol.set(elem->node_ref(1).dof_number(0,1,0), 3);
        sol.set(elem->node_ref(2).dof_number(0,1,0), 3);
        sol.set(elem->node_ref(5).dof_number(0,1,0), 3);
        sol.set(elem->node_ref(6).dof_number(0,1,0), 3);

        // Set c05 = 0.5
        sol.set(elem->node_ref(0).dof_number(0,2,0), 0.5);
        sol.set(elem->node_ref(1).dof_number(0,2,0), 0.5);
        sol.set(elem->node_ref(2).dof_number(0,2,0), 0.5);
        sol.set(elem->node_ref(3).dof_number(0,2,0), 0.5);
        sol.set(elem->node_ref(4).dof_number(0,2,0), 0.5);
        sol.set(elem->node_ref(5).dof_number(0,2,0), 0.5);
        sol.set(elem->node_ref(6).dof_number(0,2,0), 0.5);
        sol.set(elem->node_ref(7).dof_number(0,2,0), 0.5);

        // Set y4 = 4*y
        sol.set(elem->node_ref(2).dof_number(0,3,0), 4);
        sol.set(elem->node_ref(3).dof_number(0,3,0), 4);
        sol.set(elem->node_ref(6).dof_number(0,3,0), 4);
        sol.set(elem->node_ref(7).dof_number(0,3,0), 4);

        // Set xy = x*y
        sol.set(elem->node_ref(2).dof_number(0,4,0), 1);
        sol.set(elem->node_ref(6).dof_number(0,4,0), 1);

        // Set yz = y*z
        sol.set(elem->node_ref(6).dof_number(0,5,0), 1);
        sol.set(elem->node_ref(7).dof_number(0,5,0), 1);

        // Set xyz = x*y*z
        sol.set(elem->node_ref(6).dof_number(0,6,0), 1);
      }

    sol.close();
    sys->update();

    c.reset(new FEMContext(*sys));
    s.reset(new FEMContext(*sys));
    if (elem && elem->processor_id() == TestCommWorld->rank())
      {
        c->pre_fe_reinit(*sys, elem);
        c->elem_fe_reinit();
        s->pre_fe_reinit(*sys, elem);
        s->side = 3;
        s->side_fe_reinit();
      }
  }