Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Modelica - iterator with exception?

Tags:

modelica

Slightly generalised example:

How do I make a for loop with exceptions when I define model equations?

The following works:

  model Test
     Real[9] q;
  equation
     q[2] = 1.2;
     q[4] = 1.4; 
     for i in {1,3,5,6,7,8,9} loop
        q[i] = 0;
     end for;
  end Test;

But I would rather like to write something like:

  model Test
     Real[9] q;
  equation
     q[2] = 1.2;
     q[4] = 1.4;
     for i in 1:9 and not in {2,4} loop
        q[i] = 0;
     end for;
  end Test;

Is this possible?

like image 927
janpeter Avatar asked Jan 24 '23 18:01

janpeter


2 Answers

This should be possible, as long as you make sure to have an equation for every unknown.

Probably not the perfect solution, but actually pretty readable:

model LoopException
  Real[9] q;
equation 
  q[2] = 1.2;
  q[4] = 1.4; 
  for i in 1:9 loop
    if Modelica.Math.Vectors.find(i, {2, 4}) == 0 then
      q[i] = 0;
    end if;
  end for;
end LoopException;

As an alternative, you could also try to write an "Array Constructor with Iterators" (Modelica Language Spec. Sec. 10.4.1), but that probably gets a bit messy...

like image 127
Markus A. Avatar answered Feb 24 '23 20:02

Markus A.


With 2 helper functions you can easily emulate what you want:

model Test
 Real[9] q;
equation
 q[2] = 1.2;
 q[4] = 1.4;
 for i in allExcept(1:9, {2,4}) loop
    q[i] = 0;
 end for;
end Test;

Here are the functions you need for that:

function contains
"Check if vector v contains any element with value e"
  input Integer vec[:];
  input Integer e;
  output Boolean result;
algorithm 
  result := false;
  for v in vec loop
    if v == e then
      result := true;
      break;
    end if;
  end for;
end contains;

function allExcept
  "Return all elements of vector v which are not part of vector ex"
  input Integer all[:];
  input Integer ex[:];
  output Integer vals[size(all, 1) - size(ex, 1)];
protected 
  Integer i=1;
algorithm 
  for v in all loop
    if not contains(ex, v) then
      vals[i] := v;
      i := i + 1;
    end if;
  end for;
end allExcept;

Note that Modelica tools usually need to know the size of vectors during translation, especially here when you generate equations. Hence, the following line is required:

output Integer vals[size(all, 1) - size(ex, 1)];

It will fail when all or ex contain duplicate elements. Therefore the model will not translate, if you try something like

for i in allExcept(1:3, {2, 2}) loop
like image 26
marco Avatar answered Feb 24 '23 21:02

marco