Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

FMU throws unjustified assert when called with and without y_refs in a sequence (presumably same for ec_idcs and dx_refs) #55

Closed
juguma opened this issue Nov 13, 2023 · 3 comments
Assignees

Comments

@juguma
Copy link

juguma commented Nov 13, 2023

When you call your loaded fmu with different arguments for y_refs in a sequence (first call with y_refs, second without y_refs), an assert is thrown claiming that the lenghts of y_refs and y should be equal.
The first call enters the if-condition (if length(y_refs)>0) and allocates the c.default_y and sets y equal to it. The second does not enter this condition, hence does not re-allocate c.default_y, but then compares y (the old y=c.default_y!?) to the new y_refs' length.
Since y is used again later (e.g. in 274) if length(y)>0, it should be allocated in every call correctly, i.e.

  1. y_refs exists, y exist <- check lengths, assert if unequal
  2. y_refs exist, no y in arguments <- allocate y with length of y_refs
  3. no y_refs, but y <-assert that no y_refs is there, that is basically 1.
  4. no y_refs, no y <- allocate y with length zero, i.e. like 2.

So what about:

if length(y) > 0
    @assert (length(y) == length(y_refs)) "Length of `y` must match length of `y_refs`."
else
    y = zeros(fmi2Real, length(y_refs))
    if length(y_refs)>0
        logInfo(c.fmu, "Automatically allocated `y` for given `y_refs`")
    end 
end

I have to admit, I didn't get the point of having default_y, so my proposal might be nonsense.
Here's a minimal example:

using FMI
using FMI:fmi2ValueReference
using FMIZoo

tSave = 0.0:0.01:8.0
fmu = fmiLoad("SpringPendulumExtForce1D", "Dymola", "2022x"; type=:ME) 
fmiSimulate(fmu,(tStart,tStop)) #<-you need this (or something smarter) to generate a fmu-component before calling the fmu below. That's another bug in my opinion.

outputVRs = UInt32[]
for vr in fmu.modelDescription.outputValueReferences
    push!(outputVRs, vr)
end

#1st call, with y_refs
fmu(;y_refs=outputVRs)

#2nd call, w/o y_refs -> assert
fmu()

#workaround...
length(fmu.components[1].default_y)
fmu.components[1].default_y=zeros(fmi2Real,0)
fmu()
@ThummeTo ThummeTo self-assigned this Nov 16, 2023
@ThummeTo
Copy link
Owner

Will be fixed in the next release

@ThummeTo
Copy link
Owner

Can you please check if this is still valid?

@juguma
Copy link
Author

juguma commented Feb 29, 2024

I tried it in FMICore v0.20.1, it is fixed.
FYI, this example is one of the places where you end up with this "no fmu-component allocated"-Error I complained/we discussed about 😉 when you directly call the fmu after loading it....
I had to make some extra gymnastics (fmiSimulate) to prepare the fmu to create a component (before I could do the fmu-call).
Actually, in v0.20.1. I had to add the line fmu.executionConfig.freeInstance = false before the simulation such that the component is kept (which probably was the default in earlier versions).

@juguma juguma closed this as completed Feb 29, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants