Research Article

Finite Element Assembly Using an Embedded Domain Specific Language

Listing 1

Implementation of the assembly procedure for the Poisson problem.
(1) // The unknown function. The first template argument is a constant to distinguish each
variable at compile time
(2) FieldVariable<0, ScalarField> f("f", solution_tag());
(3) // The source term, to be set at runtime using an initial condition
(4) FieldVariable<1, ScalarField> g("g", "source_term");
(5)
(6) // Action handling the assembly
(7) Handle<ProtoAction> assembly = create_component<ProtoAction>("Assembly");
(8) // Set the expression
(9) assembly->set_expression(elements_expression
(10) (
(11) mesh::LagrangeP1::CellTypes(), // All first order Lagrange elements
(12) group
(13) (
(14)   _A = _0, _a = _0,// The element matrix and RHS vector, initialized to 0
(15)   element_quadrature // Integration over the element
(16)   (
(17)    _A(f) += transpose(nabla(f)) * nabla(f),
(18)    _a[f] += transpose(N(g))*g
(19)   ),
(20)   system_matrix += _A, // Assemble into the global linear system
(21)   system_rhs += _a
(22) )
(23) ));