Modified MWE to force single input argument. Code now is
# define the mesh with N elements e_k = [x_k, x_{k+1}] for 1 <= k <= N
# the mesh contains N+1 nodes of which N-1 internal and 2 (left and right) boundary nodes
N = 5; h = 1/N;
# define mesh points
xmesh = Vector(0:h:1)
# define evaluation points
xeval = Vector(0:h:1)
# define midpoints
xmid = Vector(h/2:h:1-h/2)
# define the magnetization coefficients
m = ones(N)
# define kernel
function kernel(x,xp)
return x+xp
end
# compute integral by quadrature over second input (xp) over all elements e_k
# on e_k the integral is x-dependent and stored in a array of functions
function foo(x,m,xmesh)
N = length(m)
fooarray = Array{Function}(undef, N)
for k=1:N
fooarray[k] = (x,m,xmesh) -> quadgk(xp -> m[k]*kernel(x,xp), xmesh[k], xmesh[k+1])[1]
end
return sum([fooarray[k](x,m,xmesh) for k=1:N])
end
# average of gradient of foo over e_k
function avgfoo(m)
N = length(m)
bfluxvec = zeros(N)
for k=1:N
bfluxvec[k] = quadgk(x -> foo(x,m,xmesh), xmesh[k], xmesh[k+1];atol=1e-2, rtol=1e-2)[1]
end
return bfluxvec
end
# evaluate foo in the nodes
foosamp = foo.(xeval,Ref(m),Ref(xmesh))
# evaluate avgddxfoo on the elements
avgfoosamp = avgfoo(m)
p1 = plot(xeval, foosamp)
p2 = plot(xmid, avgfoosamp)
plot(p1,p2,layout=(1,2))
# compute the Jacobian wrt parameters m
Cp = ForwardDiff.jacobian(avgfoo, m)
Resulting stack trace is
MethodError: no method matching Float64(::ForwardDiff.Dual{ForwardDiff.Tag{typeof(avgfoo), Float64}, Float64, 5})
Closest candidates are:
(::Type{T})(::Real, ::RoundingMode) where T<:AbstractFloat at rounding.jl:200
(::Type{T})(::T) where T<:Number at boot.jl:772
(::Type{T})(::AbstractChar) where T<:Union{AbstractChar, Number} at char.jl:50
…
Stacktrace:
[1] convert(#unused#::Type{Float64}, x::ForwardDiff.Dual{ForwardDiff.Tag{typeof(avgfoo), Float64}, Float64, 5})
@ Base ./number.jl:7
[2] setindex!(A::Vector{Float64}, x::ForwardDiff.Dual{ForwardDiff.Tag{typeof(avgfoo), Float64}, Float64, 5}, i1::Int64)
@ Base ./array.jl:966
[3] avgfoo(m::Vector{ForwardDiff.Dual{ForwardDiff.Tag{typeof(avgfoo), Float64}, Float64, 5}})
@ Main ./In[90]:35
[4] vector_mode_dual_eval!
@ ~/.julia/packages/ForwardDiff/PcZ48/src/apiutils.jl:24 [inlined]
[5] vector_mode_jacobian(f::typeof(avgfoo), x::Vector{Float64}, cfg::ForwardDiff.JacobianConfig{ForwardDiff.Tag{typeof(avgfoo), Float64}, Float64, 5, Vector{ForwardDiff.Dual{ForwardDiff.Tag{typeof(avgfoo), Float64}, Float64, 5}}})
@ ForwardDiff ~/.julia/packages/ForwardDiff/PcZ48/src/jacobian.jl:125
[6] jacobian(f::Function, x::Vector{Float64}, cfg::ForwardDiff.JacobianConfig{ForwardDiff.Tag{typeof(avgfoo), Float64}, Float64, 5, Vector{ForwardDiff.Dual{ForwardDiff.Tag{typeof(avgfoo), Float64}, Float64, 5}}}, ::Val{true})
@ ForwardDiff ~/.julia/packages/ForwardDiff/PcZ48/src/jacobian.jl:0
[7] jacobian(f::Function, x::Vector{Float64}, cfg::ForwardDiff.JacobianConfig{ForwardDiff.Tag{typeof(avgfoo), Float64}, Float64, 5, Vector{ForwardDiff.Dual{ForwardDiff.Tag{typeof(avgfoo), Float64}, Float64, 5}}}) (repeats 2 times)
@ ForwardDiff ~/.julia/packages/ForwardDiff/PcZ48/src/jacobian.jl:19
[8] top-level scope
@ In[90]:51