@@ -329,7 +329,7 @@ slave_instance::slave_instance(
329329
330330slave_instance::~slave_instance () noexcept
331331{
332- if (simStarted_ ) {
332+ if (lifecycleState_ == lifecycle_state::step ) {
333333 fmi2_import_terminate (handle_);
334334 }
335335 fmi2_import_free_instance (handle_);
@@ -343,7 +343,7 @@ void slave_instance::setup(
343343 std::optional<time_point> stopTime,
344344 std::optional<double > relativeTolerance)
345345{
346- assert (!setupComplete_ );
346+ assert (lifecycleState_ == lifecycle_state::instantiated );
347347 const auto rcs = fmi2_import_setup_experiment (
348348 handle_,
349349 relativeTolerance ? fmi2_true : fmi2_false,
@@ -364,31 +364,27 @@ void slave_instance::setup(
364364 last_log_record (instanceName_).message );
365365 }
366366
367- setupComplete_ = true ;
368367 lifecycleState_ = lifecycle_state::initialization;
369368}
370369
371370
372371void slave_instance::start_simulation ()
373372{
374- assert (setupComplete_);
375- assert (!simStarted_);
373+ assert (lifecycleState_ == lifecycle_state::initialization);
376374 const auto rc = fmi2_import_exit_initialization_mode (handle_);
377375 if (rc != fmi2_status_ok && rc != fmi2_status_warning) {
378376 throw error (
379377 make_error_code (errc::model_error),
380378 last_log_record (instanceName_).message );
381379 }
382- simStarted_ = true ;
383380 lifecycleState_ = lifecycle_state::step;
384381}
385382
386383
387384void slave_instance::end_simulation ()
388385{
389- assert (simStarted_ );
386+ assert (lifecycleState_ == lifecycle_state::step );
390387 const auto rc = fmi2_import_terminate (handle_);
391- simStarted_ = false ;
392388 if (rc != fmi2_status_ok && rc != fmi2_status_warning) {
393389 throw error (
394390 make_error_code (errc::model_error),
@@ -400,7 +396,7 @@ void slave_instance::end_simulation()
400396
401397step_result slave_instance::do_step (time_point currentT, duration deltaT)
402398{
403- assert (simStarted_ );
399+ assert (lifecycleState_ == lifecycle_state::step );
404400 const auto rc = fmi2_import_do_step (
405401 handle_,
406402 to_double_time_point (currentT),
@@ -607,8 +603,6 @@ void slave_instance::restore_state(state_index stateIndex)
607603 make_error_code (errc::model_error),
608604 last_log_record (instanceName_).message );
609605 }
610- setupComplete_ = state.setupComplete ;
611- simStarted_ = state.simStarted ;
612606 lifecycleState_ = state.lifecycleState ;
613607}
614608
@@ -672,8 +666,6 @@ serialization::node slave_instance::export_state(state_index stateIndex) const
672666 exportedState.put (" scheme_version" , export_scheme_version);
673667 exportedState.put (" fmu_uuid" , fmu_->model_description ()->uuid );
674668 exportedState.put (" serialized_fmu_state" , serializedFMUState);
675- exportedState.put (" setup_complete" , savedState.setupComplete );
676- exportedState.put (" simulation_started" , savedState.simStarted );
677669 exportedState.put (
678670 " lifecycle_state" ,
679671 static_cast <std::int32_t >(savedState.lifecycleState ));
@@ -715,56 +707,26 @@ slave::state_index slave_instance::import_state(
715707 }
716708
717709 // Validate wrapper state before asking the FMU to allocate a state.
718- savedState.setupComplete = exportedState.get <bool >(" setup_complete" );
719- savedState.simStarted = exportedState.get <bool >(" simulation_started" );
720- if (schemeVersion == 0 ) {
721- if (savedState.setupComplete && !savedState.simStarted ) {
710+ const auto serializedLifecycleState =
711+ exportedState.get <std::int32_t >(" lifecycle_state" );
712+ switch (serializedLifecycleState) {
713+ case static_cast <std::int32_t >(lifecycle_state::instantiated):
714+ savedState.lifecycleState = lifecycle_state::instantiated;
715+ break ;
716+ case static_cast <std::int32_t >(lifecycle_state::initialization):
717+ savedState.lifecycleState = lifecycle_state::initialization;
718+ break ;
719+ case static_cast <std::int32_t >(lifecycle_state::step):
720+ savedState.lifecycleState = lifecycle_state::step;
721+ break ;
722+ case static_cast <std::int32_t >(lifecycle_state::terminated):
723+ savedState.lifecycleState = lifecycle_state::terminated;
724+ break ;
725+ default :
722726 throw error (
723727 make_error_code (errc::bad_file),
724728 " The serialized state of subsimulator '" + instanceName_
725- + " ' uses scheme 0 lifecycle data that is ambiguous "
726- " between Initialization Mode and Terminated" );
727- }
728- savedState.lifecycleState = savedState.simStarted
729- ? lifecycle_state::step
730- : lifecycle_state::instantiated;
731- } else {
732- const auto serializedLifecycleState =
733- exportedState.get <std::int32_t >(" lifecycle_state" );
734- switch (serializedLifecycleState) {
735- case static_cast <std::int32_t >(lifecycle_state::instantiated):
736- savedState.lifecycleState = lifecycle_state::instantiated;
737- break ;
738- case static_cast <std::int32_t >(lifecycle_state::initialization):
739- savedState.lifecycleState = lifecycle_state::initialization;
740- break ;
741- case static_cast <std::int32_t >(lifecycle_state::step):
742- savedState.lifecycleState = lifecycle_state::step;
743- break ;
744- case static_cast <std::int32_t >(lifecycle_state::terminated):
745- savedState.lifecycleState = lifecycle_state::terminated;
746- break ;
747- default :
748- throw error (
749- make_error_code (errc::bad_file),
750- " The serialized state of subsimulator '" + instanceName_
751- + " ' contains an invalid lifecycle state" );
752- }
753- const bool lifecycleStateConsistent =
754- (savedState.lifecycleState == lifecycle_state::instantiated &&
755- !savedState.setupComplete && !savedState.simStarted ) ||
756- (savedState.lifecycleState == lifecycle_state::initialization &&
757- savedState.setupComplete && !savedState.simStarted ) ||
758- (savedState.lifecycleState == lifecycle_state::step &&
759- savedState.setupComplete && savedState.simStarted ) ||
760- (savedState.lifecycleState == lifecycle_state::terminated &&
761- savedState.setupComplete && !savedState.simStarted );
762- if (!lifecycleStateConsistent) {
763- throw error (
764- make_error_code (errc::bad_file),
765- " The serialized state of subsimulator '" + instanceName_
766- + " ' contains inconsistent lifecycle data" );
767- }
729+ + " ' contains an invalid lifecycle state" );
768730 }
769731
770732 const auto & serializedFMUState = std::get<std::vector<std::byte>>(
@@ -829,9 +791,12 @@ void slave_instance::get_directional_derivative(
829791 lifecycleState_ != lifecycle_state::step &&
830792 lifecycleState_ != lifecycle_state::terminated) {
831793 throw error (
832- make_error_code (errc::model_error ),
794+ make_error_code (errc::invalid_operation ),
833795 instanceName_ +
834- " : invalid lifecycle operation: GetDirectionalDerivative" );
796+ " : GetDirectionalDerivative can only be called in lifecycle states "
797+ " initialization (1), step (2), or terminated (3); current lifecycle "
798+ " state: " +
799+ std::to_string (static_cast <std::int32_t >(lifecycleState_)));
835800 }
836801 COSIM_INPUT_CHECK (!unknowns.empty ());
837802 COSIM_INPUT_CHECK (!knowns.empty ());
@@ -844,9 +809,6 @@ void slave_instance::get_directional_derivative(
844809 references.end (),
845810 reference) != references.end ();
846811 };
847- const bool initializing =
848- lifecycleState_ == lifecycle_state::initialization;
849-
850812 for (const auto reference : unknowns) {
851813 const auto variable = fmi2_import_get_variable_by_vr (
852814 handle_, fmi2_base_type_real, reference);
@@ -857,7 +819,8 @@ void slave_instance::get_directional_derivative(
857819 contains (outputReferences_, reference) &&
858820 (variability == fmi2_variability_enu_continuous ||
859821 variability == fmi2_variability_enu_discrete);
860- const bool validUnknown = initializing
822+ const bool validUnknown =
823+ lifecycleState_ == lifecycle_state::initialization
861824 ? contains (initialUnknownReferences_, reference)
862825 : eligibleOutput ||
863826 contains (derivativeReferences_, reference);
@@ -879,7 +842,7 @@ void slave_instance::get_directional_derivative(
879842 validKnown =
880843 causality == fmi2_causality_enu_input ||
881844 causality == fmi2_causality_enu_independent;
882- if (initializing ) {
845+ if (lifecycleState_ == lifecycle_state::initialization ) {
883846 validKnown =
884847 validKnown ||
885848 fmi2_import_get_initial (variable) ==
@@ -940,8 +903,6 @@ void slave_instance::copy_current_state(saved_state& state)
940903 make_error_code (errc::model_error),
941904 last_log_record (instanceName_).message );
942905 }
943- state.setupComplete = setupComplete_;
944- state.simStarted = simStarted_;
945906 state.lifecycleState = lifecycleState_;
946907}
947908
0 commit comments