@@ -144,12 +144,16 @@ function MTK.FMIComponent(::Val{Ver}; fmu = nothing, tolerance = 1e-6,
144144
145145 push! (params, wrapper, functor)
146146 push! (states, __mtk_internal_u)
147- elseif type == :CS && Ver == 2
147+ elseif type == :CS
148148 state_value_references = UInt32[value_references[var] for var in diffvars]
149149 state_and_output_value_references = vcat (
150150 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
153157 @parameters (functor:: (typeof(_functor) ))(.. )[1 : (length (__mtk_internal_u) + length (__mtk_internal_o))] = _functor
154158 for (i, x) in enumerate (collect (__mtk_internal_o))
155159 push! (initialization_eqs,
@@ -168,11 +172,11 @@ function MTK.FMIComponent(::Val{Ver}; fmu = nothing, tolerance = 1e-6,
168172 if symbolic_type (__mtk_internal_u) != NotSymbolic ()
169173 cb_modified = (cb_modified... , states = __mtk_internal_u)
170174 end
171- initialize_affect = MTK. ImperativeAffect (fmi2CSInitialize !; observed = cb_observed,
175+ initialize_affect = MTK. ImperativeAffect (fmiCSInitialize !; observed = cb_observed,
172176 modified = cb_modified, ctx = _functor)
173177 finalize_affect = MTK. FunctionalAffect (fmiFinalize!, [], [wrapper], [])
174178 step_affect = MTK. ImperativeAffect (
175- fmi2CSStep !; observed = cb_observed, modified = cb_modified, ctx = _functor)
179+ fmiCSStep !; observed = cb_observed, modified = cb_modified, ctx = _functor)
176180 instance_management_callback = MTK. SymbolicDiscreteCallback (
177181 communication_step_size, step_affect; initialize = initialize_affect, finalize = finalize_affect
178182 )
@@ -318,6 +322,16 @@ function get_instance_ME!(wrapper::FMI3InstanceWrapper, states, inputs, params,
318322 return wrapper. instance
319323end
320324
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+
321335function complete_step! (wrapper:: FMI3InstanceWrapper )
322336 wrapper. instance === nothing && return
323337 enterEventMode = Ref (FMI. fmi3False)
440454 ndims = 1
441455end
442456
443- function fmi2CSInitialize ! (m, o, ctx:: FMI2CSFunctor , integrator)
457+ function fmiCSInitialize ! (m, o, ctx:: FMI2CSFunctor , integrator)
444458 states = isdefined (m, :states ) ? m. states : ()
445459 inputs = o. inputs
446460 params = o. params
@@ -449,6 +463,7 @@ function fmi2CSInitialize!(m, o, ctx::FMI2CSFunctor, integrator)
449463 if wrapper. instance != = nothing
450464 reset_instance! (wrapper)
451465 end
466+
452467 instance = get_instance_common! (wrapper, states, inputs, params, t)
453468 @statuscheck FMI. fmi2ExitInitializationMode (instance)
454469 if isdefined (m, :states )
@@ -461,7 +476,7 @@ function fmi2CSInitialize!(m, o, ctx::FMI2CSFunctor, integrator)
461476 return m
462477end
463478
464- function fmi2CSStep ! (m, o, ctx:: FMI2CSFunctor , integrator)
479+ function fmiCSStep ! (m, o, ctx:: FMI2CSFunctor , integrator)
465480 wrapper = o. wrapper
466481 states = isdefined (m, :states ) ? m. states : ()
467482 inputs = o. inputs
@@ -482,4 +497,79 @@ function fmi2CSStep!(m, o, ctx::FMI2CSFunctor, integrator)
482497 return m
483498end
484499
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+
485575end # module
0 commit comments