Example: Deduction of the Weak Form

While partial differential equations are typically posed in the strong form, e.g.

- \Delta u = f \ ,

the finite element method is based on the weak form, which is under the assumption of homogeneous Neumann boundary conditions in the above case given by

\int_\Omega \nabla u \cdot \nabla v \: dx = \int_\Omega fv \: dx \quad \forall v \in \mathcal{V} \ ,

where V is a suitable test space. By an extension of the functionality in ViennaMath, ViennaFEM can also deduce the weak form automatically:

Deducing the weak form out of the strong form
using namespace viennamath;
function_symbol  u;   // instantiate the unknown
// instantiate Poisson equation with f=1:
equation poisson_eq = make_equation(laplace(u), -1.0); 
std::cout << "Strong form: " << poisson_eq << std::endl;
std::cout << "Weak form:   " << viennafem::make_weak_form(poisson_eq) << std::endl;
// Inhomogeneous permittivity: div( eps * grad(u)) = -1.0:
viennafem::cell_quan<CellType> eps; eps.wrap_constant( my_key() );
equation poisson_eq2 = make_equation( div( eps * grad(u)), -1);
std::cout << "Strong form: " << poisson_eq2 << std::endl;
std::cout << "Weak form:   " << viennafem::make_weak_form(poisson_eq2) << std::endl;

The second form of the Poisson equation includes a diffusion coefficient 'eps', which is constant within each ViennaGrid cell (of type 'CellType'), but may vary among the cells inside the mesh.