Skip to content

Commit c86fd5d

Browse files
committed
Add doc for excitation convolution + check bounds
1 parent 4e75ce5 commit c86fd5d

3 files changed

Lines changed: 32 additions & 13 deletions

File tree

doc/user/_theory/theory.rst

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,7 @@ This transform allows the frequency domain coefficients, :math:`B(\omega)`, to b
117117
Wave excitation force, :math:`F_{exc}(t)`
118118
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
119119

120-
The following method to compute the wave excitation force involves convolution between the excitation impulse response function :math:`K_{exc}(t)` and the wave elevation time sequence :math:`\eta(t)`:
120+
The following method to compute the wave excitation force involves convolution between the excitation Impulse Response Function (IRF) :math:`K_{exc}(t)` and the wave elevation time sequence :math:`\eta(t)`:
121121

122122
.. math::
123123
:label: f_ex
@@ -126,6 +126,8 @@ The following method to compute the wave excitation force involves convolution b
126126
127127
By amalgamating these forces into the equation of motion, one can effectively model the behavior of a multibody oceanic system influenced by hydrodynamic forces.
128128

129+
In HydroChrono, the force is computed through trapezoidal integration by discretizing at the time values given by the excitation IRF time array relative to the current simulation time step. Linear interpolation is done for the free surface elevation if a given time value is between two values of the time series of the precomputed free surface elevation.
130+
129131

130132
.. rubric:: Footnotes
131133

include/hydroc/wave_types.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -366,6 +366,11 @@ class IrregularWaves : public WaveBase {
366366
/**
367367
* @brief Calculates the component of force from Convolution integral for specified body, dof, time.
368368
*
369+
* The discretization uses the time series of the of the IRF relative to the current time step.
370+
* Linear interpolation is done for the free surface elevation if time_sim-time_irf is between two
371+
* values of the time series of the precomputed free surface elevation.
372+
* Trapezoidal integration is used to compute the force.
373+
*
369374
* @param body which body currently calculating for
370375
* @param dof which degree of freedom to calculate force value for
371376
* @param time the time to compute force for

src/wave_types.cpp

Lines changed: 24 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -530,7 +530,7 @@ double IrregularWaves::ExcitationConvolution(int body, int dof, double time) {
530530
auto tmin = free_surface_time_sampled_.front();
531531
auto tmax = free_surface_time_sampled_.back();
532532
double t_tau = time - irf_time_array[0];
533-
int idx = 0;
533+
int idx = 0;
534534
if (t_tau <= tmin) {
535535
idx = 0;
536536
} else if (t_tau >= tmax) {
@@ -549,26 +549,38 @@ double IrregularWaves::ExcitationConvolution(int body, int dof, double time) {
549549
idx -= 1;
550550
}
551551

552-
// linearly interpolate free surface elevation between bounds
553552
// free surface time values
554553
auto t1 = free_surface_time_sampled_[idx];
555554
auto t2 = free_surface_time_sampled_[idx + 1];
556-
// double check that t_tau is between bounds
557-
if (t_tau < t1 || t_tau > t2) {
555+
556+
// get free surface elevation
557+
double eta_val;
558+
if (t_tau == t1) {
559+
eta_val = free_surface_time_sampled_[idx];
560+
} else if (t_tau == t2) {
561+
eta_val = free_surface_time_sampled_[idx + 1];
562+
} else if (t_tau > t1 && t_tau < t2) {
563+
// linearly interpolate free surface elevation between bounds
564+
auto eta1 = free_surface_elevation_sampled_[idx];
565+
auto eta2 = free_surface_elevation_sampled_[idx + 1];
566+
// weights
567+
auto w1 = (t2 - t_tau) / (t2 - t1);
568+
auto w2 = 1.0 - w1;
569+
// weighted value
570+
auto eta_val = w1 * eta1 + w2 * eta2;
571+
} else {
558572
throw std::runtime_error("Excitation convolution: wrong tau value " + std::to_string(tau) +
559573
" not between " + std::to_string(t1) + " and " + std::to_string(t2) + ".");
560574
}
561-
// free surface elevation values
562-
auto eta1 = free_surface_elevation_sampled_[idx];
563-
auto eta2 = free_surface_elevation_sampled_[idx + 1];
564-
// weights
565-
auto w1 = (t2 - t_tau) / (t2 - t1);
566-
auto w2 = 1.0 - w1;
567-
// weighted value
568-
auto eta_val = w1 * eta1 + w2 * eta2;
569575

570576
// add to excitation force
571577
f_ex += irf_val_mat(dof, j) * eta_val * irf_width_array[j];
578+
579+
} else {
580+
throw std::runtime_error(
581+
"Excitation convolution: trying to find free surface elevation at a time out of bounds from "
582+
"the precomputed free surface elevation (" +
583+
std::to_string(t_tau) + "not in [" + std::to_string(tmin) + ", " + std::to_string(tmax) + "]).");
572584
}
573585
}
574586

0 commit comments

Comments
 (0)