@@ -144,12 +144,16 @@ function MTK.FMIComponent(::Val{Ver}; fmu = nothing, tolerance = 1e-6,
144
144
145
145
push! (params, wrapper, functor)
146
146
push! (states, __mtk_internal_u)
147
- elseif type == :CS && Ver == 2
147
+ elseif type == :CS
148
148
state_value_references = UInt32[value_references[var] for var in diffvars]
149
149
state_and_output_value_references = vcat (
150
150
state_value_references, output_value_references)
151
- _functor = FMI2CSFunctor (state_and_output_value_references,
152
- state_value_references, output_value_references)
151
+ _functor = if Ver == 2
152
+ FMI2CSFunctor (state_and_output_value_references,
153
+ state_value_references, output_value_references)
154
+ else
155
+ FMI3CSFunctor (state_value_references, output_value_references)
156
+ end
153
157
@parameters (functor:: (typeof(_functor) ))(.. )[1 : (length (__mtk_internal_u) + length (__mtk_internal_o))] = _functor
154
158
for (i, x) in enumerate (collect (__mtk_internal_o))
155
159
push! (initialization_eqs,
@@ -168,11 +172,11 @@ function MTK.FMIComponent(::Val{Ver}; fmu = nothing, tolerance = 1e-6,
168
172
if symbolic_type (__mtk_internal_u) != NotSymbolic ()
169
173
cb_modified = (cb_modified... , states = __mtk_internal_u)
170
174
end
171
- initialize_affect = MTK. ImperativeAffect (fmi2CSInitialize !; observed = cb_observed,
175
+ initialize_affect = MTK. ImperativeAffect (fmiCSInitialize !; observed = cb_observed,
172
176
modified = cb_modified, ctx = _functor)
173
177
finalize_affect = MTK. FunctionalAffect (fmiFinalize!, [], [wrapper], [])
174
178
step_affect = MTK. ImperativeAffect (
175
- fmi2CSStep !; observed = cb_observed, modified = cb_modified, ctx = _functor)
179
+ fmiCSStep !; observed = cb_observed, modified = cb_modified, ctx = _functor)
176
180
instance_management_callback = MTK. SymbolicDiscreteCallback (
177
181
communication_step_size, step_affect; initialize = initialize_affect, finalize = finalize_affect
178
182
)
@@ -318,6 +322,16 @@ function get_instance_ME!(wrapper::FMI3InstanceWrapper, states, inputs, params,
318
322
return wrapper. instance
319
323
end
320
324
325
+ function get_instance_CS! (wrapper:: FMI3InstanceWrapper , states, inputs, params, t)
326
+ if wrapper. instance === nothing
327
+ wrapper. instance = FMI. fmi3InstantiateCoSimulation! (
328
+ wrapper. fmu; eventModeUsed = false ):: FMI.FMU3Instance
329
+ get_instance_common! (wrapper, states, inputs, params, t)
330
+ @statuscheck FMI. fmi3ExitInitializationMode (wrapper. instance)
331
+ end
332
+ return wrapper. instance
333
+ end
334
+
321
335
function complete_step! (wrapper:: FMI3InstanceWrapper )
322
336
wrapper. instance === nothing && return
323
337
enterEventMode = Ref (FMI. fmi3False)
440
454
ndims = 1
441
455
end
442
456
443
- function fmi2CSInitialize ! (m, o, ctx:: FMI2CSFunctor , integrator)
457
+ function fmiCSInitialize ! (m, o, ctx:: FMI2CSFunctor , integrator)
444
458
states = isdefined (m, :states ) ? m. states : ()
445
459
inputs = o. inputs
446
460
params = o. params
@@ -449,6 +463,7 @@ function fmi2CSInitialize!(m, o, ctx::FMI2CSFunctor, integrator)
449
463
if wrapper. instance != = nothing
450
464
reset_instance! (wrapper)
451
465
end
466
+
452
467
instance = get_instance_common! (wrapper, states, inputs, params, t)
453
468
@statuscheck FMI. fmi2ExitInitializationMode (instance)
454
469
if isdefined (m, :states )
@@ -461,7 +476,7 @@ function fmi2CSInitialize!(m, o, ctx::FMI2CSFunctor, integrator)
461
476
return m
462
477
end
463
478
464
- function fmi2CSStep ! (m, o, ctx:: FMI2CSFunctor , integrator)
479
+ function fmiCSStep ! (m, o, ctx:: FMI2CSFunctor , integrator)
465
480
wrapper = o. wrapper
466
481
states = isdefined (m, :states ) ? m. states : ()
467
482
inputs = o. inputs
@@ -482,4 +497,79 @@ function fmi2CSStep!(m, o, ctx::FMI2CSFunctor, integrator)
482
497
return m
483
498
end
484
499
500
+ struct FMI3CSFunctor
501
+ state_value_references:: Vector{UInt32}
502
+ output_value_references:: Vector{UInt32}
503
+ end
504
+
505
+ function (fn:: FMI3CSFunctor )(wrapper:: FMI3InstanceWrapper , states, inputs, params, t)
506
+ states = states isa SubArray ? copy (states) : states
507
+ inputs = inputs isa SubArray ? copy (inputs) : inputs
508
+ params = params isa SubArray ? copy (params) : params
509
+ instance = get_instance_CS! (wrapper, states, inputs, params, t)
510
+ if isempty (fn. output_value_references)
511
+ return eltype (states)[]
512
+ else
513
+ return FMI. fmi3GetFloat64 (instance, fn. output_value_references)
514
+ end
515
+ end
516
+
517
+ @register_array_symbolic (fn:: FMI3CSFunctor )(
518
+ wrapper:: FMI3InstanceWrapper , states:: Vector{<:Real} ,
519
+ inputs:: Vector{<:Real} , params:: Vector{<:Real} , t:: Real ) begin
520
+ size = (length (states) + length (fn. output_value_references),)
521
+ eltype = eltype (states)
522
+ ndims = 1
523
+ end
524
+
525
+ function fmiCSInitialize! (m, o, ctx:: FMI3CSFunctor , integrator)
526
+ states = isdefined (m, :states ) ? m. states : ()
527
+ inputs = o. inputs
528
+ params = o. params
529
+ t = o. t
530
+ wrapper = o. wrapper
531
+ if wrapper. instance != = nothing
532
+ reset_instance! (wrapper)
533
+ end
534
+ instance = get_instance_CS! (wrapper, states, inputs, params, t)
535
+ if isdefined (m, :states )
536
+ @statuscheck FMI. fmi3GetFloat64! (instance, ctx. state_value_references, m. states)
537
+ end
538
+ if isdefined (m, :outputs )
539
+ @statuscheck FMI. fmi3GetFloat64! (instance, ctx. output_value_references, m. outputs)
540
+ end
541
+
542
+ return m
543
+ end
544
+
545
+ function fmiCSStep! (m, o, ctx:: FMI3CSFunctor , integrator)
546
+ wrapper = o. wrapper
547
+ states = isdefined (m, :states ) ? m. states : ()
548
+ inputs = o. inputs
549
+ params = o. params
550
+ t = o. t
551
+ dt = o. dt
552
+
553
+ instance = get_instance_CS! (wrapper, states, inputs, params, integrator. t)
554
+ eventEncountered = Ref (FMI. fmi3False)
555
+ terminateSimulation = Ref (FMI. fmi3False)
556
+ earlyReturn = Ref (FMI. fmi3False)
557
+ lastSuccessfulTime = Ref (zero (FMI. fmi3Float64))
558
+ @statuscheck FMI. fmi3DoStep! (
559
+ instance, integrator. t - dt, dt, FMI. fmi3True, eventEncountered,
560
+ terminateSimulation, earlyReturn, lastSuccessfulTime)
561
+ @assert eventEncountered[] == FMI. fmi3False
562
+ @assert terminateSimulation[] == FMI. fmi3False
563
+ @assert earlyReturn[] == FMI. fmi3False
564
+
565
+ if isdefined (m, :states )
566
+ @statuscheck FMI. fmi3GetFloat64! (instance, ctx. state_value_references, m. states)
567
+ end
568
+ if isdefined (m, :outputs )
569
+ @statuscheck FMI. fmi3GetFloat64! (instance, ctx. output_value_references, m. outputs)
570
+ end
571
+
572
+ return m
573
+ end
574
+
485
575
end # module
0 commit comments