Example: Linear Elasticity

The weak formulation of the Lame equation describing linear elasticity is to find u in a suitable space such that
\int_\Omega \varepsilon(u) : \sigma(v) \: \mathrm{d} \Omega = \int_\Omega F \cdot v \: \mathrm{d} \Omega
for all vector-valued test functions v from a suitable space. The assembly within ViennaFEM for F=(0,0,1)^{\mathrm T} is triggered by following exactly the mathematical formulation by first defining vector-valued unknowns and test functions, and then specifying the weak formulation:

Defining the weak form of the Lame equation
// Define trial and test functions
  std::vector< FunctionSymbol > u(3);
  u[0] = FunctionSymbol(0, unknown_tag<>());
  u[1] = FunctionSymbol(1, unknown_tag<>());
  u[2] = FunctionSymbol(2, unknown_tag<>());
  std::vector< FunctionSymbol > v(3);
  v[0] = FunctionSymbol(0, test_tag<>());
  v[1] = FunctionSymbol(1, test_tag<>());
  v[2] = FunctionSymbol(2, test_tag<>());
// Define weak form:
  std::vector< Expression > strain = strain_tensor(u);
  std::vector< Expression > stress = stress_tensor(v);
  Equation weak_form_lame = 
         make_equation( integral(symbolic_interval(), tensor_reduce( strain, stress )),
                        integral(symbolic_interval(), viennamath::constant(1.0) * v[2])  );

Here, strain_tensor() and stress_tensor() are simple implementations of the strain and stress tensor using ViennaMath, respectively, and tensor_reduce() sums over the entries of both tensors. The remaining code is similar to the Poisson equation example.