Modia.jl icon indicating copy to clipboard operation
Modia.jl copied to clipboard

MethodError when simulating coupled rotational system

Open crlaugh opened this issue 6 years ago • 4 comments

I was trying to construct an example of a rotational system today, and ran into some problems when coupling two inertias to either side of a spring damper. When I try to simulate the final model, I get a method error: MethodError: no method matching -(::Float64, ::Array{Float64,0}). I constructed the same model in Dymola and ran it without problems. Any thoughts on how to address this problem (should my model be reformulated somehow? Is this functionality not expected to work yet in Modia?) would be much appreciated.

Many of these models are similar to those in Modia.Rotational, but I had redefine them to allow the compiler to select phi_rel as a state in PartialCompliant2.

using Modia, ModiaMath
using Modia.Blocks
using Modia.Rotational

@model Pulse begin
    height = Parameter(1.0, info="Height of pulse")
    offset = Parameter(0.0, info="Offset of output signal")
    startTime = Parameter(0.0, info="Output y = offset of time < startTime")
    duration = Parameter(1.0, info="Duration of pulse")
    y = Variable(info="Output signal")
    @equations begin
        y = (time < startTime) ? 0.0 : (time < (startTime + duration)) ? height : 0.0
    end
end;

@model AngleSensor begin
    phi=Modia.Rotational.Angle()
    flange=Flange()
    @equations begin
        0=flange.tau
        phi=flange.phi
    end
end;

@model PartialCompliant2 begin
    phi_rel = Modia.Rotational.Angle(start=0.0)
    tau = Modia.Rotational.TorqueVar()
    flange_a = Flange(info = "Left flange of shaft")
    flange_b = Flange(info = "Right flange of shaft")
    @equations begin 
        phi_rel = flange_b.phi - flange_a.phi
        flange_b.tau = tau
        flange_a.tau = -tau
    end
end; 

@model SpringDamper2 begin
    c = Parameter(min = 0, start = 1.0e5, info = "Spring constant", T = U"N*m/rad")
    d = Parameter(info = "Damping constant", T = U"N*m*s/rad")
    phi_rel0 = Parameter(0.0, start = 0.0, info = "Unstretched spring angle", T = U"rad")
    w_rel = Variable(start=0.0)
    @extends PartialCompliant2()
    @inherits tau, phi_rel
    @equations begin 
        w_rel = der(phi_rel)
        tau = c * (phi_rel - phi_rel0) + d * w_rel
    end
end; 

@model SysTest1 begin
    pulse=Pulse(startTime=1)
    torque=Torque()
    inertia1=Inertia(J=0.1)
    springDamper=SpringDamper2(c=10, d=0.1)
    inertia2=Inertia(J=10)
    angleSensor=AngleSensor()
    @equations begin
        connect(pulse.y, torque.tau)
        connect(torque.flange, inertia1.flange_a)
        connect(inertia1.flange_b, springDamper.flange_a)
        connect(springDamper.flange_b, inertia2.flange_a)
        connect(inertia2.flange_b, angleSensor.flange)
    end    
end;

result=simulate(SysTest1, 3)

Simulating model: SysTest1
Number of equations: 29
Number of variables: 33
Number of continuous states: 5
Number of non states: 1
MethodError: no method matching -(::Float64, ::Array{Float64,0})
Closest candidates are:
  -(::Float64, !Matched::Float64) at float.jl:397
  -(::Float64) at float.jl:387
  -(!Matched::PyCall.PyObject, ::Any) at C:\Users\laughman\.julia\packages\PyCall\0jMpb\src\pyoperators.jl:14
  ...

Stacktrace:
 [1] top-level scope at none:0
 [2] eval at .\boot.jl:319 [inlined]
 [3] eval at C:\Users\laughman\.julia\packages\Modia\kJUT1\src\language\Execution.jl:10 [inlined]
 [4] macro expansion at .\show.jl:555 [inlined]
 [5] #prepare_ida#5(::Bool, ::Bool, ::Function, ::Modia.Instantiation.Instance, ::Array{Symbol,1}, ::Dict{Symbol,Any}) at C:\Users\laughman\.julia\packages\Modia\kJUT1\src\language\Execution.jl:441
 [6] (::getfield(Modia.Execution, Symbol("#kw##prepare_ida")))(::NamedTuple{(:store_eliminated, :need_eliminated_f),Tuple{Bool,Bool}}, ::typeof(Modia.Execution.prepare_ida), ::Modia.Instantiation.Instance, ::Array{Symbol,1}, ::Dict{Symbol,Any}) at .\none:0
 [7] #simulate_ida#12(::Bool, ::Float64, ::Float64, ::Bool, ::Function, ::Modia.Instantiation.Instance, ::Array{Float64,1}, ::Nothing) at C:\Users\laughman\.julia\packages\Modia\kJUT1\src\language\Execution.jl:591
 [8] (::getfield(Modia.Execution, Symbol("#kw##simulate_ida")))(::NamedTuple{(:log,),Tuple{Bool}}, ::typeof(Modia.Execution.simulate_ida), ::Modia.Instantiation.Instance, ::Array{Float64,1}, ::Nothing) at .\none:0
 [9] #simulate_ida#11 at C:\Users\laughman\.julia\packages\Modia\kJUT1\src\language\Execution.jl:574 [inlined]
 [10] #simulate_ida at .\none:0 [inlined]
 [11] #simulateModelWithOptions#7(::Base.Iterators.Pairs{Union{},Union{},Tuple{},NamedTuple{(),Tuple{}}}, ::Function, ::Modia.Instantiation.Model, ::StepRangeLen{Float64,Base.TwicePrecision{Float64},Base.TwicePrecision{Float64}}) at C:\Users\laughman\.julia\packages\Modia\kJUT1\src\symbolic\ModelElaboration.jl:359
 [12] #simulate#9 at .\none:0 [inlined]
 [13] simulate(::Modia.Instantiation.Model, ::Int64) at C:\Users\laughman\.julia\packages\Modia\kJUT1\src\symbolic\ModelElaboration.jl:424
 [14] top-level scope at In[7]:1

crlaugh avatar Oct 16 '18 21:10 crlaugh

I recently discovered that there is a regression with regards to removeSingularities for certain models. Turning off removeSingularities enables simulating the model: result=simulate(SysTest1, 3, removeSingularities=false)

HildingElmqvist avatar Oct 17 '18 00:10 HildingElmqvist

Thanks for taking a look at this. The good news is that the previous error is gone. The bad news is that it has been replaced by a different error. Here's the error that I am now getting:

removeSingularities = false

Simulating model: SysTest1
Number of equations: 33
Number of variables: 37
Number of continuous states: 5
AssertionError: state_size == residual_size

Stacktrace:
 [1] #prepare_ida#5(::Bool, ::Bool, ::Function, ::Modia.Instantiation.Instance, ::Array{Symbol,1}, ::Dict{Symbol,Any}) at C:\Users\laughman\.julia\packages\Modia\kJUT1\src\language\Execution.jl:456
 [2] (::getfield(Modia.Execution, Symbol("#kw##prepare_ida")))(::NamedTuple{(:store_eliminated, :need_eliminated_f),Tuple{Bool,Bool}}, ::typeof(Modia.Execution.prepare_ida), ::Modia.Instantiation.Instance, ::Array{Symbol,1}, ::Dict{Symbol,Any}) at .\none:0
 [3] #simulate_ida#12(::Bool, ::Float64, ::Float64, ::Bool, ::Function, ::Modia.Instantiation.Instance, ::Array{Float64,1}, ::Nothing) at C:\Users\laughman\.julia\packages\Modia\kJUT1\src\language\Execution.jl:591
 [4] (::getfield(Modia.Execution, Symbol("#kw##simulate_ida")))(::NamedTuple{(:log,),Tuple{Bool}}, ::typeof(Modia.Execution.simulate_ida), ::Modia.Instantiation.Instance, ::Array{Float64,1}, ::Nothing) at .\none:0
 [5] #simulate_ida#11 at C:\Users\laughman\.julia\packages\Modia\kJUT1\src\language\Execution.jl:574 [inlined]
 [6] #simulate_ida at .\none:0 [inlined]
 [7] #simulateModelWithOptions#7(::Base.Iterators.Pairs{Symbol,Bool,Tuple{Symbol},NamedTuple{(:removeSingularities,),Tuple{Bool}}}, ::Function, ::Modia.Instantiation.Model, ::StepRangeLen{Float64,Base.TwicePrecision{Float64},Base.TwicePrecision{Float64}}) at C:\Users\laughman\.julia\packages\Modia\kJUT1\src\symbolic\ModelElaboration.jl:359
 [8] #simulate#9 at .\none:0 [inlined]
 [9] (::getfield(Modia.ModelElaboration, Symbol("#kw##simulate")))(::NamedTuple{(:removeSingularities,),Tuple{Bool}}, ::typeof(simulate), ::Modia.Instantiation.Model, ::Int64) at .\none:0
 [10] top-level scope at In[8]:1

Thoughts?

crlaugh avatar Oct 17 '18 20:10 crlaugh

Sorry. I forgot. You have to declare that phi_rel (which appears differentiated) is not a state: @model PartialCompliant2 begin phi_rel = Modia.Rotational.Angle(start=0.0,state=false)

There should be a better error message. We can leave the issue open regarding both aspects.

HildingElmqvist avatar Oct 17 '18 21:10 HildingElmqvist

Thanks! It works great now. I'll leave this issue open as suggested so that we can improve the diagnostics and figure out why removeSingularities=false enables it to work better.

crlaugh avatar Oct 17 '18 22:10 crlaugh