@@ -346,9 +346,10 @@ const hydrochrono::hydro::SystemState& TestHydro::GetCachedSystemState(double ti
346346}
347347
348348// ------------------------------------------------------------
349- // SECTION: Hydrostatics (delegates to HydrostaticsComponent)
349+ // SECTION: Hydrostatics (legacy path, delegates to HydrostaticsComponent)
350350// ------------------------------------------------------------
351- // Delegates to HydrostaticsComponent for force computation.
351+ // NOTE: This method is kept for backward compatibility but is no longer called by
352+ // CoordinateFuncForBody(). The main force path now goes through HydroSystem.
352353
353354std::vector<double > TestHydro::ComputeForceHydrostatics () {
354355 auto __t0 = std::chrono::steady_clock::now ();
@@ -552,6 +553,10 @@ hydrochrono::hydro::BodyForces TestHydro::EvaluateHydroSystem(double time) {
552553}
553554
554555void TestHydro::CompareWithHydroSystem (double time, int total_dofs) {
556+ // DEPRECATED: This method is no longer called from CoordinateFuncForBody().
557+ // The main force path now routes through HydroSystem, so there's nothing to compare.
558+ // This method is kept for potential external use but will likely be removed in a future cleanup.
559+
555560 // Evaluate forces via the persistent HydroSystem path
556561 hydrochrono::hydro::BodyForces new_forces = EvaluateHydroSystem (time);
557562
@@ -596,9 +601,10 @@ void TestHydro::CompareWithHydroSystem(double time, int total_dofs) {
596601 }
597602}
598603
599- // Main radiation convolution computation.
604+ // Legacy radiation convolution computation.
600605// RadiationComponent is the single source of truth for radiation history and forces.
601- // It internally manages velocity history and performs RIRF convolution.
606+ // NOTE: This method is kept for backward compatibility but is no longer called by
607+ // CoordinateFuncForBody(). The main force path now goes through HydroSystem.
602608std::vector<double > TestHydro::ComputeForceRadiationDampingConv () {
603609 auto __t0 = std::chrono::steady_clock::now ();
604610 const int total_dofs = kDofPerBody * num_bodies_;
@@ -621,20 +627,22 @@ std::vector<double> TestHydro::ComputeForceRadiationDampingConv() {
621627 // RadiationComponent::Compute() handles:
622628 // - Recording current velocities into its internal history
623629 // - Performing RIRF convolution over the velocity history
624- // - Returning the radiation damping forces
630+ // - Returning the radiation damping forces (negative, since damping opposes motion)
625631 hydrochrono::hydro::BodyForces body_forces (num_bodies_);
626632 for (int b = 0 ; b < num_bodies_; ++b) {
627633 body_forces[b].resize (kDofPerBody );
628634 body_forces[b].setZero ();
629635 }
630636 radiation_component_->Compute (system_state, simulation_time, body_forces);
631637
632- // Convert BodyForces to legacy flat 6N vector format
638+ // Convert BodyForces to legacy flat 6N vector format.
639+ // Negate to return positive damping magnitude (legacy convention: CoordinateFuncForBody
640+ // used to subtract this, but now HydroSystem handles the sign internally).
633641 force_radiation_damping_.assign (kDofPerBody * num_bodies_, 0.0 );
634642 for (int b = 0 ; b < num_bodies_; ++b) {
635643 const int body_offset = kDofPerBody * b;
636644 for (int i = 0 ; i < kDofPerBody ; ++i) {
637- force_radiation_damping_[body_offset + i] = body_forces[b][i];
645+ force_radiation_damping_[body_offset + i] = - body_forces[b][i]; // Negate for legacy compatibility
638646 }
639647 }
640648
@@ -669,9 +677,10 @@ double TestHydro::GetRIRFval(int row, int col, int st) {
669677}
670678
671679// ------------------------------------------------------------
672- // SECTION: Wave excitation
680+ // SECTION: Wave excitation (legacy path, delegates to ExcitationComponent)
673681// ------------------------------------------------------------
674- // Delegates to ExcitationComponent for force computation.
682+ // NOTE: This method is kept for backward compatibility but is no longer called by
683+ // CoordinateFuncForBody(). The main force path now goes through HydroSystem.
675684
676685Eigen::VectorXd TestHydro::ComputeForceWaves () {
677686 auto __t0 = std::chrono::steady_clock::now ();
@@ -718,8 +727,8 @@ Eigen::VectorXd TestHydro::ComputeForceWaves() {
718727// SECTION: Main force evaluation (Chrono callback entry point)
719728// ------------------------------------------------------------
720729// Called by Chrono via ForceFunc6d/ComponentFunc callbacks.
721- // Coordinates all force components and caches results per time step .
722- // TODO: This will become a thin adapter delegating to HydroSystem .
730+ // Routes force computation through HydroSystem + ChronoHydroCoupler .
731+ // Forces are cached per timestep via prev_time check .
723732
724733double TestHydro::CoordinateFuncForBody (int b, int dof_index) {
725734 if (dof_index < 0 || dof_index >= kDofPerBody || b < 1 || b > num_bodies_) {
@@ -740,33 +749,35 @@ double TestHydro::CoordinateFuncForBody(int b, int dof_index) {
740749 return total_force_[body_num_offset + dof_index];
741750 }
742751
743- // Update time and reset forces for this time step
752+ // Update time for this new timestep
744753 prev_time = bodies_[0 ]->GetChTime ();
745754
746- // Build SystemState once for this timestep (reused by all force computations)
755+ // Build SystemState once for this timestep
747756 hydrochrono::hydro::BuildSystemStateFromChronoBodies (bodies_, cached_state_);
748757 cached_state_time_ = prev_time;
749758
750- std::fill (total_force_.begin (), total_force_.end (), 0.0 );
751- std::fill (force_hydrostatic_.begin (), force_hydrostatic_.end (), 0.0 );
752- std::fill (force_radiation_damping_.begin (), force_radiation_damping_.end (), 0.0 );
753- std::fill (force_waves_.begin (), force_waves_.end (), 0.0 );
759+ // Ensure HydroSystem + ChronoHydroCoupler are initialized
760+ EnsureHydroSystemAndCoupler ();
754761
755- // Compute all force components (multibody: all bodies computed together)
756- force_hydrostatic_ = ComputeForceHydrostatics ();
757- force_radiation_damping_ = ComputeForceRadiationDampingConv ();
758- force_waves_ = ComputeForceWaves ();
762+ // Compute total forces via HydroSystem.
763+ // HydroSystem::Evaluate() combines all components:
764+ // - Hydrostatics: added with + sign
765+ // - Radiation: added with - sign (damping opposes motion, handled inside RadiationComponent)
766+ // - Excitation: added with + sign
767+ // Result: total = hydrostatics - radiation + waves
768+ hydrochrono::hydro::BodyForces body_forces = chrono_coupler_->Evaluate (prev_time);
759769
760- // Accumulate total force (multibody: sum over all DOFs for all bodies)
761- // Note: radiation damping is subtracted (damping opposes motion)
762- for (int index = 0 ; index < total_dofs; index++) {
763- total_force_[index] = force_hydrostatic_[index] - force_radiation_damping_[index] + force_waves_[index];
770+ // Flatten BodyForces into total_force_ (legacy flat 6N format)
771+ std::fill (total_force_.begin (), total_force_.end (), 0.0 );
772+ for (int body_idx = 0 ; body_idx < num_bodies_; ++body_idx) {
773+ const int offset = kDofPerBody * body_idx;
774+ for (int dof = 0 ; dof < kDofPerBody ; ++dof) {
775+ total_force_[offset + dof] = body_forces[body_idx][dof];
776+ }
764777 }
765778
766- // Comparison harness: compare legacy path vs HydroSystem path
767- if (compare_mode_) {
768- CompareWithHydroSystem (prev_time, total_dofs);
769- }
779+ // Note: compare_mode_ is no longer used here because the main path IS HydroSystem now.
780+ // The legacy per-component path is preserved for external callers but not used by this method.
770781
771782#ifdef HYDROCHRONO_DEBUG
772783 std::cout << " [HYDRO_DEBUG] CoordinateFuncForBody: body=" << b << " , dof=" << dof_index
0 commit comments