Skip to content

Commit 262c57c

Browse files
Simplify WOperator copy method implementation
- Use internal constructor with new{...}(...) for direct field copying - Place copy method inside struct definition to access new constructor - Copy mutable fields (_func_cache, _concrete_form) to ensure independence - Much cleaner and more efficient than previous approach 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <[email protected]>
1 parent 068883f commit 262c57c

File tree

1 file changed

+11
-28
lines changed

1 file changed

+11
-28
lines changed

lib/OrdinaryDiffEqDifferentiation/src/derivative_utils.jl

Lines changed: 11 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -323,6 +323,17 @@ mutable struct WOperator{IIP, T,
323323
_func_cache, _concrete_form,
324324
jacvec)
325325
end
326+
327+
function Base.copy(W::WOperator{IIP, T, MType, GType, JType, F, C, JV}) where {IIP, T, MType, GType, JType, F, C, JV}
328+
return new{IIP, T, MType, GType, JType, F, C, JV}(
329+
W.mass_matrix,
330+
W.gamma,
331+
W.J,
332+
W._func_cache === nothing ? nothing : copy(W._func_cache),
333+
W._concrete_form === nothing ? nothing : copy(W._concrete_form),
334+
W.jacvec
335+
)
336+
end
326337
end
327338
function WOperator{IIP}(f::F, u, gamma) where {IIP, F}
328339
if isa(f, Union{SplitFunction, DynamicalODEFunction})
@@ -344,34 +355,6 @@ end
344355

345356
SciMLBase.isinplace(::WOperator{IIP}, i) where {IIP} = IIP
346357
Base.eltype(W::WOperator) = eltype(W.J)
347-
function Base.copy(W::WOperator{IIP}) where {IIP}
348-
# Create a dummy u vector for the constructor by using the same size as the func cache
349-
if W._func_cache !== nothing
350-
u = similar(W._func_cache)
351-
else
352-
# Fallback: try to infer size from J or mass_matrix
353-
if hasmethod(size, (typeof(W.J),))
354-
n = size(W.J, 1)
355-
u = zeros(n)
356-
else
357-
# If we can't determine size, use a minimal vector
358-
u = [0.0]
359-
end
360-
end
361-
362-
# Create new WOperator using the public constructor
363-
W_new = WOperator{IIP}(W.mass_matrix, W.gamma, W.J, u, W.jacvec)
364-
365-
# Manually copy the internal fields that might have been computed differently
366-
if W._func_cache !== nothing
367-
W_new._func_cache .= W._func_cache
368-
end
369-
if W._concrete_form !== nothing
370-
copyto!(W_new._concrete_form, W._concrete_form)
371-
end
372-
373-
return W_new
374-
end
375358

376359
# In WOperator update_coefficients!, accept both missing u/p/t and missing dtgamma and don't update them in that case.
377360
# This helps support partial updating logic used with Newton solvers.

0 commit comments

Comments
 (0)