modelon-community / fmi-library

C library for importing FMUs
Other
116 stars 34 forks source link

fmi2_import_get_variable_has_start(fmi2_import_variable_t*) API is returning zero (0) for Outputs and Global Block Outputs #117

Closed Yaismin closed 7 months ago

Yaismin commented 8 months ago

Hi Team,

I have a requirement of passing start value for Outputs and Global Block Outputs variables in FMI2.0. As part of this , I am trying to utilize fmi2_import_get_variable_has_start(fmi2_import_variable_t*) API to check if the variable contains start. But unfortunately, above mentioned API is returning zero (0), so I could not proceed further for retrieving the start value.

My question is, is it expected behavior for fmi2_import_get_variable_has_start(fmi2_import_variable_t*) API not to read start value for Outputs and Global Block Outputs variables. Though I am getting 1 while trying to read from Parameters and Inputs variable.

Many Thanks, Yaismin

PeterMeisrimelModelon commented 8 months ago

Hi Yaismin,

can you provide us with a minimal reproducer? I.e., your call sequence and the relevant variables in your modelDescription.xml?

/Peter

Yaismin commented 8 months ago

Hi Peter,

Highlighted Local casualty (name="der(v)" and name="der(h)" ) from following ModelDescription.xml, I was trying to read start value , but its returning zero(0). Bouncingball.fmu is modified.

<ModelVariables>
    <ScalarVariable name="time" valueReference="0" causality="independent" variability="continuous" description="Simulation time">
      <Real/>
    </ScalarVariable>
    <ScalarVariable name="h" valueReference="1" causality="output" variability="continuous" initial="exact" description="Position of the ball">
      <Real start="1" declaredType="Position"/>
    </ScalarVariable>
    <ScalarVariable name="der(h)" valueReference="2" causality="local" variability="continuous" initial="calculated" description="Derivative of h">
      <Real start="0.5" derivative="1" declaredType="Velocity"/>
    </ScalarVariable>
    <ScalarVariable name="v" valueReference="3" causality="output" variability="continuous" initial="exact" description="Velocity of the ball">
      <Real start="0" reinit="true" declaredType="Velocity"/>
    </ScalarVariable>
    <ScalarVariable name="der(v)" valueReference="4" causality="local" variability="continuous" initial="calculated" description="Derivative of v">
      <Real start="0.1" derivative="3" declaredType="Acceleration"/>
    </ScalarVariable>
    <ScalarVariable name="g" valueReference="5" causality="parameter" variability="fixed" initial="exact" description="Gravity acting on the ball">
      <Real start="-9.81" derivative="2" declaredType="Acceleration"/>
    </ScalarVariable>
    <ScalarVariable name="e" valueReference="6" causality="parameter" variability="tunable" initial="exact" description="Coefficient of restitution">
      <Real start="0.7" min="0.5" max="1"/>
    </ScalarVariable>
    <ScalarVariable name="v_min" valueReference="7" variability="constant" description="Velocity below which the ball stops bouncing">
      <Real start="0.1" declaredType="Velocity"/>
    </ScalarVariable>
  </ModelVariables>

call sequence: fmi2_import_variable_list_t varList = fmi2_import_get_variable_list(fmu, 0); for(int i=0;i<n;i++) { fmi2_import_variable_t var = fmi2_import_get_variable(varList, i); IsStartValue=fmi2_import_get_variable_has_start(var); //returning zero if(IsStartValue==1 && VariableType=="real64") //check fails { fmi2_import_real_variable_t *rv = fmi2_import_get_variable_as_real(var); .. } }

Thanks, Yaismin

PeterMeisrimelModelon commented 8 months ago

With regards to your call sequence; this is not how you check variable types. The call sequence should look like this:

    fmi2_import_variable_list_t* varList = fmi2_import_get_variable_list(xml, 0);
    size_t n = fmi2_import_get_variable_list_size(varList);
    for(size_t i = 0; i < n; i++) {
        fmi2_import_variable_t* var = fmi2_import_get_variable(varList, i);
        int hasStartValue = fmi2_import_get_variable_has_start(var);
        int isRealVariable = fmi2_import_get_variable_base_type(var) == fmi2_base_type_real;
        if (hasStartValue && isRealVariable) {
            fmi2_import_real_variable_t *rv = fmi2_import_get_variable_as_real(var);
            // ....
        }
    }

Also be aware of the warnings/errors given during parsing, some of your attribute combinations are not valid. The start attributes for variables with initial = 'calculated' will be ignored.

Yaismin commented 8 months ago

Hi Peter,

Thank you for the support. As you mentioned the combinations are not valid in shared modelDescription.xml, so during parsing it is supposed to throw warning/ error. But while following the call sequence, I di not get any such warning. In that case, do I need to enable warning/error explicitly? Could you please guide on the same.

Thanks Yaismin

PeterMeisrimelModelon commented 7 months ago

Hi Yaismin,

how are you invoking the parsing?

Using e.g.,

    jm_callbacks *cb = jm_get_default_callbacks();
    fmi_import_context_t *ctx = fmi_import_allocate_context(cb);
    fmi2_import_t* xml = fmi2_import_parse_xml(ctx, "path/to/directory/with/unpacked/fmu", NULL);

the default logger will be jm_default_logger, which prints all log messages to stderr.

/Peter

Yaismin commented 7 months ago

Hi Peter,

I am following the similar approach for parsing. I was not aware of jm_default_logger. Thanks for the information.

As all the queries are resolved, I am closing the call.

Thanks Yaismin