How to modify NDSolve`StateData without crashing the kernel?
How to modify NDSolve`StateData without crashing the kernel?
Probably a hard question, but it's better to cry out loud.
Reminded by Chris K, I noticed my fix function has been broken since v11.3. After some checking, I found NDSolveStateData[…]`, which is not an atom in v9 and becomes an atom now, can no longer be modified with pattern matching.
To keep fix up to date, I tried the solution in this excellent post about modifying data inside atom, sadly the modified NDSolveStateDatacrashes the kernel in theNDSolveProcessSolutions stage even in v9 and I can't figure out a workaround.
The following is a simplified example attempting to modify the difference order to 2. The last line crashes the kernel of course so please save your work before testing.
tmax = 10; lb = 0; rb = 5;
system = With[{u = u[t, x]}, {D[u, t] == D[u, x, x], u == 0 /. t -> 0,
u == Sin[t] /. x -> lb, u == 0 /. x -> rb}];
{state} = NDSolve`ProcessEquations[system, u, {t, 0, tmax}, {x, lb, rb}];
teststate =
state /. a_NDSolve`FiniteDifferenceDerivativeFunction :>
RuleCondition@
NDSolve`FiniteDifferenceDerivative[a@"DerivativeOrder", a@"Coordinates",
"DifferenceOrder" -> 2, PeriodicInterpolation -> a@"PeriodicInterpolation"];
Head[#]["DifferenceOrder"] & /@
teststate["NumericalFunction"]["FunctionExpression"][[2, 1]]
(* Should give {{2}} if the replacement succeeds. *)
(*Failed attempt: *)
ml = LinkCreate[LinkMode -> Loopback];
LinkWrite[ml, With[{e = state}, Hold[e]]];
holdstate = LinkRead[ml];
newstate = holdstate /.
a_NDSolve`FiniteDifferenceDerivativeFunction :>
RuleCondition@
NDSolve`FiniteDifferenceDerivative[a@"DerivativeOrder", a@"Coordinates",
"DifferenceOrder" -> 2, PeriodicInterpolation -> a@"PeriodicInterpolation"] //
ReleaseHold
NDSolve`Iterate[newstate, tmax]
(*Warning: the following line crashes the kernel.*)
u /. NDSolve`ProcessSolutions@newstate
Any way to avoid the crashing and fix my fix function?
A bit of spelunking shows this seems to be (at least partly) related to InternalBag`. A minimal example:
bag = Internal`Bag[]
ml = LinkCreate[LinkMode -> Loopback];
LinkWrite[ml, With[{e = bag}, Hold[e]]]
holdbag = LinkRead[ml]
LinkClose[ml]
ReleaseHold[holdbag] === bag
(* False *)
K2-Think
To modify NDSolveStateDatawithout causing kernel crashes, especially when dealing with changes like adjusting the difference order, it's crucial to avoid direct manipulation of the atomicStateDataobject. Instead, configure the desired parameters during the initial setup usingNDSolve`'s method options. Here's how:
Problem Analysis
The NDSolveStateData` object became atomic in Mathe...
GPT-5
Short answer: You can’t safely do this any more. NDSolveStateData is now an opaque object that contains internal handles (e.g. InternalBag) whose identity has to be preserved. Any attempt to “crack it open” and rebuild it (including via the loopback-link Hold/ReleaseHold trick) will create new internal objects that no longer match the other references inside the state. That breaks NDSolve’s inva...
Claude 3.7 Sonnet
Modifying NDSolve`StateData Without Crashing the Kernel
This is indeed a challenging problem involving Mathematica's undocumented internals. I'll explain what's happening and suggest some potential approaches.
The Core Issue
The fundamental problem is that NDSolveStateData` became an atomic object in v11.3, meaning it can't be directly modified with pattern matching as it could in earlie...
Claude Opus 4
This is indeed a challenging problem related to modifying internal Mathematica structures that have become atomic in newer versions. The crash occurs because the modified NDSolveStateDataobject loses its internal integrity when manipulated through theLinkCreate/LinkWrite` workaround.
Understanding the Problem
The core issue is that NDSolveStateData` and related internal structures (...
o3 Pro
Short version
• Since version 11.3 NDSolve\StateData[…]is no longer an ordinary expression but an opaque “handle” that just stores a pointer to an internal C-structure. • As soon as that pointer is duplicated, e.g. byLinkWrite/LinkRead, or the object is reconstructed with Hold[…] /. … // ReleaseHold`, the link between the
Mathematica level and the C-level data is broken.
• Anything ...
DeepSeek R1
The goal is to change the "DifferenceOrder" of ...
Gemini 2.5 Pro
An excellent and challenging question. Your diagnosis is spot on: the kernel crash is indeed related to the way mutable structures like InternalBagare handled when they are "de-atomized" and "re-atomized" via the loopbackLinkRead/LinkWrite` trick.
The Cause of the Crash: Corrupted InternalBag`
When you create an NDSolveStateData` object, it contains several components. Some of th...
o3
Short version
‾‾‾‾‾‾‾‾‾‾‾‾
• Since version 10 NDSolve\StateData[…]is an **opaque, read-only kernel object**. • The object contains references (among others toInternal`Bag`) that are not preserved when an
expression is taken apart and rebuilt. As soon as such an object is copied or its internals are
re-inserted into a new expression the consistency of the reference structure is br...
o4 mini
Unfortunately there does not turn out to be a “magic” trick that will let you safely take an already‐baked StateData[…], reach inside its Internal`Bag‘s and switch out the difference order without blowing up the kernel. As soon as you serialize a StateData and re-import it you lose the original bag‐ids and the C-level code in ProcessSolutions will simply dereference a dead pointer.
In practice y...
You need to be logged in to submit an answer