Message Boards Message Boards

1
|
8824 Views
|
4 Replies
|
2 Total Likes
View groups...
Share
Share this post:

How to use flexible array sizes inside expandable connectors?

A support case with the identification [CASE:4272754] was created.


(cross-posted on StackOverflow)

Motivation

Building more complex components (e.g. subsystems in a larger model) inevitably leads to a growing number of connectors. To make this more manageable we may use records or arrays. Records as part a connector as far as I know have the disadvantage, that we may not easily access a single element within the record when we are making a connection. An array (e.g. a flattened list of output for a subsystem) on the other hand allows to connect individual parts (e.g. a subrange or an individual element inside the array) but does not allow to assign different units to elements inside the same array. Also but flattened lists quickly become unwieldly.

The above considerations seem to be the reason for the development of the expandable connector class, which can be used to model DataBus-like structures (Note: Why are Dymola pop-up windows referenced in the Wolfram System Modeler documentation? ).

A few "mysteries" remain though which I would like to inquire about.

Adding variables without predefinition

In the following simple example we simply define an empty DataBus structure and then add elements using connect():

expandable connector DataBus
end DataBus;

model SimpleModel
    DataBus dataBus "An empty bus";
    Modelica.Blocks.Interfaces.RealOutput x[ nElements ]( unit = "widgets" ) "A vector of real elements";
    parameter Integer nElements = 2 "Length of x vector";
equation
    x = ones( 2 ); // assign dummy results to x
    connect( x, dataBus.x );
end SimpleModel;

Entering this model in the Model Center and then Simulating it reveals, that dataBus.x has the correct dimension, but does not have the appropriate units (and other attributes). What to do?

Adding variables with predefinition (first attempt)

In order to make use of units and other attributes (e.g. maybe using predefined types) we will now declare a variable inside the expandable connector. Since we do not know the size of the vector x in advance (its size is a parameter), we will try to define x inside the DataBus in a flexible fashion:

    expandable connector DataBus
        Real x[:] ( unit = "widgets" );
    end DataBus;

    model SimpleModel
        DataBus dataBus "A predefined bus";
        Modelica.Blocks.Interfaces.RealOutput x[ nElements ]( unit = "widgets" ) "A vector of real elements";
        parameter Integer nElements = 2 "Length of x vector";
    equation
        x = ones( 2 );
        connect( x, dataBus.x );
    end SimpleModel;

Unfortunately, this model will give errors upon validation:

Error message

I do not understand, why this use of [:] is throwing an error - a similar example is given by Peter Fritzson in chapter 5.9.5 of "Principles of Object-Oriented Modeling and Simulation with Modelica 3.3" - also see the reference to the Modelica Specification in the update below. (Note: As I am told, this code runs without problems in Dymola.)

So, we maybe need to somehow pass the parameter nElements (defining the array size) to the expandable connector?

Adding variables with predefinition (second attempt)

To make the size of the vector x known to the expandable connector DataBus, we make the bus a sub-component of the model and pass on the parameter nElements via inner and outer constructs:

model SimpleModel
  DataBus dataBus "A predefined bus";
  Modelica.Blocks.Interfaces.RealOutput x[2](unit = "widgets") "A vector of real elements";
  inner parameter Integer nElements = 2 "Length of x vector";

  expandable connector DataBus
    Real x[ nElements ];
    outer parameter Integer nElements;
  end DataBus;

equation
  x = ones(2);
  connect(x, dataBus.x);
end SimpleModel;

But again, the model will not validate without errors:

error message

Unfortunately, neither adding annotation( Evaluate = true ) or change the parameter to a constant will help.

How then can predefined variables inside an expandable connector be created while still allowing structural variability (e.g. have parametric array sizes)?

Update:

In the Modelica Specification (Version 3.2 Revision 2) we find in Section 9.1.3 Expandable Connectors:

Before generating connection equations non-parameter scalar variables and non-parameter array lements declared in expandable connectors are marked as only being potentially present. A non-parameter array element may be declared with array dimensions “:” indicating that the size is unknown. This applies to both variables of simple types, and variables of structured types. (Emphasis is my own)

4 Replies

Ok, thanks for the clarification. To wrap this thread up, I would suggest the following changes in an upcoming (hopefully the next) release of System Modeler:

  1. Fully support flexible array sizes in expandable connectors in accordance with Modelica Sepcification - and at least some remarks in the documentation until that is implemented.
  2. Adapt the documentation to show Wolfram System Modeler examples and screenshots: It is rather confusing to find screenshots from Dymola in the documentation for System Modeler that do not apply to how things are done in WSM.
Posted 5 years ago

Yes, flexible array sizes in expandable connectors is not supported.

POSTED BY: Carl Jönsson

Thank you, Carl. That may indeed work as I am mainly needing the flexible sizes for outputs so that the dimensions are known when placing/initiating the submodel. (Providing a flexible connector for inputs where the size information may come later is another question - I had probably thought too generally here ... ;-) )

Your answer suggests, that the use of flexible array sizes in an expandable connector is currently not supported by WSM (even though it should be according to specifications)?

Posted 5 years ago

You could propagate the size the regular way:

model SimpleModel
  DataBus dataBus(nElements = nElements) "A predefined bus";
  Modelica.Blocks.Interfaces.RealOutput x[2](unit = "widgets") "A vector of real elements";
  parameter Integer nElements = 2 "Length of x vector";

  expandable connector DataBus
    Real x[ nElements ];
    parameter Integer nElements;
  end DataBus;

equation
  x = ones(2);
  connect(x, dataBus.x);
end SimpleModel;
POSTED BY: Carl Jönsson
Reply to this discussion
Community posts can be styled and formatted using the Markdown syntax.
Reply Preview
Attachments
Remove
or Discard

Group Abstract Group Abstract