Hello,
Is there a function to get the index from variable names in ModelingToolkit.jl? Or a function that returns me a varmap (Vector{Pair{Num, Float64}})?
So the opposite of ModelingToolkit.varmap_to_vars()
I’m currently using:
function varname_to_varmapindex(varname)
states_sys = states(sys)
length_states = size(states_sys, 1)
index = findfirst(i -> (states_sys[i].metadata)[Symbolics.VariableSource][2] == varname, 1:length_states)
return isnothing(index) ? -1 : index # Return -1 or another suitable value if not found
end
For example, in a callback I would like to call the variable by name and not by the index.
function affect!(integrator)
index = varname_to_varmapindex(:varname)
integrator.u[index] += 1.0
end
The integrator struct doesn’t have provide a way to access the system, so the only way I have figured out to do this is to create the affect (or condition) in a closure. You should modify your varname_to_varmapindex function to accept an argument for sys as well, creating sys as a global variable can lead to performance problems.
function create_increment_affect(sys, varname)
let index = varname_to_varmapindex(sys, varname)
function affect!(integrator)
integrator.u[index] += 1.0
end
end
end
Another option, since you are already using ModelingToolkit, is to use the symbolic event handling interface. Most uses of callbacks can be fit into this framework, although you do need to occasionally mark a variable as irreducible (tell the simplification code not to elminiate this variable as a state).
Do I understand correctly that the difference between Event Handling and Callback Functions is that an event is symbolically added to the ODE system and, after simplification, is executed as a callback?
“Event” and “Callback” is used almost interchangeably. An “event” is something that happens (condition triggers) that triggers an action, the callback function.
When you use the symbolically specified events in MTK, those are translated internally into callbacks, similar to how you would write the callbacks yourself.