Simulate ModelingToolkit system with different parameters

Hi all,

In the past day, I have been reading the documentation on efficiently simulating ModelingToolkit models with different parameters. However, I find the documentation somewhat complex, especially for new users. In my case, I have a very simple system, which consists of a constant input and an integrator:

using ModelingToolkit, Plots, OrdinaryDiffEq
using ModelingToolkit: t_nounits as t, D_nounits as D
using ModelingToolkitStandardLibrary.Blocks


@mtkmodel TestModel begin

	@parameters begin

		value=3
	
	end

	@components begin

		InputBlock = Constant(k=value)
		IntegratorBlock =  Integrator(k=1.0,x=0.0)
	end

	@equations begin

		connect(InputBlock.output,IntegratorBlock.input)

	end

end
@mtkbuild system = TestModel()
prob = ODEProblem(system,Pair[],(0,10.0))
sol = solve(prob,Tsit5(), dt=0.001, adaptive=false) 

Suppose I want to re-simulate the system by changing the parameter of the constant value that serves as the input, without having to recompile the system. In this case, when I query the parameters, I get the following:

prob.p

First, I noticed that the initial value (in this case, 3) appears twice: once as a constant and once as the input value of the constant block. When trying to re-simulate the system by changing this parameter (for example, to 5), I implemented the following code. However, the solution of the system does not change at all.

p_new = copy(prob.p)  
p_new[1][4] = 5
prob2 = remake(prob; p = p_new)
sol2 = solve(prob2,Tsit5(), dt=0.001, adaptive=false) 

For this reason, I wonder if this process is incorrect. If it is, I think it would be helpful to have a simple example to understand how remake works. Thanks in advance.

remake is expecting a symbolic parameter map, so for this case you need to do…

prob2 = remake(prob; p = [system.value => 5])

Also, depending on what you are trying to accomplish, you may find this of interest: Home · ModelingToolkitInputs.jl. Note the example shown is for a similar system where the integrated constant is an input which can be changed as discrete input.

Oh wow, that really solved it!. Did not know about ’ ModelingToolkitInputs.jl’.

Thank you a lot!

Hi again,

It seems I spoke too soon. While I have been able to verify that this method works correctly, I realized that in large systems, this process can take a lot of time. Is there any way to perform this same process more efficiently? (Perhaps passing a symbolic map creates bottlenecks?).

Best regards,

Using symbolic maps does symbolic operations each time. It’s more for simple and interactive use, if you want to put it in a loop then you’ll need to make sure you do something a bit more optimized. If you instead use the SymbolicIndexingInterface you can compile and cache that specialized remake. This is discussed in the docs:

Hello,

Indeed, after looking at that example I’ve come to the conclusion that using replace() can be more efficient because of not using the symbolic map. However, I’m having a hard time seeing how to use that method in a simple example like the one I mentioned earlier.

I believe the info you need is here (Getting and Setting Parameter Values): Using the SciML Symbolic Indexing Interface · SymbolicIndexingInterface.jl

See the setp function in particular.

This was the solution I was looking for! Extremely efficient!

Thank you both so much.