66#include " ../hydro_yaml_parser.h"
77#include < hydroc/hydro_forces.h>
88#include < hydroc/simulation_exporter.h>
9+ #include < hydroc/wave_types.h>
910
1011#include < chrono_parsers/yaml/ChParserMbsYAML.h>
1112#include < chrono/physics/ChSystem.h>
2425#include < sstream>
2526#include < chrono>
2627#include < iomanip>
28+ #include < cmath>
2729
2830#ifdef _WIN32
2931#include < windows.h>
@@ -443,8 +445,10 @@ int RunHydroChronoFromYAML(int argc, char* argv[]) {
443445
444446 // Setup hydrodynamic forces
445447 hydroc::debug::LogDebug (" Initializing TestHydro..." );
446- // Provide a neutral horizon (Chrono governs runtime via YAML/UI)
447- test_hydro = SetupHydroFromYAML (hydro_data, bodies, loop_dt, /* time_end_hint*/ 0.0 , 0.0 );
448+ // Provide simulation horizon from YAML end_time (important for irregular waves spectrum)
449+ double sim_duration_hint = 0.0 ;
450+ TryFindYamlDouble (sim_file, " end_time" , sim_duration_hint);
451+ test_hydro = SetupHydroFromYAML (hydro_data, bodies, loop_dt, sim_duration_hint, 0.0 );
448452 hydroc::debug::LogDebug (" Hydrodynamic forces initialized successfully" );
449453
450454 // Inform location for diagnostics CSVs: write to hydro file directory
@@ -650,9 +654,23 @@ int RunHydroChronoFromYAML(int argc, char* argv[]) {
650654 exporter = std::make_unique<hydroc::SimulationExporter>(exp_opts);
651655
652656 // Write static info and model before stepping
653- exporter->WriteSimulationInfo (system.get (), std::string (" " ), std::filesystem::path (model_file).filename ().generic_string (), loop_dt, /* duration_seconds*/ 0.0 );
657+ double duration_hint = 0.0 ; TryFindYamlDouble (sim_file, " end_time" , duration_hint);
658+ exporter->WriteSimulationInfo (system.get (), std::string (" " ), std::filesystem::path (model_file).filename ().generic_string (), loop_dt, duration_hint);
654659 exporter->WriteModel (system.get ());
655660 exporter->BeginResults (system.get (), /* expected_steps*/ 0 );
661+
662+ // If irregular waves are configured, persist spectrum and eta(t) inputs to HDF5
663+ if (test_hydro) {
664+ auto wave_ptr = test_hydro->GetWave ();
665+ if (wave_ptr && wave_ptr->GetWaveMode () == WaveMode::irregular) {
666+ auto irreg = std::static_pointer_cast<IrregularWaves>(wave_ptr);
667+ std::vector<double > f = irreg->GetFrequenciesHz ();
668+ std::vector<double > S = irreg->GetSpectrum ();
669+ std::vector<double > tvec = irreg->GetFreeSurfaceTime ();
670+ std::vector<double > eta = irreg->GetFreeSurfaceElevation ();
671+ exporter->WriteIrregularInputs (f, S, tvec, eta);
672+ }
673+ }
656674 } catch (const std::exception& e) {
657675 hydroc::cli::LogWarning (std::string (" HDF5 exporter disabled: " ) + e.what ());
658676 exporter.reset ();
@@ -691,6 +709,14 @@ int RunHydroChronoFromYAML(int argc, char* argv[]) {
691709
692710 if (nogui) {
693711 const double end_time_bound = (yaml_end_time > 0.0 ) ? yaml_end_time : 40.0 ;
712+ // Estimate total steps for progress bar; ensure at least 1
713+ const double remaining_time = std::max (0.0 , end_time_bound - initial_time);
714+ const size_t total_steps_est = static_cast <size_t >(std::max (1.0 , std::ceil (remaining_time / std::max (1e-12 , loop_dt))));
715+ size_t last_progress_step = 0 ;
716+
717+ // Initial progress line
718+ hydroc::cli::ShowProgress (0 , total_steps_est, std::string (" t=" ) + hydroc::FormatNumber (initial_time, 2 ) + " / " + hydroc::FormatNumber (end_time_bound, 2 ) + " s" );
719+
694720 while (system->GetChTime () < end_time_bound) {
695721 double current_time = system->GetChTime ();
696722 try {
@@ -703,18 +729,33 @@ int RunHydroChronoFromYAML(int argc, char* argv[]) {
703729 exporter->RecordStep (system.get ());
704730 if (profile_mode) { prof_export_seconds += std::chrono::duration_cast<std::chrono::duration<double >>(std::chrono::steady_clock::now () - t).count (); }
705731 }
732+ // Update progress periodically to reduce console churn
733+ if (step_count == 1 || step_count - static_cast <int >(last_progress_step) >= 25 ) {
734+ const size_t current_steps = static_cast <size_t >(std::min<double >(total_steps_est, std::ceil ((system->GetChTime () - initial_time) / std::max (1e-12 , loop_dt))));
735+ std::string msg = std::string (" t=" ) + hydroc::FormatNumber (system->GetChTime (), 2 ) + " / " + hydroc::FormatNumber (end_time_bound, 2 ) + " s" ;
736+ hydroc::cli::ShowProgress (current_steps, total_steps_est, msg);
737+ last_progress_step = static_cast <size_t >(step_count);
738+ }
706739 previous_time = current_time;
707740 } catch (const std::exception& e) {
741+ hydroc::cli::StopProgress ();
708742 hydroc::cli::LogError (std::string (" 🔥 Exception during DoStepDynamics at step " ) + std::to_string (step_count) + " : " + e.what ());
709743 hydroc::cli::LogError (std::string (" Simulation time: " ) + hydroc::FormatNumber (current_time, 6 ) + " s" );
710744 hydroc::cli::LogError (std::string (" Step size: " ) + hydroc::FormatNumber (loop_dt, 6 ) + " s" );
711745 break ;
712746 } catch (...) {
747+ hydroc::cli::StopProgress ();
713748 hydroc::cli::LogError (std::string (" 🔥 Unknown exception during DoStepDynamics at step " ) + std::to_string (step_count));
714749 hydroc::cli::LogError (std::string (" Simulation time: " ) + hydroc::FormatNumber (current_time, 6 ) + " s" );
715750 break ;
716751 }
717752 }
753+ // Finalize progress line
754+ if (system->GetChTime () >= end_time_bound - 1e-9 ) {
755+ hydroc::cli::ShowProgress (total_steps_est, total_steps_est, " Completed" );
756+ } else {
757+ hydroc::cli::StopProgress ();
758+ }
718759 } else {
719760 // GUI-driven loop: respects pause via ui.simulationStarted and closes when window stops
720761 while (ui.IsRunning (loop_dt)) {
0 commit comments