Skip to content

Add 1D Allen-Cahn FEniCS playground: SDC order reduction & boundary lifting#636

Draft
Copilot wants to merge 3 commits intomasterfrom
copilot/add-1d-allen-cahn-playground
Draft

Add 1D Allen-Cahn FEniCS playground: SDC order reduction & boundary lifting#636
Copilot wants to merge 3 commits intomasterfrom
copilot/add-1d-allen-cahn-playground

Conversation

Copy link
Contributor

Copilot AI commented Mar 23, 2026

Summary

New playground at pySDC/playgrounds/FEniCS/allen_cahn_1d/ demonstrating SDC order reduction with inhomogeneous time-dependent Dirichlet boundary conditions for the 1D Allen-Cahn equation, and its remedy via boundary lifting. This follows the blueprint of PR #632 (heat equation) but applied to Allen-Cahn.

Equation

$$\frac{\partial u}{\partial t} = \frac{\partial^2 u}{\partial x^2} - \frac{2}{\varepsilon^2} u(1-u)(1-2u) - 6,d_w,u(1-u)$$

Exact solution (traveling wave):
$$u(x,t) = \tfrac{1}{2}!\left(1 + \tanh!\left(\frac{x - 0.5 - vt}{\sqrt{2},\varepsilon}\right)\right), \quad v = 3\sqrt{2},\varepsilon,d_w$$

The domain $[0,1]$ is a shift of $[-0.5, 0.5]$. Boundary conditions are inhomogeneous and time-dependent (exact solution evaluated at $x=0,1$).

New playground: pySDC/playgrounds/FEniCS/allen_cahn_1d/

Problem classes (problem_classes.py)

Both classes use an IMEX split with imex_1st_order_mass: diffusion implicit, nonlinear reaction explicit. Default parameters eps=0.3, dw=-0.04 ensure the front is well-resolved and the boundary values vary measurably with time.

  • fenics_allencahn_imex_timebc — naive time-dependent BC imposition: bc.apply(b.values.vector()) inside solve_system overwrites boundary DOFs of the accumulated SDC right-hand side with the exact Dirichlet data at the new time, disrupting the sweeper's fixed-point and causing order reduction.

  • fenics_allencahn_imex_timebc_lift — boundary lifting: decomposes $u = v + E$ where $E(x,t) = u_L(t)(1-x) + u_R(t),x$ is a linear interpolation of the boundary values. The transformed variable $v$ satisfies homogeneous BCs. solve_system only applies bc_hom (no overwrite), and eval_f includes the modified explicit forcing $M(-N(v+E) - E_t)$. This restores the full SDC collocation order.

Convergence study (run_convergence.py)

Standalone script varying dt over [0.5, 0.25, 0.125] and comparing estimated convergence orders for both problem classes.

Tests (test_order_reduction.py)

All tests are marked @pytest.mark.fenics.

Test Assertion
test_allencahn_order_reduction naive order < 2M − 1 − 0.3 for M=3
test_lifting_restores_full_order[M] lifting order ≥ 2M − 2 for M ∈ {2, 3}
test_lifting_has_higher_order_than_naive lifting order > naive order + 0.3

Security Summary

CodeQL found no alerts. No new dependencies were added.

@pancetta
Copy link
Member

@copilot Did you introduce an artificial order reduction by applying the boundary conditions to the accumulated right-hand side in the solver? Is the order reduction gone if you don't do this?

Copy link
Contributor Author

Copilot AI commented Mar 24, 2026

@copilot Did you introduce an artificial order reduction by applying the boundary conditions to the accumulated right-hand side in the solver? Is the order reduction gone if you don'...

No, the order reduction is not artificial. The previous implementation had a redundant second bc.apply(b.values.vector()) call, which I've now removed (commit d418a80).

The key point is that dolfin's bc.apply(T, b.values.vector()) call does two things at once: it modifies the system matrix and overwrites the boundary DOFs of b with the Dirichlet value u_D(t). This single necessary call is the source of the order reduction — it replaces whatever the SDC iteration had accumulated at the boundary nodes with the exact data at the new time, disrupting the sweeper's fixed-point property.

If you don't enforce the BCs at all in solve_system, the Dirichlet constraint is not applied and the solution is simply wrong. The only clean remedy — without compromising BC enforcement — is the boundary lifting in fenics_allencahn_imex_timebc_lift, which transforms to a homogeneous problem so that bc_hom.apply(T, b) sets boundary values to zero (consistent with what the SDC sweep has accumulated) and causes no disruption.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants