Consider a “rheometer” which corresponds to a torus, in which a linear elastic material is placed consists of two phases. In terms of boundary conditions this implies taking the geometry periodic in horizontal direction, while the displacements of the top and bottom boundary are controlled. For simplicity two-dimensional plane strain is considered.


Below the important difference with respect to the previous example are discussed. The full example can be downloaded:


The same example is available using the Python interface:

Node sets

    xt::xtensor<size_t,1> nodesLft = mesh.nodesLeftOpenEdge();
    xt::xtensor<size_t,1> nodesRgt = mesh.nodesRightOpenEdge();
    xt::xtensor<size_t,1> nodesTop = mesh.nodesTopEdge();
    xt::xtensor<size_t,1> nodesBot = mesh.nodesBottomEdge();

We will apply periodicity to all the nodes along the left and right boundary of the geometry. The corner nodes are thereby assigned the fixed displacement (that is itself taken periodic).

Apply periodicity

    for (size_t j = 0; j < coor.shape(1); ++j) {
        xt::view(dofs, xt::keep(nodesRgt), j) = xt::view(dofs, xt::keep(nodesLft), j);

    dofs = GooseFEM::Mesh::renumber(dofs);

Applying periodicity in this case is rather straightforward. In particular the degrees-of-freedom along the right edge are eliminated, and replaced by the degrees-of-freedom of the left edge. The size of the actually solved system is therefore reduced, while the response vectors are simply assembled to both sides of the geometry.

Fixed displacement

    xt::xtensor<size_t,1> iip = xt::concatenate(xt::xtuple(
        xt::view(dofs, xt::keep(nodesBot), 0),
        xt::view(dofs, xt::keep(nodesBot), 1),
        xt::view(dofs, xt::keep(nodesTop), 0),
        xt::view(dofs, xt::keep(nodesTop), 1)));

The degrees-of-freedom of which the displacement is controlled are finally extracted from the renumbered list of degrees-of-freedom.