Jack
Jack

Reputation: 1232

How could I use 'fmi2GetDirectionalDerivative'?

I am trying to get the model Jacobian matrix from FMU, according to the following literature, I could use fmi2GetDirectionalDerivative to do this, but I am not sure what I need to do exactly.

My question is:

  1. Could I call this function in Dymola or MATLAB?
  2. A screenshot or an example would be very helpful.

https://ep.liu.se/ecp/132/091/ecp17132831.pdf

enter image description here

Upvotes: 2

Views: 682

Answers (2)

Dag B
Dag B

Reputation: 759

There was a paper from Mitsubishi Electric at the recent NAM Modelica Conference 2020 that might be related.

Upvotes: 0

I am not familiar with calling DLL functions in MATLAB but this is an example in Python. FMPy (https://github.com/CATIA-Systems/FMPy) has these wrappers for running FMUs in python.

I've tested this for a simple model I've written here(How to access model jacobian from FMU or Dymola without analytical jacobian). In this case, knowns are value references of either states or inputs, unknowns are value references of derivatives or outputs.

I have had success extracting the Jacobian when exported through Dymola as Model Exchange FMU but not Co-Simulation FMU.

def get_jacobian(fmu, vr_knowns, vr_unknowns):
    """
    populates jacobian from list of knowns and unknowns
    can be only called after the current sim time and inputs are set
    """
    jacobian = []
    try:
        for vr_known in vr_knowns:
            for vr_unknown in vr_unknowns:
                jacobian.extend(
                    fmu.getDirectionalDerivative(
                        vUnknown_ref=[vr_unknown],
                        vKnown_ref=[vr_known],
                        dvKnown=[1.0]
                    ))
        print_status(f'Jacobian Elements: {jacobian}')
    except Exception as e:
        print("[ERROR] cannot compute jacobian at current timestep")
        print(f"[ERROR] {e}")

I use this code snippet to collect the value references for states and derivatives using FMPy:

# get FMU model description object
model_description = fmpy.read_model_description(
    os.path.join(fmu_path, fmu_filename)
)

# collect the value references
vrs = {}
for variable in model_description.modelVariables:
    vrs[variable.name] = variable.valueReference

# collect list of states and derivatives
states = []
derivatives = []
for derivative in model_description.derivatives:
    derivatives.append(derivative.variable.name)
    states.append(re.findall('^der\((.*)\)$',derivative.variable.name)[0])

# collect the value references for states and derivatives
vr_states = [vrs[x] for x in states]
vr_derivatives = [vrs[x] for x in derivatives]

Upvotes: 4

Related Questions