5
$\begingroup$

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


I am having some difficulties to provide vector inputs for a Modelica model using Mathematica. To demonstrate this I am using a simple block that will pass a real vector of length 3 unchenaged to its output of the same dimension:

model = ImportString[
    "block VectorPassThrough
         input Real[3] u;
         output Real[3] y;
       equation
         y = u;
     end VectorPassThrough;"
   , 
   "mo"
];

model["ModelicaDisplay"]

Modelica Code

Now I would like to simulate this simple block and provide a vector input:

sim = SystemModelSimulate[ model, {"y"}, {0, 1}, Association[
   "Inputs" -> {
     "u" -> Function[ t, {1., 2., 3.}]
     }
   ]
]

Will throw the error SystemModelSimulate::val :

The variables {u} were not recognized, or the types do not match the model.

Using a time Series also will not help:

sim = SystemModelSimulate[ model, {"y"}, {0, 1}, 
    Association[    
        "Inputs" -> {
            "u" -> TimeSeries[ { {1, 2, 3}, {1, 2, 3} }, { {0, 1} }]
        }
    ] 
]

In what format shall vector (and matrix) inputs be given for SystemModelSimulate?

$\endgroup$
1
  • $\begingroup$ @MalteLenz Still hoping for a nice solution ... ;-) $\endgroup$ – gwr Dec 30 '20 at 16:13
6
$\begingroup$

I have received answer from Technical Support at WRI:

At present we cannot feed vectors as lists; instead we have to use array variables such as u[1], u[2] and so on.

[...]

The developers are currently working on implementing the feature for feeding vectors as lists.

Since arrays/vectors can also be indexed using enumerations (e.g. "myEnumeration.first", "myEnumeration.second", ... ), having to address individual arguments in this way will be very cumbersome. Expanding the functionality of SystemModelSimulate would be very welcome.

Update

... but the most important reason for implementing vector input is, that in Modelica array dimensions can be left unspecified (e.g. mat[:,:], vec[:]). We cannot simply assign a value to vec[1] because the Modelica compiler needs to be able to determine the dimensions form the dimensions of the input given. It would be really cumbersome, having to work around this using additional components like the Multiplex.

$\endgroup$
1
$\begingroup$

Preliminary Solution for Vectors

Until we get what we deserve, here at least is a solution for vector input and output, which may be expanded:

vecOutput::usage = "vecOutput[\"var\", dim ] returns Sequence[\"var[1]\", \"var[2]\", ... , \"var[dim]\"]";
vecOutput[ var_String, dim_Integer ] := Sequence @@ Array[ var <> "[" <> ToString[#] <> "]" &, dim ]

vecInput::usage = "vecInput[ \"var\", { func1, func2, ... } ] returns Sequence[\"var[1]\" -> func1, \"var[2]\" -> func2, ...]"; 
vecInput[ var_String, funcList : { __Function } ] := Module[
    {
        varList = Array[ var <> "[" <> ToString[#] <> "]" &, Length @ funcList ]
    }
    ,
    Sequence @@ Thread[ varList ->  funcList ]
]

vecInput[ var_String, l_List ] := Module[
  { 
      varList = Array[ var <> "[" <> ToString[#] <> "]" &, Length @ l ],
      funcList = Map[ Function[t, #] & , l ]
  }
  ,
  Sequence @@ Thread[ varList ->  funcList ]
]

vecInput[ var_String, td_TemporalData ] /; td[ "PathCount" ] != 1 := With[ 
    { dim = td[ "PathCount"] }
    ,
    Module[
        {
            varList = Array[ var <> "[" <> ToString[#] <> "]" &, dim ],
            funcList = Array[ td[ "PathFunction", # ] &, dim ]
        }
        ,
        Sequence @@ Thread[ varList ->  funcList ]
    ]
]

vecInput[ var_String, ts_TemporalData ] /; ts[ "PathCount"] == 1 := With[ 
    { dim = ts[ "ValueDimensions"] }
    ,
    Module[
        {
            times = ts[ "Times" ],
            values = ts[ "Values" ]
        }
        ,
        vecInput[ var, TemporalData[ Transpose @ values, List @ times ] ]
    ]
]

We can now do the following:

vecInput[ "u", { 1, 2, 3} ] (* assign constant functions *)

to obtain

Sequence["u[1]" -> Function[t, 1], "u[2]" -> Function[t, 2]]

For the simple model given in the OP we can then do:

sim = SystemModelSimulate[model, { vecOutput[ "y", 3 ] }, {0, 1},
    Association[
        "Inputs" -> { 
             vecInput[ "u", TimeSeries[ { {1, 2, 3}, {1, 2, 3} }, { {0, 1} } ]  ] 
        }
    ]
] 

SystemModelSimulationData[ ... ]

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.