- Index
- » Users
- » mkobierski
- » Profile
Posts
Posts
Hello,
In developing a piece of software which interfaces with FMUs created by OpenModelica, I have come across some literature that stipulates an fmiStatus of fmiDiscard should be returned under circumstances where a result was not convergent. According to my research, when this happens, I must reduce the step size and try the step again.
Under what circumstances will an FMU created by omc return an fmiDiscard, and what steps can I take to ensure simulation proceeds correctly?
Thanks in advance.
(OpenModelica v1.9.1(r22929))
Hello all,
For the purpose of exploring OpenModelica's code generation for conditional statements, I have created the short model below. The purpose is to use if-else-end for conditionally evaluated statements in a compiled FMU.
Code:
model IfTest
parameter Real a = 1;
parameter Real b = 2;
parameter Boolean useA = true;
output Real y;
equation
if useA then
y = a;
else
y = b;
end if;
end IfTest;
Upon instantiation, I see the if statement has been flattened, resulting in the same path of execution regardless of the value of useA.
Code:
class IfTest
parameter Real a = 1.0;
parameter Real b = 2.0;
parameter Boolean useA = true;
output Real y;
equation
y = a;
end IfTest;
This isn't ideal, so let's see what happenes if no default value is given for useA.
Code:
parameter Boolean useA;
Instantiated:
Code:
class IfTest
parameter Real a = 1.0;
parameter Real b = 2.0;
parameter Boolean useA;
output Real y;
equation
if useA then
y = a;
else
y = b;
end if;
end IfTest;
Great! The conditional is going to be evaluated differently depending on the value of useA! Having a quick look at the code of IfTest_06inz.c to confirm:
Code:
/*
equation index: 1
type: SIMPLE_ASSIGN
useA = false
*/
void IfTest2_eqFunction_1(DATA *data)
{
const int equationIndexes[2] = {1,1};
$PuseA = 0;
}
/*
equation index: 2
type: SIMPLE_ASSIGN
y = if useA then a else b
*/
void IfTest2_eqFunction_2(DATA *data)
{
const int equationIndexes[2] = {1,2};
$Py = ($PuseA?$Pa:$Pb);
}
Uhoh... the false branch of equation 2 will always be executed for initialization... Ok, what if I set useA to use (fixed=false)?
Code:
parameter Boolean useA(fixed = false);
Instantiated:
Code:
class IfTest
parameter Real a = 1.0;
parameter Real b = 2.0;
parameter Boolean useA(fixed = false);
output Real y;
equation
if useA then
y = a;
else
y = b;
end if;
end IfTest;
Good, the conditional is still there. C:
Code:
/*
equation index: 1
type: SIMPLE_ASSIGN
useA = $_start(useA)
*/
void IfTest_eqFunction_1(DATA *data)
{
const int equationIndexes[2] = {1,1};
$PuseA = $P$ATTRIBUTE$PuseA.start;
}
/*
equation index: 2
type: SIMPLE_ASSIGN
y = if useA then a else b
*/
void IfTest_eqFunction_2(DATA *data)
{
const int equationIndexes[2] = {1,2};
$Py = ($PuseA?$Pa:$Pb);
}
Great, now I can use the conditional by setting the start value before initialization (fmiSetBoolean() would do the trick I believe).
This leads to a three-part question:
1. Why is the conditional flattened when a default parameter is provided, as in case 1 above?
2. Why are parameters zero-initialized (overwriting any fmiSetxxx) in 06inz.c if no default values are provided?
3. Is the use of (fixed=false) here the right solution for the desired behaviour?
Note that I could have used the equation
Code:
y = if useA then a else b;
for this single-line assignment, but want to later extend the concept to more complex conditional blocks in the FMU.
Thank you in advance!
Mike
- Index
- » Users
- » mkobierski
- » Profile