Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Array of components #2674

Closed
B-LIE opened this issue Apr 27, 2024 · 12 comments
Closed

Array of components #2674

B-LIE opened this issue Apr 27, 2024 · 12 comments
Assignees
Labels
question Further information is requested

Comments

@B-LIE
Copy link

B-LIE commented Apr 27, 2024

Is there an example of how to use arrays of components in the documentation❓

image

From a presentation, I've seen the the syntax:

@components begin
    resistor[1:n] = Resistor()
end

I don't know if this is a standard notation or not. I've tried to use it, but have problems when I add equations where the instances have fields, such...

@equations begin
    resistor[1].R ~ 3 
end

would not work.

However,

@components begin
    resistor_1 = Resistor()
end
#
@equations begin
    resistor_1.R ~ 3
end

would work.

@B-LIE B-LIE added the question Further information is requested label Apr 27, 2024
@ChrisRackauckas
Copy link
Member

@ven-k is the array form documented?

@ven-k
Copy link
Member

ven-k commented Apr 29, 2024

Yes it's the examples here: https://docs.sciml.ai/ModelingToolkit/stable/basics/MTKModel_Connector/#What-can-an-MTK-Model-definition-have?

The relevant bits (from ModelC example):

@mtkmodel ModelC begin
    @structural_parameters begin
        N = 2
    end
:
    @components begin
        model_a = ModelA(; k_array)
        model_array_a = [ModelA(; k = i) for i in 1:N]
        model_array_b = for i in 1:N
            k = i^2
            ModelA(; k)
        end
    end
:
end

For @named model_c = ModelC() ,the subcomponents can be then accessed as model_c.model_array_a_1, model_c.model_array_a_2 and so on.

@B-LIE
Copy link
Author

B-LIE commented Apr 29, 2024 via email

@B-LIE
Copy link
Author

B-LIE commented Apr 29, 2024 via email

@B-LIE
Copy link
Author

B-LIE commented Apr 29, 2024

(My color coding disappeared when transferring my e-mail to the GitHub system...)

@cstjean
Copy link
Contributor

cstjean commented Oct 25, 2024

For @named model_c = ModelC() ,the subcomponents can be then accessed as model_c.model_array_a_1, model_c.model_array_a_2 and so on.

How can I iterate over that array of components? Eg. I can write

connect(model_c.model_array_a_1, other_component)
connect(model_c.model_array_a_2, other_component)
connect(model_c.model_array_a_3, other_component)
connect(model_c.model_array_a_4, other_component)

but that's terrible. Can I somehow write a for loop?

Context

@ChrisRackauckas
Copy link
Member

[connect(model_c.model_array_a[i], other_component) for i in 1:n]

@cstjean
Copy link
Contributor

cstjean commented Oct 29, 2024

This does not work for me. MWE:

using ModelingToolkit    # v9.48.0
using ModelingToolkit: t_nounits as t

@mtkmodel MyComponent begin
   @variables begin
      x(t)
   end
   @equations begin
      x ~ 10
   end
end

@mtkmodel Moo begin
   @components begin
      some_comp = MyComponent()
      comp_array = [MyComponent() for i in 1:4]
   end
end

@named moo = Moo()

moo.some_comp      # works
moo.comp_array_1   # works
moo.comp_array     # ArgumentError: System moo: variable comp_array does not exist

This is the same problem highlighted in @B-LIE's comment above (#2674 (comment))

EDIT: first version accidentally used @connector, but the result is the same.

@ven-k
Copy link
Member

ven-k commented Oct 29, 2024

The component-array is splat before adding them as subsystems. So moo.comp_array won't work. They should be queried along with the number as moo.comp_array_i.

Note that getproperty can be used to query the subsystems via a loop as [getproperty(moo, Symbol(:comp_array_, i)) for i in 1:4]

@cstjean
Copy link
Contributor

cstjean commented Oct 29, 2024

Sounds good! Is there any reason why we couldn't have comp_array = [comp_array_1, comp_array_2, ...] automatically defined by the macro? Then the above would just work, instead of having to go through getproperty and Symbol.

@ven-k
Copy link
Member

ven-k commented Oct 29, 2024

ODESystem constructor doesn't accept Vector{ODESystem} (for subsystem) as input.

Also, [getproperty(moo, Symbol(:comp_array_, i)) for i in 1:4] is meant for accessing the subsystems outside the macro.
The connect statement above, is placed inside macro and macro handles that.

 @mtkmodel Moo begin
          @components begin
             some_comp = MyComponent()
             comp_array = [MyComponent() for i in 1:4]
          end
           @equations begin
               [connect(comp_array[i], some_comp) for i in 1:4]
           end
   end

comp_array = [getproperty(moo, Symbol(:comp_array_, i)) for i in 1:4]

Maybe there can be a helper function to access it. But I fear it will have many non-obvious failing edge cases. If I can come up with a reliable one, I'll add.

@cstjean
Copy link
Contributor

cstjean commented Oct 29, 2024

ODESystem constructor doesn't accept Vector{ODESystem} (for subsystem) as input.

That looks like a complicated change indeed.

For context, I wanted to have a component with N connectors. In that case, the connect equation is outside of the @mtkmodel, and it does not work:

using ModelingToolkit
using ModelingToolkit: t_nounits as t

@mtkmodel MyConnector begin
    @variables begin
        x(t)
    end
end

@mtkmodel MilkTank begin
    @components begin
        connections = [MyConnector() for i in 1:4]
    end
end

@mtkmodel Farm begin
    @components begin
        m1 = MilkTank()
	m2 = MilkTank()
    end
    @equations begin
        # (sorry for the meaningless example)
        [connect(co1, co2) for (co1, co2) in zip(m1.connections, m2.connections)]...
    end
end

@named farm = Farm()  # System m1: variable connections does not exist

But on further investigation, stream connectors look like a better solution to my problem, so I don't need multiple connectors. Thank you for the input!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
question Further information is requested
Projects
None yet
Development

No branches or pull requests

4 participants