How to apply Lagrange multiplier constraint dolfinx?

Hello,

I am trying to impose BCs using Lagrange multipliers similar to some old posts:
Imposing bcs using Lagrange Multiplier
Applying a constraint using a Lagrange multiplier dolfinx
How to specify Lagrange Multiplier on a boundary?

However, non of them were solved. I’ve tried running all of the similar post’s MWE, with no luck, and combinations of each approach. Right now, my MWE is modified from the fundamentals code tutorial. Following all of the other approaches, I attempted to apply Lagrange multiplier constraints with a mixed finite element formulation. I also tried treating the constraint space two ways: 1. as the full domain mesh, with boundary integrals specified in the weak form, and 2. on a mesh derived from the boundary facets. The MWE code is:

from mpi4py import MPI
from dolfinx import mesh
import numpy
from dolfinx import mesh, fem,plot
import ufl
from mpi4py import MPI
from petsc4py import PETSc
from petsc4py.PETSc import ScalarType

import pyvista
from dolfinx.fem import FunctionSpace
import numpy

# Create mesh and boundary mesh
domain = mesh.create_unit_square(MPI.COMM_WORLD, 8, 8, mesh.CellType.quadrilateral)
tdim = domain.topology.dim
fdim = tdim - 1
domain.topology.create_connectivity(fdim, tdim)
boundary_facets = mesh.exterior_facet_indices(domain.topology)
boundEdges = mesh.meshtags(domain,fdim,boundary_facets,55) 
boundDomain = boundEdges.mesh

# define mixed finite element space
P1 = ufl.FiniteElement("Lagrange", domain.ufl_cell(), 1)
P1b = ufl.FiniteElement("Lagrange", boundDomain.ufl_cell(), 1)

V, LG = fem.FunctionSpace(domain, P1), fem.FunctionSpace(boundDomain, P1b)

M = ufl.MixedElement([P1, P1])

# mixed space and test+trial functions
W = fem.FunctionSpace(domain, M)
u, lg = ufl.TrialFunctions(W)
v, mu = ufl.TestFunctions(W)

# boundary condition for weak enforcement
uD = fem.Function(V)
uD.interpolate(lambda x: 1 + x[0]**2 + 2 * x[1]**2)

# weak form
f = fem.Constant(domain, ScalarType(-6))
a = ufl.dot(ufl.grad(u), ufl.grad(v)) * ufl.dx + ufl.inner(v,lg)*ufl.ds + u*mu*ufl.ds
L = f * v * ufl.dx+ mu*uD*ufl.ds

# solve
problem = fem.petsc.LinearProblem(a, L)
uh = problem.solve()

us, lgs = uh.split()
lgs.x.array

and outputs Infs. Also, in the lines defining the function spaces, I’ve also tried with:

# define mixed finite element space
P1 = ufl.FiniteElement("Lagrange", domain.ufl_cell(), 1)
P1b = ufl.FiniteElement("Lagrange", boundDomain.ufl_cell(), 1)

V, LG = fem.FunctionSpace(domain, P1), fem.FunctionSpace(boundDomain, P1b)

M = ufl.MixedElement([P1, P1b]) # change here in lagrange multiplier space

Does anyone have suggestions or know the solution? Thanks!!

see GitHub - multiphenics/multiphenicsx: multiphenicsx - easy prototyping of multiphysics problems in FEniCSx (disclaimer: I am the author of that), or @jpdean branch in dolfinx

2 Likes

I’m currently encountering challenges while trying to implement Lagrange multipliers to constrain rigid body motion in FEniCSx. Despite consulting numerous relevant posts and trying out different methods, I haven’t found a solution yet.

Based on this suggestion, I’m contemplating using multiphenicsx to overcome this issue. However, before proceeding, I’d like to clarify whether multiphenicsx is indispensable for this task or if it’s achievable solely within the framework of FEniCSx.

Could someone provide insights into the feasibility and recommended practices for implementing Lagrange multipliers to restrict rigid body motion in FEniCSx? Additionally, if there are any specific resources or examples available, I’d greatly appreciate any guidance provided.

Search the forum with the keyword nullspace to constrain rigid body motions using dolfinx alone.

You can also find it in: Elasticity using algebraic multigrid — DOLFINx 0.7.3 documentation

1 Like

Thank you for your response and for pointing out the documentation on null space for elasticity. While the provided link offers handling null space for elasticity problems, I’m encountering challenges in adapting it to my specific problem of poroelasticity with mixed elements.

In my case, the problem involves a mixed function space comprising elements for pressure, fluid flux, and solid displacement, defined as follows:

ele_p = ufl.FiniteElement(“P”, mesh.ufl_cell(), 1) # pressure
ele_q = ufl.VectorElement(“P”, mesh.ufl_cell(), 2) # fluid flux
ele_us = ufl.VectorElement(“P”, mesh.ufl_cell(), 3) # solid displacement
element = ufl.MixedElement([ele_p, ele_q, ele_us])
W = FunctionSpace(mesh, element)>

When attempting to use the same approach as described in the elasticity example, I encountered the RuntimeError: “Cannot tabulate coordinates for a mixed FunctionSpace.”

I’ve been exploring potential solutions, but so far, I haven’t been successful in overcoming this issue. I believe the crux of the problem lies in the mixed nature of the function space.

Given this context, I’m reaching out to seek further guidance on how to handle null space constraints in the context of mixed element function spaces. Any additional insights or specific resources would be immensely helpful in resolving this issue.