1414#include < chrono/physics/ChLoad.h>
1515#include < unsupported/Eigen/Splines>
1616
17+ #include < Eigen/Dense>
1718#include < algorithm>
1819#include < cmath>
20+ #include < fstream>
21+ #include < iostream>
1922#include < memory>
2023#include < numeric> // std::accumulate
2124#include < random>
22- #include < vector>
23- #include < Eigen/Dense>
24- #include < fstream>
25- #include < iostream>
2625#include < stdexcept>
26+ #include < vector>
2727
2828const int kDofPerBody = 6 ;
2929const int kDofLinOrRot = 3 ;
@@ -96,7 +96,7 @@ ForceFunc6d::ForceFunc6d() : forces_{{this, 0}, {this, 1}, {this, 2}, {this, 3},
9696
9797ForceFunc6d::ForceFunc6d (std::shared_ptr<ChBody> object, TestHydro* user_all_forces) : ForceFunc6d() {
9898 body_ = object;
99- std::string temp = body_->GetNameString (); // remove "body" from "bodyN", convert N to int, get body num
99+ std::string temp = body_->GetNameString (); // remove "body" from "bodyN", convert N to int, get body num
100100 b_num_ = stoi (temp.erase (0 , 4 )); // 1 indexed TODO: fix b_num starting here to be 0 indexed
101101 all_hydro_forces_ = user_all_forces; // TODO switch to smart pointers? does this use = ?
102102 if (all_hydro_forces_ == NULL ) {
@@ -166,9 +166,7 @@ TestHydro::TestHydro(std::vector<std::shared_ptr<ChBody>> user_bodies,
166166 : bodies_(user_bodies),
167167 num_bodies_(bodies_.size()),
168168 file_info_(H5FileInfo(h5_file_name, num_bodies_).ReadH5Data()) {
169-
170- prev_time = -1 ;
171- offset_rirf = 0 ;
169+ prev_time = -1 ;
172170
173171 // Set up time vector
174172 rirf_time_vector = file_info_.GetRIRFTimeVector ();
@@ -178,7 +176,11 @@ TestHydro::TestHydro(std::vector<std::shared_ptr<ChBody>> user_bodies,
178176 int total_dofs = kDofPerBody * num_bodies_;
179177
180178 // Initialize vectors
181- velocity_history_.assign (file_info_.GetRIRFDims (2 ) * total_dofs, 0.0 );
179+ time_history_.clear ();
180+ velocity_history_.clear ();
181+ for (int b = 0 ; b < num_bodies_; ++b) {
182+ velocity_history_.push_back (std::vector<std::vector<double >>(0 ));
183+ }
182184 force_hydrostatic_.assign (total_dofs, 0.0 );
183185 force_radiation_damping_.assign (total_dofs, 0.0 );
184186 total_force_.assign (total_dofs, 0.0 );
@@ -238,48 +240,12 @@ void TestHydro::AddWaves(std::shared_ptr<WaveBase> waves) {
238240 user_waves_->Initialize ();
239241}
240242
241- double TestHydro::GetVelHistoryVal (int step, int c) const {
242- if (step < 0 || step >= file_info_.GetRIRFDims (2 ) || c < 0 || c >= num_bodies_ * kDofPerBody ) {
243- std::cout << " wrong vel history index " << std::endl;
244- return 0 ;
245- }
246-
247- int index = c % kDofPerBody ;
248- int b = c / kDofPerBody ; // 0 indexed
249- int calculated_index = index + (kDofPerBody * b) + (kDofPerBody * num_bodies_ * step);
250-
251- if (calculated_index >= num_bodies_ * kDofPerBody * file_info_.GetRIRFDims (2 ) || calculated_index < 0 ) {
252- std::cout << " bad vel history math" << std::endl;
253- return 0 ;
254- }
255-
256- return velocity_history_[calculated_index];
257- }
258-
259- double TestHydro::SetVelHistory (double val, int step, int b_num, int index) {
260- if (step < 0 || step >= file_info_.GetRIRFDims (2 ) || b_num < 1 || b_num > num_bodies_ || index < 0 ||
261- index >= kDofPerBody ) {
262- std::cout << " bad set vel history indexing" << std::endl;
263- return 0 ;
264- }
265-
266- int calculated_index = index + (kDofPerBody * (b_num - 1 )) + (kDofPerBody * num_bodies_ * step);
267-
268- if (calculated_index < 0 || calculated_index >= num_bodies_ * kDofPerBody * file_info_.GetRIRFDims (2 )) {
269- std::cout << " bad set vel history math" << std::endl;
270- return 0 ;
271- }
272-
273- velocity_history_[calculated_index] = val;
274- return val;
275- }
276-
277243std::vector<double > TestHydro::ComputeForceHydrostatics () {
278244 assert (num_bodies_ > 0 );
279245
280- const double rho = file_info_.GetRhoVal ();
281- const auto g_acc = bodies_[0 ]->GetSystem ()->Get_G_acc (); // assuming all bodies in same system
282- const double gg = g_acc.Length ();
246+ const double rho = file_info_.GetRhoVal ();
247+ const auto g_acc = bodies_[0 ]->GetSystem ()->Get_G_acc (); // assuming all bodies in same system
248+ const double gg = g_acc.Length ();
283249
284250 for (int b = 0 ; b < num_bodies_; b++) {
285251 std::shared_ptr<chrono::ChBody> body = bodies_[b];
@@ -294,7 +260,7 @@ std::vector<double> TestHydro::ComputeForceHydrostatics() {
294260
295261 chrono::ChVectorN<double , kDofPerBody > body_displacement;
296262 for (int ii = 0 ; ii < kDofLinOrRot ; ii++) {
297- body_displacement[ii] = body_position[ii] - body_equilibrium[ii];
263+ body_displacement[ii] = body_position[ii] - body_equilibrium[ii];
298264 body_displacement[ii + kDofLinOrRot ] = body_rotation[ii] - body_equilibrium[ii + kDofLinOrRot ];
299265 }
300266
@@ -328,69 +294,95 @@ std::vector<double> TestHydro::ComputeForceRadiationDampingConv() {
328294 const int numRows = kDofPerBody * num_bodies_;
329295 const int numCols = kDofPerBody * num_bodies_;
330296
331- // "Shift" everything left 1
332- offset_rirf--; // Starts as 0 before timestep change
333-
334- // Keep offset close to 0, avoids small chance of overflow errors in long simulations
335- if (offset_rirf < -1 * size) {
336- offset_rirf += size;
337- }
338-
339297 assert (numRows * size > 0 && numCols > 0 );
340298
341- std::vector<double > timeseries (numRows * numCols * size, 0.0 );
342299 std::vector<double > tmp_s (numRows * size, 0.0 );
343300
344- // Helper function for timeseries indexing
345- auto TimeseriesIndex = [&](int row, int col, int step) { return (row * numCols * size) + (col * size) + step; };
346-
347301 // Helper function for tmp_s indexing
348302 auto TmpSIndex = [&](int row, int step) { return (row * size) + step; };
349303
350- // Helper function for circular indexing
351- auto CircularIndex = [&](int value) { return ((value % size) + size) % size; };
304+ // time history
305+ auto t_sim = bodies_[0 ]->GetChTime ();
306+ auto t_min = t_sim - rirf_timestep_ * size;
307+ time_history_.insert (time_history_.begin (), t_sim);
308+
309+ // velocity history
310+ for (int b = 0 ; b < num_bodies_; b++) {
311+ auto & body = bodies_[b];
312+ auto & velocity_history_body = velocity_history_[b];
352313
353- // Set last entry as velocity
354- for (int i = 0 ; i < 3 ; i++) {
355- for (int b = 1 ; b <= num_bodies_; b++) {
356- int vi = CircularIndex (size + offset_rirf);
357- SetVelHistory (bodies_[b - 1 ]->GetPos_dt ()[i], vi, b, i);
358- SetVelHistory (bodies_[b - 1 ]->GetWvel_par ()[i], vi, b, i + 3 );
314+ auto vel = body->GetPos_dt ();
315+ auto wvel = body->GetWvel_par ();
316+ std::vector<double > vel_vec = {vel[0 ], vel[1 ], vel[2 ], wvel[0 ], wvel[1 ], wvel[2 ]};
317+ velocity_history_body.insert (velocity_history_body.begin (), vel_vec);
318+ }
319+
320+ // remove unnecessary history
321+ if (time_history_.size () > 1 ) {
322+ while (time_history_[time_history_.size () - 2 ] < t_min) {
323+ time_history_.pop_back ();
324+ for (int b = 0 ; b < num_bodies_; b++) {
325+ auto & velocity_history_body = velocity_history_[b];
326+ velocity_history_body.pop_back ();
327+ }
359328 }
360329 }
361330
362- if (convTrapz_) {
363- for (int row = 0 ; row < numRows; row++) {
364- for (int st = 0 ; st < size; st++) {
365- int vi = CircularIndex (st + offset_rirf);
366- tmp_s[TmpSIndex (row, st)] = 0 ;
367- for (int col = 0 ; col < numCols; col++) {
368- timeseries[TimeseriesIndex (row, col, st)] = GetRIRFval (row, col, st) * GetVelHistoryVal (vi, col);
369- tmp_s[TmpSIndex (row, st)] += timeseries[TimeseriesIndex (row, col, st)];
331+ if (convTrapz_ && time_history_.size () > 1 ) {
332+ int idx_history = 0 ;
333+
334+ // iterate over RIRF steps
335+ for (int step = 0 ; step < size; step++) {
336+ auto t_rirf = t_sim - rirf_timestep_ * step;
337+ while (time_history_[idx_history + 1 ] > t_rirf && idx_history < time_history_.size () - 1 ) {
338+ idx_history += 1 ;
339+ }
340+ if (idx_history >= time_history_.size () - 1 ) {
341+ break ;
342+ }
343+
344+ // iterate over bodies
345+ for (int idx_body = 0 ; idx_body < num_bodies_; idx_body++) {
346+ auto & velocity_history_body = velocity_history_[idx_body];
347+
348+ // interpolate velocity at t_rirf from recorded velocity history
349+ // time values
350+ auto t1 = time_history_[idx_history + 1 ];
351+ auto t2 = time_history_[idx_history];
352+ if (t_rirf < t1 || t_rirf > t2) {
353+ throw std::runtime_error (" Radiation convolution: wrong interpolation: " + std::to_string (t_rirf) +
354+ " not between " + std::to_string (t1) + " and " + std::to_string (t2) + " ." );
355+ }
356+ // weights
357+ auto w1 = (t2 - t_rirf) / (t2 - t1);
358+ auto w2 = 1.0 - w1;
359+ // velocity values
360+ auto vel1 = velocity_history_body[idx_history + 1 ];
361+ auto vel2 = velocity_history_body[idx_history];
362+
363+ for (int dof = 0 ; dof < kDofPerBody ; dof++) {
364+ // get column index
365+ int col = dof + idx_body * kDofPerBody ;
366+ // get weighted velocity for DOF
367+ auto vel_weighted = w1 * vel1[dof] + w2 * vel2[dof];
368+
369+ // iterate over rows
370+ for (int row = 0 ; row < numRows; row++) {
371+ tmp_s[TmpSIndex (row, step)] += GetRIRFval (row, col, step) * vel_weighted;
372+ }
370373 }
371- if (st > 0 ) {
374+ }
375+
376+ if (step > 0 ) {
377+ // cummulate values for current step on all rows
378+ for (int row = 0 ; row < numRows; row++) {
372379 // Integrate tmp_s
373- force_radiation_damping_[row] += (tmp_s[TmpSIndex (row, st - 1 )] + tmp_s[TmpSIndex (row, st )]) / 2.0 *
374- (rirf_time_vector[st ] - rirf_time_vector[st - 1 ]);
380+ force_radiation_damping_[row] += (tmp_s[TmpSIndex (row, step - 1 )] + tmp_s[TmpSIndex (row, step )]) /
381+ 2.0 * (rirf_time_vector[step ] - rirf_time_vector[step - 1 ]);
375382 }
376383 }
377384 }
378385 }
379- // else {
380- // // Convolution integral assuming fixed dt
381- // for (int row = 0; row < numRows; row++) {
382- // double sumVelHistoryAndRIRF = 0.0;
383- // for (int col = 0; col < numCols; col++) {
384- // for (int st = 0; st < size; st++) {
385- // int vi = CircularIndex(st + offset_rirf);
386- // timeseries[TimeseriesIndex(row, col, st)] = GetRIRFval(row, col, st) * GetVelHistoryVal(vi, col);
387- // sumVelHistoryAndRIRF += timeseries[TimeseriesIndex(row, col, st)];
388- // }
389- // }
390- // force_radiation_damping_[row] -= sumVelHistoryAndRIRF * rirf_timestep;
391- // }
392- // }
393-
394386 return force_radiation_damping_;
395387}
396388
0 commit comments