Skip to content

Commit 73ca6bd

Browse files
committed
route TestHydro force computation through HydroSystem and ChronoHydroCoupler
Make HydroSystem + ChronoHydroCoupler the authoritative force path in TestHydro. CoordinateFuncForBody() now ensures the HydroSystem/coupler are initialized, calls chrono_coupler_->Evaluate(time) each new timestep, and flattens the resulting BodyForces into total_force_ for all DOFs. Legacy ComputeForce* methods and CompareWithHydroSystem() are retained but marked as legacy.
1 parent 01d0b24 commit 73ca6bd

2 files changed

Lines changed: 44 additions & 31 deletions

File tree

src/hydro/force_components/radiation_component.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -124,11 +124,13 @@ void RadiationComponent::Compute(const SystemState& state,
124124
}
125125
}
126126

127-
// Map flat vector to per-body forces and add to inout_forces
127+
// Map flat vector to per-body forces and add to inout_forces.
128+
// Radiation damping opposes motion, so we SUBTRACT (add with negative sign).
129+
// This ensures HydroSystem::Evaluate() produces: total = hydrostatics - radiation + waves.
128130
for (int b = 0; b < num_bodies_; ++b) {
129131
const int body_offset = kDofPerBody * b;
130132
for (int i = 0; i < kDofPerBody; ++i) {
131-
inout_forces[b][i] += force_flat[body_offset + i];
133+
inout_forces[b][i] -= force_flat[body_offset + i];
132134
}
133135
}
134136
}

src/hydro_forces.cpp

Lines changed: 40 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -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

353354
std::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

554555
void 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.
602608
std::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

676685
Eigen::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

724733
double 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

Comments
 (0)