Repository navigation
Fix complex boundary condition splitting (supersedes #133) - #161
Merged
Merged
Conversation
Test complex coefficients, products between dependent fields, and duplicated real/imaginary boundary equations. The regression fails against the current normalization before the fix. Co-Authored-By: Chris Rackauckas <accounts@chrisrackauckas.com> Co-Authored-By: Codex <noreply@openai.com> Agent-Harness: Codex CLI 0.156.0 Agent-Model: gpt-6-luna Agent-Session: local session, transcript at /home/crackauc/sandbox/agent-jobs/PDEBase.jl/jobs/125-codex/log.txt on amdci2.julia.csail.mit.edu
Retain ModelingToolkit's equation-pair grouping, reconstruct each complex residual, substitute real and imaginary dependent variables, then expand derivatives and complex products before splitting. Generate real-valued component variables and use the same residual split for complex boundary equations. Co-Authored-By: Chris Rackauckas <accounts@chrisrackauckas.com> Co-Authored-By: Codex <noreply@openai.com> Agent-Harness: Codex CLI 0.156.0 Agent-Model: gpt-6-luna Agent-Session: local session, transcript at /home/crackauc/sandbox/agent-jobs/PDEBase.jl/jobs/125-codex/log.txt on amdci2.julia.csail.mit.edu
Split each side of complex equations independently so downstream symbolic consumers retain the equation form they expect. Co-Authored-By: Chris Rackauckas <accounts@chrisrackauckas.com> Co-Authored-By: Codex <noreply@openai.com> Agent-Harness: Codex CLI 0.156.0 Agent-Model: gpt-6-luna Agent-Session: local session, transcript at /home/crackauc/sandbox/agent-jobs/PDEBase.jl/jobs/125-codex/log.txt on amdci2.julia.csail.mit.edu
Cover a time-dependent complex Dirichlet condition at the BC splitting boundary, rename the imaginary component local, and remove the unused ComplexEq type. Keep handle_complex's real-equation branch because complex BC-only systems can reach it. Co-Authored-By: Chris Rackauckas <accounts@chrisrackauckas.com> Co-Authored-By: Codex <noreply@openai.com> Agent-Harness: Codex CLI 0.156.0 Agent-Model: gpt-6-luna Agent-Session: local session, transcript at /home/crackauc/sandbox/agent-jobs/PDEBase.jl/jobs/125-codex/log.txt on amdci2.julia.csail.mit.edu
Resolve the follow-up against the now-merged complex coupling change and current release base. Co-Authored-By: Chris Rackauckas <accounts@chrisrackauckas.com> Co-Authored-By: Codex <noreply@openai.com> Agent-Harness: Codex CLI 0.156.0 Agent-Model: gpt-6-luna Agent-Session: local session, transcript at /home/crackauc/sandbox/agent-jobs/PDEBase.jl/jobs/125-codex/log.txt on amdci2.julia.csail.mit.edu
Co-Authored-By: Chris Rackauckas <accounts@chrisrackauckas.com> Co-Authored-By: Codex <noreply@openai.com> Agent-Harness: Codex CLI 0.156.1 Agent-Model: gpt-6-sol Agent-Session: local session, transcript at /home/crackauc/sandbox/agent-jobs/PDEBase.jl/jobs/130-codex/log.txt on amdci2.julia.csail.mit.edu
Co-Authored-By: Chris Rackauckas <accounts@chrisrackauckas.com> Co-Authored-By: Codex <noreply@openai.com> Agent-Harness: Codex CLI 0.156.1 Agent-Model: gpt-6-sol Agent-Session: local session, transcript at /home/crackauc/sandbox/agent-jobs/PDEBase.jl/jobs/130-codex/log.txt on amdci2.julia.csail.mit.edu
Co-Authored-By: Chris Rackauckas <accounts@chrisrackauckas.com> Co-Authored-By: Codex <noreply@openai.com> Agent-Harness: Codex CLI 0.156.1 Agent-Model: gpt-6-luna Agent-Session: local session, transcript at /home/crackauc/sandbox/agent-jobs/PDEBase.jl/jobs/127-codex/log.txt on amdci2.julia.csail.mit.edu
Co-Authored-By: Chris Rackauckas <accounts@chrisrackauckas.com> Co-Authored-By: Codex <noreply@openai.com> Agent-Harness: Codex CLI 0.156.1 Agent-Model: gpt-6-luna Agent-Session: local session, transcript at /home/crackauc/sandbox/agent-jobs/PDEBase.jl/jobs/127-codex/log.txt on amdci2.julia.csail.mit.edu
Co-Authored-By: Chris Rackauckas <accounts@chrisrackauckas.com> Co-Authored-By: Codex <noreply@openai.com> Agent-Harness: Codex CLI 0.156.1 Agent-Model: gpt-6-sol Agent-Session: local session, transcript at /home/crackauc/sandbox/agent-jobs/PDEBase.jl/jobs/130-codex/log.txt on amdci2.julia.csail.mit.edu
Co-Authored-By: Chris Rackauckas <accounts@chrisrackauckas.com> Co-Authored-By: Codex <noreply@openai.com> Agent-Harness: Codex CLI 0.156.1 Agent-Model: gpt-6-luna Agent-Session: local session, transcript at /home/crackauc/sandbox/agent-jobs/PDEBase.jl/jobs/127-codex/log.txt on amdci2.julia.csail.mit.edu
Flatten nested boundary groups without inferring complex equations from their shape. Use typed complex fields for Symbolics pre-split complex boundary expressions, split known complex equations mathematically, and reject false boundary sides. Co-Authored-By: Chris Rackauckas <accounts@chrisrackauckas.com> Co-Authored-By: Codex <noreply@openai.com> Agent-Harness: Codex CLI 0.156.1 Agent-Model: gpt-6-luna Agent-Session: local session, transcript at /home/crackauc/sandbox/agent-jobs/PDEBase.jl/jobs/127-codex/log.txt on amdci2.julia.csail.mit.edu
Co-Authored-By: Chris Rackauckas <accounts@chrisrackauckas.com> Co-Authored-By: Codex <noreply@openai.com> Agent-Harness: Codex CLI 0.156.1 Agent-Model: gpt-6-luna Agent-Session: local session, transcript at /home/crackauc/sandbox/agent-jobs/PDEBase.jl/jobs/127-codex/log.txt on amdci2.julia.csail.mit.edu
Real systems that group boundary conditions per boundary point (clamped beam, interface conditions) produce the same nested two-equation shape Symbolics emits when it pre-splits a complex boundary condition, and were rejected with advice to declare ::Complex. The pair rejection now only runs when the equations or boundary conditions already contain complex values, except for a `0 ~ expr` member over a parameter-only expression, which constrains no unknown and is a definite pre-split signature. The boundary `false` check is also skipped for Complex-typed fields, where Symbolics' `real(ψ) ~ false, imag(ψ) ~ true` split of `ψ ~ im` is exact, and the docs now name the silently truncated literal forms. Co-Authored-By: Chris Rackauckas <accounts@chrisrackauckas.com> Co-Authored-By: Devin <noreply@cognition.ai> Agent-Harness: Devin CLI 3000.11.1 Agent-Model: swe-2-max Agent-Session: local session, transcript at /home/crackauc/sandbox/agent-jobs/PDEBase.jl/jobs/127-codex/log-cont1.txt on amdci2.julia.csail.mit.edu
Co-Authored-By: Chris Rackauckas <accounts@chrisrackauckas.com> Co-Authored-By: Codex <noreply@openai.com> Agent-Harness: Codex CLI 0.157.1 Agent-Model: gpt-6-luna Agent-Session: local session, transcript at /home/crackauc/sandbox/aj/p127/log-cont2.txt on amdci2.julia.csail.mit.edu
Symbolics 7.42 marks an opted-in complex `~` as `SplitComplexEquation` (split_complex_equation), which preserves the original complex equation. handle_complex restores that original before flattening so the condition splits with real and imaginary parts coupled; plain `~` output and hand-written pairs stay ambiguous and are still rejected. Nested pairs containing a literal `0 ~` member now reject unconditionally: that is Symbolics' pre-split signature (the imaginary half of a real-typed lhs) and otherwise flattens silently into wrong real BCs for untyped complex conditions on real-coefficient PDEs. Real grouped pairs of that shape must be passed un-nested. Bump the Symbolics compat to 7.42 for the marker API, and document the opt-in marker alongside the typed `::Complex` recommendation. Co-Authored-By: Chris Rackauckas <accounts@chrisrackauckas.com> Co-Authored-By: Devin <noreply@cognition.ai> Agent-Harness: Devin CLI 3000.11.3 Agent-Model: swe-2-max Agent-Session: local session, transcript at /home/crackauc/sandbox/aj/p127/log-cont3.txt on amdci2.julia.csail.mit.edu
A nested pair `[L ~ a, 0 ~ b]` where `L` is a single dependent-variable application (possibly under a `Differential`) and neither `a` nor `b` mentions a dependent variable can only be Symbolics' split of `L(ψ) ~ a + i b`, so rebuild it as that equation instead of rejecting. This restores MethodOfLines' "Schroedinger with complex bcs" test input, which passed on master and errored on the previous head. Pairs whose members both have a `0 ~` left-hand side mean the same thing as a real grouping or a `0 ~` complex split, so they pass through; other nested pairs containing a `0 ~` member keep being rejected, as do same-instance pairs on systems with complex values. Also document that `Symbolics.split_complex_equation` is only valid for holomorphic conditions on untyped fields (`conj`/`real`/`imag`/`abs`/`abs2` simplify before the marker is built) and that numeric complex data truncates the same way as `~`; pin both limitations in tests. Remove the dead `Symbolics.value` try/catch in `_split_complex_components` and bump to 0.1.39 so the release can register. Co-Authored-By: Chris Rackauckas <accounts@chrisrackauckas.com> Co-Authored-By: Devin <noreply@cognition.ai> Agent-Harness: Devin CLI 3000.11.3 Agent-Model: swe-2-max Agent-Session: local session, transcript at /home/crackauc/sandbox/aj/p127/log-cont6.txt on amdci2.julia.csail.mit.edu
A nested pair of `0 ~`-lhs equations was passed through unconditionally, but a pair where exactly one member is free of dependent variables is the Symbolics pre-split of a residual-form complex condition like `0 ~ ψ(t,0) - exp(im*t)` — as a real grouping a DV-free `0 ~ b` constrains no unknown — and passing it through silently mis-splits it: each member was duplicated into both components. Rebuild such a pair as `0 ~ a + i b` so it splits with real and imaginary parts coupled; keep the pass-through only when both members mention a dependent variable (broadcast Neumann pairs, grouped real constraints) and reject pairs with no dependent variable at all. Docs: write complex conditions with the field on the left, since a reversed `exp(im*t) ~ ψ(t,0)` pre-splits to a shape that cannot be reconstructed. Drop the testset that pinned a Symbolics truncation defect as PDEBase behaviour; the workflow doc sentence covers it. Co-Authored-By: Chris Rackauckas <accounts@chrisrackauckas.com> Co-Authored-By: Devin <noreply@cognition.ai> Agent-Harness: Devin CLI 3000.11.3 Agent-Model: swe-2-max Agent-Session: local session, transcript at /home/crackauc/sandbox/aj/p127/log-cont7.txt on amdci2.julia.csail.mit.edu
- Define the `SplitComplexEquation` restore method only when the installed Symbolics provides it, and set the Symbolics compat floor back to 7.39.2. Every registered Symbolics (up to 7.46.0) lacks the marker, so the previous `Symbolics = "7.42"` entry made PDEBase fail to precompile. The pre-split error message names `split_complex_equation` only when it exists, and the marker testset runs only when Symbolics provides it. - Read pre-split pairs with the field on the right (`exp(im*t) ~ ψ(t, 0)`, `exp(im*t) ~ Dx(ψ(t, 1))`, `ψ(t, 0) - exp(im*t) ~ 0`) as the mirror image of the field-on-the-left rules. These previously split silently into inconsistent real systems. - Handle array-valued dependent variables when collecting dependent operations in `handle_complex`; the "Optimization-system replaced variable map" test merged from master errored with a MethodError. - Build the unsplit complex BC in complex_splitting.jl with the `Equation` constructor instead of the unreleased marker API. - Bump version to 0.1.40 (0.1.39 is registered). Co-Authored-By: Chris Rackauckas <accounts@chrisrackauckas.com> Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Agent-Harness: Claude Code 2.1.301 Agent-Model: claude-opus-5-5 Agent-Session: local session ID 30f090ef-c4ec-41be-88b4-ad1ffd17da57 (headless claude -p, no URL)
A nested `[0 ~ a, L ~ b]` pair whose members both mention a dependent variable, such as `[0 ~ u(t, 0), u(t, 1) ~ 1]` on a real heat equation, was rejected with an ArgumentError although master accepted it and returned it unchanged. Such pairs are now left to `_ambiguous_presplit_bc`, which rejects them only when the system shows complex values, matching the existing rule for same-point pairs. Pairs whose `0 ~` member or second member constrains no unknown are still rejected. On a purely real system an untyped `im*Dx(ψ(t, 1)) ~ ψ(t, 1)` pre-splits to the same shape and is read as real, as on master; workflow.md says to declare `::Complex` for such conditions. Co-Authored-By: Chris Rackauckas <accounts@chrisrackauckas.com> Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Agent-Harness: Claude Code 2.1.301 Agent-Model: claude-opus-5-5 Agent-Session: local session ID 30f090ef-c4ec-41be-88b4-ad1ffd17da57 (headless claude -p, no URL)
…rejected On an untyped field `ψ(t, 0) + im*Dx(ψ(t, 0)) ~ 0` reaches PDEBase as `[ψ(t, 0) ~ 0, Dx(ψ(t, 0)) ~ 0]`, and `im*Dx(ψ(t, 0)) ~ ψ(t, 0)` as `[0 ~ ψ(t, 0), Dx(ψ(t, 0)) ~ 0]`, so these are indistinguishable from the grouped clamped conditions that master accepted on complex systems. Master turns the Robin conditions into clamped ones. The new testset asserts that both forms and both groupings are rejected, and that the typed form splits exactly. Removing the same-point check from `_ambiguous_presplit_bc` makes two of its assertions fail; no other test covered that check. Co-Authored-By: Chris Rackauckas <accounts@chrisrackauckas.com> Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Agent-Harness: Claude Code 2.1.301 Agent-Model: claude-opus-5-5 Agent-Session: local session ID 30f090ef-c4ec-41be-88b4-ad1ffd17da57 (headless claude -p, no URL)
…ndition splitting Merges the 22 commits of SciML/PDEBase#133 (branch agent/127-complex-bcs-master of ChrisRackauckas-Claude/PDEBase.jl, head e4ec7f4) with their authorship intact, onto current master. Conflicts: Project.toml keeps master's version; in src/make_pdesys_compatible.jl split_complex_bc keeps master's SciML#137 form (no duplication of real BC data into the imaginary component, Pairs split as equations) and drops the PreSplitComplexBC branch and SciML#133's older hascomplex/duplicate path. Agent-Harness: Claude Code 2.1.312 Agent-Model: claude-sonnet-5-5 Agent-Session: a20a681b-e8cc-4c82-a40d-a5b8349014e2 Agent-Review: unreviewed Co-authored-by: Claude Code <agent@noreply.juliahub.com>
_dv_application looked through a single Differential layer, so a pre-split mixed-derivative condition such as Dt(Dx(u(t, 0))) ~ exp(im*t) was rejected. It now unwraps Differential applications recursively. Adds a mixed-derivative regression test (field on the left and on the right). Agent-Harness: Claude Code 2.1.312 Agent-Model: claude-sonnet-5-5 Agent-Session: a20a681b-e8cc-4c82-a40d-a5b8349014e2 Agent-Review: unreviewed Co-authored-by: Claude Code <agent@noreply.juliahub.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Supersedes #133 (this branch merges its 22 commits with authorship intact; thanks to its author); it is rebased by merge onto current master and reconciled with #137.
🤖 AI-generated pull request. The code was written by AI agents: Codex CLI 0.156–0.157 (gpt-6-luna, gpt-6-sol), Devin CLI 3000.11 (swe-2-max) and Claude Code 2.1.301 (claude-opus-5-5). Each agent commit's trailers name its harness and model. Three early commits (
abb3048,0b76a1d,a9b0189) carry no agent trailers, and0057ebcis a merge of master. So far the PR has been reviewed only by AI agents (Claude Code / claude-opus-5-5 and Codex CLI / gpt-6.1-sol); no human has reviewed it.The merge and conflict-resolution commit on this branch is by Claude Code 2.1.312 (claude-sonnet-5-5), unreviewed; its
Agent-*trailers say so.Part of #127. The behaviour is that of #133 (see its description for the full rules, examples and review history); this description covers what differs.
What changed relative to #133
git merge --no-ffofChrisRackauckas-Claude:agent/127-complex-bcs-master(heade4ec7f4) into master0854e6d. No commit of Fix complex boundary condition splitting #133 was amended.Project.toml: kept master's0.1.41. The version is not touched (see Breaking change).src/make_pdesys_compatible.jl,split_complex_bc: kept master's Fix real BC/IC data being duplicated into the imaginary component on complexified untyped fields #137 form. APair(initial condition) is turned into an equation and every boundary condition goes throughsplit_complex_eq(...; expand_derivatives = false); Fix complex boundary condition splitting #133's older copy of this function (aPairspecial case and a!hascomplexbranch that duplicated real data into both components) and master'sPreSplitComplexBCbranch are dropped. Fix complex boundary condition splitting #133'shandle_complexchanges (presplit-pair rebuilding, rejections, marker restore, array-valued variables) are all kept.src/variable_map.jl: Fix complex boundary condition splitting #133's removal of thePreSplitComplexBCheuristic from_flatten_bcsapplied cleanly on top of master's Order VariableMap x̄ by the dependent variables, not by Set iteration #160/Add MeshDomain interface and domain-aware VariableMap #145 changes; nothing of master's was dropped.Dt(Dx(u(t,0))) ~ exp(im*t), and its mirror), which Fix complex boundary condition splitting #133 rejected because it looked through only oneDifferentiallayer; regression test added. On master the same input throws aMethodError, so it is a fix, not a regression.handle_complex's grouping is split, Fix complex boundary condition splitting #133 changes which pre-split pairs are rebuilt or rejected before that.test/complex_splitting.jl(including Fix real BC/IC data being duplicated into the imaginary component on complexified untyped fields #137's "Real BC/IC data is not duplicated into the imaginary part", 6 assertions) andtest/complex_boundary_conditions.jl(60 assertions) both pass.Breaking change
This changes the public behaviour of
handle_complex, and with itsymbolic_discretize: boundary inputs that master accepted now throwArgumentError(for example untyped[ψ(t,0) ~ 0, Dx(ψ(t,0)) ~ 0]and[0 ~ ψ(t,0), Dx(ψ(t,0)) ~ 0]on a complex system, and[0 ~ sin(t), 0 ~ cos(t)]). They reach PDEBase as the same equations as untyped Robin conditions with an imaginary coefficient, which master silently turns into clamped conditions; see #133's description for the full table. It requires a minor version bump to0.2.0(0.x SemVer) before merging, together with compat updates in MethodOfLines, NeuralPDE and PDESystemLibrary.Project.tomlis deliberately unchanged here (0.1.41) because the bump is the maintainers' call. This PR must not be merged or registered as a0.1.xrelease.Known limitations
ψ(..)::Complexis the reliable path, and typed fields split exactly.im*Dx(ψ(t,1)) ~ ψ(t,1)pre-splits to[0 ~ ψ(t,1), Dx(ψ(t,1)) ~ 0]and is read as a real grouping. That is wrong, and it is the same as master.ψ(t,0) + im*Dx(ψ(t,0)) ~ 0behaves the same way.docs/src/workflow.mdtells users to declare::Complexfor such conditions.workflow.md).Symbolics.SplitComplexEquationmarker path (Add opt-in split_complex_equation returning a marked SplitComplexEquation JuliaSymbolics/Symbolics.jl#2008) is valid only for holomorphic conditions, and is untested here because no registered Symbolics defines it.pre, and the full Downgrade resolution.Tests
On this branch (head after the merge), with Symbolics at the registry resolution of each channel:
test/complex_boundary_conditions.jl,test/complex_splitting.jl,test/d_orders.jlthrough TestEnv on Julia 1.12.1 (default) and 1.10.12 (+lts): 62/62, 4+6+1+24 (all complex_splitting testsets, 35 total), and 15/15 on both channels.GROUP=Coreon 1.12.1: all files pass;complex_boundary_conditions.jl62/62,complex_splitting.jl35/35,d_orders.jl15/15,to_box_bcs.jl1412/1412; the only broken entries are 7 pre-existing@test_brokeninboundary_syntax.jl(96 pass, 7 broken, 103 total).GROUP=Coreon 1.13.2 (+release): the same counts.GROUP=QAon 1.12.1:QA/qa.jl20/20.--checkonsrc/make_pdesys_compatible.jl,src/variable_map.jl,test/complex_boundary_conditions.jlandtest/complex_splitting.jl: clean.🤖 Posted by an AI agent · harness: Claude Code 2.1.312 · model: claude-sonnet-5-5
Review: unreviewed
Session: a20a681b-e8cc-4c82-a40d-a5b8349014e2