Nonlinear Poisson with periodic coupling

I need to implement a nonlinear periodic coupling within the same domain. In strong form, the problem is similar to Nonlinear Poisson with a periodic coupling:

-\nabla \cdot \left(q(u) \nabla u\right) = \begin{cases}f(u(x, y)) & \text{if } (x,y)\in \Omega_1,\\ f(u(x,y))+f(u(x, y-2\pi)) & \text{otherwise},\end{cases}
u = u_D(\mathbf{x}), \qquad \text{on }\partial \Omega

where \Omega := \Omega_1\cup\Omega_2, \Omega_1 := (0, 1)\times (0, 2\pi), \Omega_2 := (0, 1)\times (2\pi, 4\pi), f: \Omega \to \mathbb{R} and q: \Omega \to \mathbb{R} are nonlinear.

Looking at a recent useful post, Long-range coupling, it’s looking like one way is to define a mapping T(x,y)=(x,y-2\pi), rewrite the problem as

-\nabla \cdot \left(q(u) \nabla u\right) = \begin{cases}f(u(x, y)) & \text{if } (x,y)\in \Omega_1,\\ f(u(x,y))+f(u(T(x, y)) & \text{otherwise},\end{cases}
u = u_D(\mathbf{x}), \qquad \text{on }\partial \Omega

and update fenicsx_ii to work with Nonlinear problems. But the example in the previous post is for disconnected domains. Am I thinking about this the right way, or is there a better way to do this?

i struggle a bit to see why you would need to define v at all, as your source term
\mathbf{1}_{\Omega_2}f(v) can be written as f(v(x, y)), x\in[0,1], y\in [2\pi,4\pi]
which is equivalent to f(u(x, y-2\pi)) x\in[0,1], y\in[2\pi,4\pi], which becomes
f(u(x,z)), x\in[0,1], z\in[0,2\pi], which is just \mathbf{1}_{\Omega_1}f(u)?

I have updated the problem statement to avoid a typo / confusion with notation.

Aha. Now i get the need for the coupling.
I’ve made a modification to FEniCSx_ii in: Mapped-restriction and subset restrictions by jorgensd · Pull Request #22 · scientificcomputing/fenicsx_ii · GitHub
which I believe will help you with your issue.
Specifically:

    translation_vector = np.array([0, 0.5])

    def translate_1_to_0(x):
        x_out = x.copy()
        for i, ti in enumerate(translation_vector):
            x_out[i] -= ti
        return x_out
    restriction = MappedRestriction(mesh, translate_1_to_0)
    tol = 20 * np.finfo(dtype).eps

    A, _, _ = create_interpolation_matrix(
        V,
        V,
        restriction,
        use_petsc=use_petsc,
        cells_K=upper_cells,
        tol=tol,
        complex_dtype=use_complex,
    )

creates the interpolation operator central for mapping data something in the same function space to another part of the problem.

I don’t have time tonight to further work on this, but it should give you some pointers on where to continue with modifications of FEniCSx_ii.
Note that with this kind of restriction operator, there shouldn’t be a need for an intermediate variable v, as far as I can tell.

2 Likes