Composing functions in Modeling Toolkit

Hello,
I’m exploring the ModelingToolkit environment and I’ve encountered a question when composing systems. When I define a complete model using a function, it works without any issues. However, when I split the model into two submodels, I get the following error:

"MethodError: no method matching -(::SymbolicUtils.BasicSymbolic{Real}, ::ModelingToolkit.ODESystem)

The function - exists, but no method is defined for this combination of argument types."

I’m attaching both versions of the code in case you can help me identify the error causing this behavior.

Working code:

function Sistema(data, time; name)
    @named src = Interpolation(LinearInterpolation, data, time)
    @named clk = ContinuousClock()
	@named transfer = TransferFunction(b=[1 2], a=[1 3 2])
    eqs = [connect(clk.output,src.input)
		  connect(src.output,transfer.input)]
 
    ODESystem(eqs, t,[], []; name, systems = [src, clk,transfer])
end

@named system1 = Sistema(1,2,3,4,5,6,7,8,9,10], [0,1,2,3,4,5,6,7,8,9]))

sys1 = structural_simplify(system1)

prob1 = ODEProblem(sys1, [], (0,9))
sol1 = solve(prob1)
plot(sol1)

Not working code:

function SistemaImplementar(; name)
	@named input = RealInput()
    @named transfer = TransferFunction(b = [1, 2], a = [1, 3, 2])

    
    # Create an input variable that will be exposed
    eqs = [

        transfer.input ~ input.u  # Expose input
    ]
    
    # Add input to the list of inputs for this system
    ODESystem(eqs, t,[], []; name, systems = [transfer,input])
end

function SistemaCompleto(data, time; name)
    @named src = Interpolation(LinearInterpolation, data, time)
    @named clk = ContinuousClock()
	@named sistemaexterno = SistemaImplementar()
	
    eqs = [connect(clk.output,src.input)
		  connect(src.output,sistemaexterno.input)]
 
    ODESystem(eqs, t; name, systems = [src, clk,sistemaexterno])
end

@named systemaprueba = SistemaCompleto(1,2,3,4,5,6,7,8,9,10], [0,1,2,3,4,5,6,7,8,9]))

sys2bis = structural_simplify(systemaprueba)

Should be either of

connect(transfer.input, input)
transfer.input.u ~ input.u 

What a simple mistake!
Thank you very much <3

I have made the same mistake several times, so I’m an expert at detecting them :wink: The key clue is that you try to perform an arithmetic operation (-) on ::ODESystem, this is because input is a connector, and thus an ODESystem, while input.u is the inner variable on which you can call -.

And would it be possible to mix elements defined using @mtkmodel and elements defined using functions? That is, for example, by defining the first function in my code as an @mtkmodel environment."

Yes, that should be no problem.