On a box, a rotated free-slip constraint on Top and the ordinary component
condition add_dirichlet_bc((None, 0.0), "Top") pin the same velocity
components at the corner where Top meets Left/Right — the corner node has
u_x = 0 from the side wall and u_y = 0 from either treatment. The two runs
do not return the same answer there.
Measured
SolCx, StructuredQuadBox(elementRes=(32, 32)), eta_B/eta_A = 10,
petsc_use_pressure_nullspace = True, free slip on Left, Right, Bottom
via component Dirichlet. Two runs differing only in how Top is held:
add_dirichlet_bc((None, 0.0), "Top") against add_rotated_freeslip_bc(0.0, "Top").
Velocity errors against the analytic solution are 1.7e-03 (Dirichlet) and
3.3e-03 (rotated). The pressure difference between the two runs, both mean
removed:
| x |
y |
p_rotated − p_dirichlet |
| 1.0000 |
1.0000 |
+2.32e-01 |
| 0.9687 |
1.0000 |
−1.25e-01 |
| 0.9375 |
1.0000 |
+2.49e-02 |
| 0.0000 |
1.0000 |
−2.33e-02 |
rms below the top row: 4.2e-04, against a pressure rms of 1.1e-01. So the
disagreement is the corner and its immediate neighbours, not the wall.
Downstream: the recovered surface stress along the top wall reads 3.2e-01
relative for the rotated run against 4.8e-02 for the Dirichlet run. Trimming two
elements from each end brings them together — 5.6e-02 against 5.4e-02 — so the
whole of that factor of six is the two corner nodes. Same at every viscosity
contrast from 10 to 1e6.
Not necessarily a bug in the constraint: at a corner the rotated frame's normal
row is a mix, which boundary_normal_traction already handles by projecting the
Cartesian reaction. The question is whether the corner row of the rotated
velocity block should reduce to the component condition when the two coincide,
as it does here.
Reproduction: examples/solcx.py in UWTN 2026-016 (Boundary conditions on
non-planar boundaries), python3 solcx.py contrast.
Underworld development team with AI support from Claude Code
On a box, a rotated free-slip constraint on
Topand the ordinary componentcondition
add_dirichlet_bc((None, 0.0), "Top")pin the same velocitycomponents at the corner where
TopmeetsLeft/Right— the corner node hasu_x = 0from the side wall andu_y = 0from either treatment. The two runsdo not return the same answer there.
Measured
SolCx,
StructuredQuadBox(elementRes=(32, 32)),eta_B/eta_A = 10,petsc_use_pressure_nullspace = True, free slip onLeft,Right,Bottomvia component Dirichlet. Two runs differing only in how
Topis held:add_dirichlet_bc((None, 0.0), "Top")againstadd_rotated_freeslip_bc(0.0, "Top").Velocity errors against the analytic solution are 1.7e-03 (Dirichlet) and
3.3e-03 (rotated). The pressure difference between the two runs, both mean
removed:
rms below the top row: 4.2e-04, against a pressure rms of 1.1e-01. So the
disagreement is the corner and its immediate neighbours, not the wall.
Downstream: the recovered surface stress along the top wall reads 3.2e-01
relative for the rotated run against 4.8e-02 for the Dirichlet run. Trimming two
elements from each end brings them together — 5.6e-02 against 5.4e-02 — so the
whole of that factor of six is the two corner nodes. Same at every viscosity
contrast from 10 to 1e6.
Not necessarily a bug in the constraint: at a corner the rotated frame's normal
row is a mix, which
boundary_normal_tractionalready handles by projecting theCartesian reaction. The question is whether the corner row of the rotated
velocity block should reduce to the component condition when the two coincide,
as it does here.
Reproduction:
examples/solcx.pyin UWTN 2026-016 (Boundary conditions onnon-planar boundaries),
python3 solcx.py contrast.Underworld development team with AI support from Claude Code