@@ -482,8 +482,9 @@ IrregularWaves::IrregularWaves(const IrregularWaveParams& params)
482482 ramp_duration_(params.ramp_duration_),
483483 seed_(params.seed_) {
484484 std::cout << " Creating IrregularWaves object..." << std::endl;
485- ex_irf_resampled_.resize (num_bodies_);
486- ex_irf_time_resampled_.resize (num_bodies_);
485+ ex_irf_sampled_.resize (num_bodies_);
486+ ex_irf_time_sampled_.resize (num_bodies_);
487+ ex_irf_width_sampled_.resize (num_bodies_);
487488 std::cout << " eta_file_path (1)" << eta_file_path_ << std::endl;
488489 if (!eta_file_path_.empty ()) {
489490 std::cout << " Reading eta.txt..." << std::endl;
@@ -521,14 +522,14 @@ void IrregularWaves::InitializeIRFVectors() {
521522 std::vector<Eigen::VectorXd> ex_irf_time_old (num_bodies_);
522523
523524 for (unsigned int b = 0 ; b < num_bodies_; b++) {
524- ex_irf_old[b] = GetExcitationIRF (b);
525- ex_irf_time_old[b] = wave_info_[b].excitation_irf_time ;
525+ ex_irf_sampled_[b] = GetExcitationIRF (b);
526+ ex_irf_time_sampled_[b] = wave_info_[b].excitation_irf_time ;
527+ CalculateWidthIRF ();
526528 }
527529
528530 // Resample excitation IRF time series
529- for (unsigned int b = 0 ; b < num_bodies_; b++) {
530- ex_irf_time_resampled_[b] = ResampleTime (ex_irf_time_old[b], simulation_dt_);
531- ex_irf_resampled_[b] = ResampleVals (ex_irf_time_old[b], ex_irf_old[b], ex_irf_time_resampled_[b]);
531+ if (simulation_dt_ > 0.0 ) {
532+ ResampleIRF (simulation_dt_);
532533 }
533534}
534535
@@ -616,44 +617,56 @@ Eigen::VectorXd IrregularWaves::GetForceAtTime(double t) {
616617 return f;
617618}
618619
619- Eigen::MatrixXd IrregularWaves::ResampleVals (const Eigen::VectorXd& t_old,
620- Eigen::MatrixXd& vals_old,
621- const Eigen::VectorXd& t_new) {
622- assert (vals_old.rows () == 6 );
623-
624- Eigen::MatrixXd vals_new (6 , t_new.size ());
625- // we need to scale t to be [0,1] for spline use
626- // TODO: change this to accomodate variable dt instead of const dt
627- Eigen::VectorXd t_old_scaled = Eigen::VectorXd::LinSpaced (t_old.size (), 0 , 1 );
628- Eigen::VectorXd t_new_scaled = Eigen::VectorXd::LinSpaced (t_new.size (), 0 , 1 );
629-
630- Eigen::Spline<double , 6 > spline =
631- Eigen::SplineFitting<Eigen::Spline<double , 6 >>::Interpolate (vals_old, 3 , t_old_scaled);
632- for (int i = 0 ; i < t_new.rows (); i++) {
633- vals_new.col (i) = spline (t_new_scaled[i]);
620+ void IrregularWaves::ResampleIRF (double dt) {
621+ for (unsigned int b = 0 ; b < num_bodies_; b++) {
622+ // 0) access arrays to modify at body index
623+ auto & time_array = ex_irf_time_sampled_[b];
624+ auto & width_array = ex_irf_width_sampled_[b];
625+ auto & val_array = ex_irf_sampled_[b];
626+ // copy time array
627+ auto time_array_old = time_array;
628+
629+ // 1) resample time
630+ auto t0 = time_array_old[0 ];
631+ auto t1 = time_array_old[time_array_old.size () - 1 ];
632+ time_array = Eigen::VectorXd::LinSpaced (static_cast <int >(ceil ((t1 - t0) / dt)), t0, t1);
633+
634+ // 2) resample width
635+ CalculateWidthIRF ();
636+
637+ // 3) resample values
638+ assert (val_array.rows () == 6 );
639+ Eigen::MatrixXd vals_new (6 , time_array.size ());
640+ // we need to scale t to be [0,1] for spline use
641+ Eigen::VectorXd t_old_scaled = Eigen::VectorXd::LinSpaced (time_array_old.size (), 0 , 1 );
642+ Eigen::VectorXd t_new_scaled = Eigen::VectorXd::LinSpaced (time_array.size (), 0 , 1 );
643+ // use spline to get new values
644+ Eigen::Spline<double , 6 > spline =
645+ Eigen::SplineFitting<Eigen::Spline<double , 6 >>::Interpolate (val_array, 3 , t_old_scaled);
646+ for (int i = 0 ; i < time_array.rows (); i++) {
647+ vals_new.col (i) = spline (t_new_scaled[i]);
648+ }
649+ val_array = vals_new;
634650 }
635-
636- // std::cout << "Old time vector:\n" << t_old << std::endl;
637- // std::cout << "Old values:\n" << vals_old << std::endl;
638- // std::cout << "New time vector:\n" << t_new << std::endl;
639- // std::cout << "New values:\n" << vals_new << std::endl; // assuming new_vals is the output of the function
640-
641- return vals_new;
642651}
643652
644- Eigen::VectorXd IrregularWaves::ResampleTime (const Eigen::VectorXd& t_old, const double dt_new) {
645- double dt_old = t_old[1 ] - t_old[0 ];
646- int size_new = static_cast <int >(ceil (t_old.size () * dt_old / dt_new));
647- double t_initial = t_old[0 ];
648- double t_final = t_old[t_old.size () - 1 ];
649- // t_0 and t_final should be the same in old/new versions, use new time step, which means a different number of
650- // timesteps
651- Eigen::VectorXd t_new = Eigen::VectorXd::LinSpaced (size_new, t_initial, t_final);
652-
653- int N_old = t_old.size () - 1 ;
654- int N_new = t_new.size () - 1 ;
655-
656- return t_new;
653+ void IrregularWaves::CalculateWidthIRF () {
654+ for (unsigned int b = 0 ; b < num_bodies_; b++) {
655+ auto & time_array = ex_irf_time_sampled_[b];
656+ auto & width_array = ex_irf_width_sampled_[b];
657+
658+ // 2) calculate width
659+ width_array.resize (time_array.size ());
660+ for (int ii = 0 ; ii < width_array.size (); ii++) {
661+ width_array[ii] = 0.0 ;
662+ if (ii < time_array.size () - 1 ) {
663+ width_array[ii] += 0.5 * abs (time_array[ii + 1 ] - time_array[ii]);
664+ }
665+ if (ii > 0 ) {
666+ width_array[ii] += 0.5 * abs (time_array[ii] - time_array[ii - 1 ]);
667+ }
668+ }
669+ }
657670}
658671
659672Eigen::VectorXd IrregularWaves::SetSpectrumFrequencies (double start, double end, int num_points) {
@@ -774,9 +787,10 @@ void IrregularWaves::CreateFreeSurfaceElevation() {
774787}
775788
776789double IrregularWaves::ExcitationConvolution (int body, int dof, double time) {
777- double f_ex = 0.0 ;
778- auto & irf_time_array = ex_irf_time_resampled_[body];
779- auto & irf_val_mat = ex_irf_resampled_[body];
790+ double f_ex = 0.0 ;
791+ auto & irf_time_array = ex_irf_time_sampled_[body];
792+ auto & irf_val_mat = ex_irf_sampled_[body];
793+ auto & irf_width_array = ex_irf_width_sampled_[body];
780794
781795 // asumptions: irf_time_array in ascending order, free_surface_time_sampled_ in ascending order
782796 // get initial index
@@ -820,18 +834,8 @@ double IrregularWaves::ExcitationConvolution(int body, int dof, double time) {
820834 // weighted value
821835 auto eta_val = w1 * eta1 + w2 * eta2;
822836
823- // calculate width
824- double width = 0 ;
825- if (j > 0 ) {
826- width += 0.5 * (irf_time_array[j] - irf_time_array[j - 1 ]);
827- }
828- if (j < irf_time_array.size () - 1 ) {
829- width += 0.5 * (irf_time_array[j + 1 ] - irf_time_array[j]);
830- }
831-
832- double ex_irf_val = irf_val_mat (dof, j);
833-
834- f_ex += ex_irf_val * eta_val * width;
837+ // add to excitation force
838+ f_ex += irf_val_mat (dof, j) * eta_val * irf_width_array[j];
835839 }
836840 }
837841
0 commit comments