@@ -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