Solving a system with lagrange multipliers

99 views
Skip to first unread message

Vinayak Vijay

unread,
Feb 20, 2024, 2:10:43 AM2/20/24
to deal.II User Group
Hello,

I am trying to solve a problem that enforces some constraints on the system using Lagrange multipliers (LMs).  The constraints are sort of on the average behavior of certain quantities (for eg. centre of mass) in the domain which is why the LMs are not  field variables. This implies they do not depend on the discretization and thus don't need to be a part of the FiniteElements. This is different from some of the problems already discussed in the tutorials, for eg., implementing incompressibility (step-44) wherein the LMs are taken as finite elements or the obstacle problem (step-42) in which the active-inactive set strategy is used.

Specifically, i have six constraint equations and thus six LMs. Therefore, the total number of unknowns becomes n_dofs+n_lagrange_multiplers(=6).

I have attempted to implement this using the naive way of simply augmenting the system_rhs(required size=n_dofs+6) and system_matrix(required size=n_dofs+6)  for these "extra dofs". The point where i get stuck is when the function make_sparsity_pattern() checks for the condition:  sparsity.n_rows() == n_dofs

This condition is of course violated because i initialize my sparsity pattern with rows=dofs + n_lagrange_multiplers(=6), columns=dofs + n_lagrange_multiplers(=6) whereas the dof_handler has no information about the "extra dofs" i.e. the LMs.

How can i solve this problem? Is there a better way to approach it?

Thanks
Vinayak

Wolfgang Bangerth

unread,
Feb 20, 2024, 8:59:49 AM2/20/24
to dea...@googlegroups.com
Vinayak:
This happens to be exactly the kind of situation that we're still discussing here:
https://github.com/dealii/dealii/pull/16412
I think you want to specifically look at the last comment at the bottom where
I point to a proposed code gallery program.

Best
Wolfgang

--
------------------------------------------------------------------------
Wolfgang Bangerth email: bang...@colostate.edu
www: http://www.math.colostate.edu/~bangerth/


jaosch

unread,
Sep 10, 2024, 5:19:38 AM9/10/24
to deal.II User Group
Hello,

Even though this discussion is a couple of months old, I would like to join, as I am confronted with the same issue as Vinayak.

I tried to understand this proposal to the code gallery (https://github.com/dealii/code-gallery/pull/156/commits/813d1100ecb18a498146a758f0fe2284a7eca85d), where FE_Nothing spaces are used in all but one cell to ensure consistency between the number of DOFs in the DoFHandler and the sparsity pattern. However, there is something I do not understand:

Namely, for my problem, I need the solution to the global Lagrange multipliers during the assembly of the RHS. Hence, when looping over all cells during the numerical integration, I need to always have access to the solution on, e.g., the first cell. How is this compatible with the parallel approach using WorkStream presented in step-44, which I was hoping to use as a template?

---------------------------

Alternatively, I thought about using AffineConstraints, where all DOFs belonging to one Lagrange multiplier are constrained to the DOF with the lowest index. In this case, I would pass the constraints object to DoFTools::make_sparsity_pattern() hoping this might keep the size of the stiffness matrix reasonably small:

constraints.clear()
ComponentMask mask = fe.component_mask(multipliers_fe);
const IndexSet dofs =
      DoFTools::extract_dofs(dof_handler, mask);
    const types::global_dof_index first_dof =
      dofs.nth_index_in_set(0);

    for (const types::global_dof_index i : dofs)
    {
      if (i != first_dof)
      {
        constraints.add_constraint(i, {{first_dof, 1.0}});
      }
    }
constraints.close()

How do you rate this second approach compared to the first one? Are there any issues to be expected?

Thank you in advance.

Best regards
Jasper

Wolfgang Bangerth

unread,
Sep 10, 2024, 11:45:38 AM9/10/24
to dea...@googlegroups.com

Jasper,

> Namely, for my problem, I need the solution to the global Lagrange multipliers
> during the assembly of the RHS. Hence, when looping over all cells during the
> numerical integration, I need to always have access to the solution on, e.g.,
> the first cell. How is this compatible with the parallel approach using
> WorkStream presented in step-44, which I was hoping to use as a template?

In that case, determine the value of the Lagrange multiplier from the first
cell once, save it in a variable, and only then start the loop over all cells.

> ---------------------------
>
> Alternatively, I thought about using AffineConstraints, where all DOFs
> belonging to one Lagrange multiplier are constrained to the DOF with the
> lowest index. In this case, I would pass the constraints object to
> DoFTools::make_sparsity_pattern() hoping this might keep the size of the
> stiffness matrix reasonably small:
>
> constraints.clear()
> ComponentMask mask = fe.component_mask(multipliers_fe);
> const IndexSet dofs =
>       DoFTools::extract_dofs(dof_handler, mask);
>     const types::global_dof_index first_dof =
>       dofs.nth_index_in_set(0);
>
>     for (const types::global_dof_index i : dofs)
>     {
>       if (i != first_dof)
>       {
>         constraints.add_constraint(i, {{first_dof, 1.0}});
>       }
>     }
> constraints.close()
>
> How do you rate this second approach compared to the first one? Are there any
> issues to be expected?

That would work too, if perhaps not the most efficient approach. It shouldn't
be terrible, though.

Best
W.
Reply all
Reply to author
Forward
0 new messages