Skip to content

feat: Add graceful well-posedness check for missing boundary conditions#543

Open
utkuyilmaz1903 wants to merge 2 commits into
SciML:masterfrom
utkuyilmaz1903:clean-bc-pr
Open

feat: Add graceful well-posedness check for missing boundary conditions#543
utkuyilmaz1903 wants to merge 2 commits into
SciML:masterfrom
utkuyilmaz1903:clean-bc-pr

Conversation

@utkuyilmaz1903

@utkuyilmaz1903 utkuyilmaz1903 commented Mar 30, 2026

Copy link
Copy Markdown
Contributor

Summary

MethodOfLines did not check whether a PDE system had enough boundary conditions before starting discretization. If the setup was ill-posed, users often hit confusing errors deep inside the pipeline (e.g. bounds/index issues during upwind discretization) with no clear link back to missing or insufficient BCs.

This PR adds boundary_validation.jl and calls it from construct_var_equation_mapping before discretization proceeds.

What changes for users

Missing BCs: If a variable has a spatial derivative but no BC is given at any boundary point, discretization now stops early with a direct ArgumentError instead of failing later.

Issue #540 (parametric advection): For -v * Dx(u) with only one BC, the old behavior was an opaque downstream failure. Now MoL detects that the advection coefficient is dynamic (parameter/state-dependent), so the upwind direction is unknown at compile time, and asks for BCs at both ends.

Constant-velocity advection: For something like -2.0 * Dx(u), one BC is enough — the check does not treat numeric literals as dynamic coefficients (including Symbolics 7 wrapped literals).

Higher-order PDEs: The required number of boundary locations follows the max spatial derivative order (e.g. second order → two distinct locations).

Robin / Neumann BCs: Boundary locations are read from the BC expression AST, not just simple Dirichlet assignments.

Duplicate locations: 0 and 0.0 at the same point count as one location, not two.

Closes #540.

throw(ArgumentError(
"Missing boundary condition for variable $(u_op) in dimension $(x). " *
"The system is ill-posed. Since $(u_op) has spatial derivatives with respect to $(x), " *
"you must provide boundary conditions for both ends of the domain."

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what about upwinding problems where the velocity always has one sign? Then we only need an upwind BC

for x in spatial_ivs
has_deriv = false
for eq in pdes
if occursin_derivative_of(eq.lhs, u_op, x) || occursin_derivative_of(eq.rhs, u_op, x)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we also need to account for higher order derivs, where more than 2 BCs can be needed

@utkuyilmaz1903

Copy link
Copy Markdown
Contributor Author

Thanks for the guidance. I've updated the PR to dynamically check the maximum spatial derivative order by recursively scanning the AST. The validation rule is now simply bc_count < max_order. This correctly allows upwinding problems to pass with just 1 BC, while strictly catching missing BCs for higher-order derivatives.

@utkuyilmaz1903

utkuyilmaz1903 commented Apr 3, 2026

Copy link
Copy Markdown
Contributor Author

Interestingly, the MWE in #540 passes this well-posedness check. This suggests that the RuleRewriteError there might not be due to a missing BC after all, but could be an underlying issue with how Chebyshev grids handle parameterized advection terms. Since this PR no longer directly resolves #540, I've removed Fixes #540 from the description so this PR can just serve as a standalone well-posedness validation feature. Let me know if the updated logic looks good to you.

@utkuyilmaz1903

Copy link
Copy Markdown
Contributor Author

Following up on my previous comment from Apr 3: I was mistaken about #540 being a Chebyshev indexing bug.

I realized it is actually an ill-posed parameterized advection problem. Because the wind direction v is a parameter, the codegen generates IfElse branches for both directions, mathematically requiring both boundaries to be provided.

Currently, our bc_count < max_order logic allows 1st-order terms to pass with just 1 BC, which is exactly why this PR currently misses the missing right BC in 540. To make this gatekeeper truly bulletproof, I am planning to upgrade the validation logic to not just count the BCs, but to spatially parse them (via SymbolicUtils) to ensure both the lower and upper bounds of the domain are explicitly covered when necessary.

@utkuyilmaz1903 utkuyilmaz1903 force-pushed the clean-bc-pr branch 2 times, most recently from c0de918 to bb47d78 Compare May 26, 2026 10:33
@utkuyilmaz1903

Copy link
Copy Markdown
Contributor Author

@xtalax @ChrisRackauckas I updated the well-posedness validation logic.

@ChrisRackauckas

Copy link
Copy Markdown
Member

Needs tests. In particular, I'd like to see some periodic BC cases in there.

@utkuyilmaz1903

Copy link
Copy Markdown
Contributor Author

You probably noticed the current periodic behavior in the commits.

Right now, if a coupled BC (like periodic) is detected, the validation simply bypasses the counting logic. While this is a good temporary measure because it prevents unfairly blocking valid periodic setups, it also creates a loophole: a 4th-order PDE can currently pass validation with just a single periodic BC, which will cause a confusing crash later downstream.

I've also been analyzing a few other edge cases, specifically pure outflow systems (which mathematically require 0 spatial BCs) and one-sided dynamic advection like Burgers' equation.

Tomorrow, I will be working on upgrading the core logic to handle all these cases properly and I will add the tests.

@utkuyilmaz1903 utkuyilmaz1903 force-pushed the clean-bc-pr branch 2 times, most recently from c364a1c to a85522e Compare June 13, 2026 12:13
@utkuyilmaz1903

Copy link
Copy Markdown
Contributor Author

@ChrisRackauckas

I've added the component tests, including the periodic cases. I've also updated the core logic.

Just a quick note on one design choice I made. I kept the dynamic advection check strict (demanding 2 BCs for non-constant coefficients). I think this is the safest approach for compile-time stability since the upwind direction is unknown, even though it might be slightly restrictive for edge cases like pure outflow or one-sided Burgers' equations.

I think it is in a good state now, but please let me know if you think we should adjust anything.

@utkuyilmaz1903

Copy link
Copy Markdown
Contributor Author

I think the current CI failures seem to be infrastructure-related and not related to this PR

@utkuyilmaz1903

Copy link
Copy Markdown
Contributor Author

@ChrisRackauckas

I wanted to report my findings. I've looked into the logs, and it seems our new BC validator might actually be catching some legacy tests that are genuinely missing spatial constraints:

  • Convection_WENO (Test 05): 4th-order, but seems to only provide 2 effective constraints via periodic BCs.
  • Higher_Order (Test 01): Appears to be missing the clamped edge slope Dx(u) ~ 0 at x=0.
  • Mixed_Derivatives (Test 01): Looks like it's missing a BC at x=1.
  • MOL_Interface1 ("RHS = 0"): 4th-order, but seems to only have 2 derivative BCs.

For the other failing jobs, based on the logs, they appear to fail for unrelated reasons:

  • 2D_Diffusion: Test 00 passes completely; Test 01 fails with a BoundsError in cartesian_nonlinear_laplacian (unrelated to BC validation).
  • DAE: Discretization succeeds, but solve fails during DAE initialization (normresid ≈ 0.003 > 1e-6).
  • Diffusion_NU: The self-hosted runner lost communication with the server (infrastructure issue).

(Also, the downstream PDESystemLibrary has many examples hitting the new validator, likely for similar missing BC reasons).

Let me know what you think.

Add missing newline at end of file.
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.

RuleRewriteError: Chebyshev grid + UpwindScheme fails for parameterized advection terms

3 participants