MoorDyn
Time.hpp
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2022, Jose Luis Cercos-Pita <jlc@core-marine.com>
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions are met:
6  *
7  * 1. Redistributions of source code must retain the above copyright notice,
8  * this list of conditions and the following disclaimer.
9  *
10  * 2. Redistributions in binary form must reproduce the above copyright notice,
11  * this list of conditions and the following disclaimer in the documentation
12  * and/or other materials provided with the distribution.
13  *
14  * 3. Neither the name of the copyright holder nor the names of its
15  * contributors may be used to endorse or promote products derived from
16  * this software without specific prior written permission.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
22  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28  * POSSIBILITY OF SUCH DAMAGE.
29  */
30 
35 #pragma once
36 
37 #include "Misc.hpp"
38 #include "IO.hpp"
39 #include "State.hpp"
40 #include "Line.hpp"
41 #include "Point.hpp"
42 #include "Rod.hpp"
43 #include "Body.hpp"
44 #include "Waves.hpp"
45 #include <vector>
46 #include <string>
47 
48 namespace moordyn {
49 
50 namespace time {
51 
58 class Scheme : public io::IO
59 {
60  public:
62  virtual ~Scheme() {}
63 
67  inline void SetGround(Body* obj) { ground = obj; }
68 
73  virtual void AddLine(Line* obj)
74  {
75  if (std::find(lines.begin(), lines.end(), obj) != lines.end()) {
76  LOGERR << "The line " << obj->number << " was already registered"
77  << endl;
78  throw moordyn::invalid_value_error("Repeated object");
79  }
80  lines.push_back(obj);
81  }
82 
89  virtual unsigned int RemoveLine(Line* obj)
90  {
91  auto it = std::find(lines.begin(), lines.end(), obj);
92  if (it == lines.end()) {
93  LOGERR << "The line " << obj->number << " was not registered"
94  << endl;
95  throw moordyn::invalid_value_error("Missing object");
96  }
97  const unsigned int i = std::distance(lines.begin(), it);
98  lines.erase(it);
99  return i;
100  }
101 
106  virtual void AddPoint(Point* obj)
107  {
108  if (std::find(points.begin(), points.end(), obj) != points.end()) {
109  LOGERR << "The point " << obj->number << " was already registered"
110  << endl;
111  throw moordyn::invalid_value_error("Repeated object");
112  }
113  points.push_back(obj);
114  }
115 
122  virtual unsigned int RemovePoint(Point* obj)
123  {
124  auto it = std::find(points.begin(), points.end(), obj);
125  if (it == points.end()) {
126  LOGERR << "The point " << obj->number << " was not registered"
127  << endl;
128  throw moordyn::invalid_value_error("Missing object");
129  }
130  const unsigned int i = std::distance(points.begin(), it);
131  points.erase(it);
132  return i;
133  }
134 
139  virtual void AddRod(Rod* obj)
140  {
141  if (std::find(rods.begin(), rods.end(), obj) != rods.end()) {
142  LOGERR << "The rod " << obj->number << " was already registered"
143  << endl;
144  throw moordyn::invalid_value_error("Repeated object");
145  }
146  rods.push_back(obj);
147  }
148 
155  virtual unsigned int RemoveRod(Rod* obj)
156  {
157  auto it = std::find(rods.begin(), rods.end(), obj);
158  if (it == rods.end()) {
159  LOGERR << "The rod " << obj->number << " was not registered"
160  << endl;
161  throw moordyn::invalid_value_error("Missing object");
162  }
163  const unsigned int i = std::distance(rods.begin(), it);
164  rods.erase(it);
165  return i;
166  }
167 
172  virtual void AddBody(Body* obj)
173  {
174  if (std::find(bodies.begin(), bodies.end(), obj) != bodies.end()) {
175  LOGERR << "The body " << obj->number << " was already registered"
176  << endl;
177  throw moordyn::invalid_value_error("Repeated object");
178  }
179  bodies.push_back(obj);
180  }
181 
188  virtual unsigned int RemoveBody(Body* obj)
189  {
190  auto it = std::find(bodies.begin(), bodies.end(), obj);
191  if (it == bodies.end()) {
192  LOGERR << "The body " << obj->number << " was not registered"
193  << endl;
194  throw moordyn::invalid_value_error("Missing object");
195  }
196  const unsigned int i = std::distance(bodies.begin(), it);
197  bodies.erase(it);
198  return i;
199  }
200 
204  inline std::string GetName() const { return name; }
205 
209  inline real GetTime() const { return t; }
210 
215  inline void SetTime(const real& time)
216  {
217  t = time;
218  Next();
219  }
220 
224  inline real GetCFL() const { return cfl; }
225 
229  inline void SetCFL(const real& cfl) { this->cfl = cfl; }
230 
235  inline void Next()
236  {
237  t_local = 0.0;
238  for (unsigned int i = 0; i < lines.size(); i++) {
239  lines[i]->updateUnstretchedLength();
240  }
241  }
242 
248  virtual void Init() = 0;
249 
257  virtual void Step(real& dt) { t_local += dt; };
258 
263  virtual moordyn::state::State GetState(unsigned int i = 0) = 0;
264 
269  inline virtual void SetState(const moordyn::state::State& state,
270  unsigned int i = 0) {};
271 
277  inline virtual void SaveState(const std::string filepath,
278  unsigned int i = 0)
279  {
280  }
281 
286  inline virtual void LoadState(const std::string filepath,
287  unsigned int i = 0)
288  {
289  }
290 
291  protected:
296  : io::IO(log)
297  , name("None")
298  , t(0.0)
299  {
300  }
301 
304 
306  std::vector<Line*> lines;
307 
309  std::vector<Point*> points;
310 
312  std::vector<Rod*> rods;
313 
315  std::vector<Body*> bodies;
316 
318  std::string name;
319 
324 
327 };
328 
334 #define AS_STATE(R) ((moordyn::state::State*)R)
335 
341 template<unsigned int NSTATE, unsigned int NDERIV>
342 class SchemeBase : public Scheme
343 {
344  public:
346  virtual ~SchemeBase()
347  {
348  for (unsigned int substep = 0; substep < NSTATE; substep++) {
349  delete _r[substep];
350  }
351  for (unsigned int substep = 0; substep < NDERIV; substep++) {
352  delete _rd[substep];
353  }
354  }
355 
360  virtual void AddLine(Line* obj)
361  {
362  try {
363  Scheme::AddLine(obj);
364  } catch (...) {
365  throw;
366  }
367  for (unsigned int i = 0; i < NSTATE; i++)
368  AS_STATE(_r[i])->addInstance(obj);
369  for (unsigned int i = 0; i < NDERIV; i++)
370  AS_STATE(_rd[i])->addInstance(obj);
371  // Add the mask value
372  _calc_mask.lines.push_back(true);
373  }
374 
375  // virtual void AddLine(Line* obj)
376  // {
377  // try {
378  // TimeScheme::AddLine(obj);
379  // } catch (...) {
380  // throw;
381  // }
382  // // Build up the states and states derivatives
383  // unsigned int n = obj->getN() - 1;
384  // LineState state;
385  // LineState mstate; // misc state stuff
386  // state.pos.assign(n, vec::Zero());
387  // state.vel.assign(n, vec::Zero());
388  // mstate.pos.assign(n+2, vec::Zero());
389  // mstate.vel.assign(n+2, vec::Zero());
390  // for (unsigned int i = 0; i < r.size(); i++) {
391  // r[i].lines.push_back(state);
392  // r[i].misc.push_back(mstate);
393  // }
394  // DLineStateDt dstate;
395  // DLineStateDt mdstate; // misc state stuff
396  // dstate.vel.assign(n, vec::Zero());
397  // dstate.acc.assign(n, vec::Zero());
398  // mdstate.vel.assign(n+2, vec::Zero());
399  // mdstate.acc.assign(n+2, vec::Zero());
400  // for (unsigned int i = 0; i < rd.size(); i++) {
401  // rd[i].lines.push_back(dstate);
402  // rd[i].misc.push_back(mdstate);
403  // }
404  // // Add the mask value
405  // _calc_mask.lines.push_back(true);
406  // }
407 
414  virtual unsigned int RemoveLine(Line* obj)
415  {
416  unsigned int i;
417  try {
418  i = Scheme::RemoveLine(obj);
419  } catch (...) {
420  throw;
421  }
422  for (unsigned int i = 0; i < NSTATE; i++)
423  AS_STATE(_r[i])->removeInstance(obj);
424  for (unsigned int i = 0; i < NDERIV; i++)
425  AS_STATE(_rd[i])->removeInstance(obj);
426  _calc_mask.lines.erase(_calc_mask.lines.begin() + i);
427  return i;
428  }
429 
430  // virtual unsigned int RemoveLine(Line* obj)
431  // {
432  // unsigned int i;
433  // try {
434  // i = TimeScheme::RemoveLine(obj);
435  // } catch (...) {
436  // throw;
437  // }
438  // for (unsigned int i = 0; i < r.size(); i++) {
439  // r[i].lines.erase(r[i].lines.begin() + i);
440  // r[i].misc.erase(r[i].misc.begin() + i);
441  // }
442  // for (unsigned int i = 0; i < rd.size(); i++) {
443  // rd[i].lines.erase(rd[i].lines.begin() + i);
444  // rd[i].misc.erase(rd[i].misc.begin() + i);
445  // }
446  // _calc_mask.lines.erase(_calc_mask.lines.begin() + i);
447  // return i;
448  // }
449 
454  virtual void AddPoint(Point* obj)
455  {
456  try {
457  Scheme::AddPoint(obj);
458  } catch (...) {
459  throw;
460  }
461  for (unsigned int i = 0; i < NSTATE; i++)
462  AS_STATE(_r[i])->addInstance(obj);
463  for (unsigned int i = 0; i < NDERIV; i++)
464  AS_STATE(_rd[i])->addInstance(obj);
465  // Add the mask value
466  _calc_mask.points.push_back(true);
467  }
468 
475  virtual unsigned int RemovePoint(Point* obj)
476  {
477  unsigned int i;
478  try {
479  i = Scheme::RemovePoint(obj);
480  } catch (...) {
481  throw;
482  }
483  for (unsigned int i = 0; i < NSTATE; i++)
484  AS_STATE(_r[i])->removeInstance(obj);
485  for (unsigned int i = 0; i < NDERIV; i++)
486  AS_STATE(_rd[i])->removeInstance(obj);
487  _calc_mask.points.erase(_calc_mask.points.begin() + i);
488  return i;
489  }
490 
495  virtual void AddRod(Rod* obj)
496  {
497  try {
498  Scheme::AddRod(obj);
499  } catch (...) {
500  throw;
501  }
502  for (unsigned int i = 0; i < NSTATE; i++)
503  AS_STATE(_r[i])->addInstance(obj);
504  for (unsigned int i = 0; i < NDERIV; i++)
505  AS_STATE(_rd[i])->addInstance(obj);
506  // Add the mask value
507  _calc_mask.rods.push_back(true);
508  }
509 
516  virtual unsigned int RemoveRod(Rod* obj)
517  {
518  unsigned int i;
519  try {
520  i = Scheme::RemoveRod(obj);
521  } catch (...) {
522  throw;
523  }
524  for (unsigned int i = 0; i < NSTATE; i++)
525  AS_STATE(_r[i])->removeInstance(obj);
526  for (unsigned int i = 0; i < NDERIV; i++)
527  AS_STATE(_rd[i])->removeInstance(obj);
528  _calc_mask.rods.erase(_calc_mask.rods.begin() + i);
529  return i;
530  }
531 
536  virtual void AddBody(Body* obj)
537  {
538  try {
539  Scheme::AddBody(obj);
540  } catch (...) {
541  throw;
542  }
543  for (unsigned int i = 0; i < NSTATE; i++)
544  AS_STATE(_r[i])->addInstance(obj);
545  for (unsigned int i = 0; i < NDERIV; i++)
546  AS_STATE(_rd[i])->addInstance(obj);
547  // Add the mask value
548  _calc_mask.bodies.push_back(true);
549  }
550 
557  virtual unsigned int RemoveBody(Body* obj)
558  {
559  unsigned int i;
560  try {
561  i = Scheme::RemoveBody(obj);
562  } catch (...) {
563  throw;
564  }
565  for (unsigned int i = 0; i < NSTATE; i++)
566  AS_STATE(_r[i])->removeInstance(obj);
567  for (unsigned int i = 0; i < NDERIV; i++)
568  AS_STATE(_rd[i])->removeInstance(obj);
569  _calc_mask.bodies.erase(_calc_mask.bodies.begin() + i);
570  return i;
571  }
572 
578  virtual void Init()
579  {
580  // NOTE: Probably is best to populate all the entities to the time
581  // integrator, no matter if they are free or not. Thus they can change
582  // types (mutate) without needing to micromanage them in the time
583  // scheme
584  for (unsigned int i = 0; i < bodies.size(); i++) {
585  // Only fully coupled bodies are intialized in MD2.cpp
586  if ((bodies[i]->type != Body::FREE) &&
587  (bodies[i]->type != Body::CPLDPIN))
588  continue;
589  bodies[i]->initialize(AS_STATE(_r[0])->get(bodies[i]));
590  for (unsigned int j = 0; j < NDERIV; j++)
591  AS_STATE(_rd[j])->get(bodies[i]).setZero();
592  }
593 
594  for (unsigned int i = 0; i < rods.size(); i++) {
595  if ((rods[i]->type != Rod::FREE) && (rods[i]->type != Rod::PINNED))
596  continue;
597  rods[i]->initialize(AS_STATE(_r[0])->get(rods[i]));
598  for (unsigned int j = 0; j < NDERIV; j++)
599  AS_STATE(_rd[j])->get(rods[i]).setZero();
600  }
601 
602  for (unsigned int i = 0; i < points.size(); i++) {
603  if (points[i]->type != Point::FREE)
604  continue;
605  points[i]->initialize(AS_STATE(_r[0])->get(points[i]));
606  for (unsigned int j = 0; j < NDERIV; j++)
607  AS_STATE(_rd[j])->get(points[i]).setZero();
608  }
609 
610  for (unsigned int i = 0; i < lines.size(); i++) {
611  lines[i]->initialize(AS_STATE(_r[0])->get(lines[i]));
612  for (unsigned int j = 0; j < NDERIV; j++)
613  AS_STATE(_rd[j])->get(lines[i]).setZero();
614  }
615  }
616 
624  virtual void Step(real& dt) { Scheme::Step(dt); };
625 
633  inline state::State* r(unsigned int i = 0)
634  {
635  if (i >= NSTATE) {
636  LOGERR << "State " << i << " cannot be got on a '" << name
637  << "' scheme that has " << NSTATE << "states" << endl;
638  throw moordyn::invalid_value_error("Invalid state");
639  }
640  return _r[i];
641  }
642 
643  inline state::State GetState(unsigned int i = 0) { return *r(i); }
654  inline virtual void SetState(const state::State& state, unsigned int i = 0)
655  {
656  if (i >= NSTATE) {
657  LOGERR << "State " << i << " cannot be setted on a '" << name
658  << "' scheme that has " << NSTATE << " states" << endl;
659  throw moordyn::invalid_value_error("Invalid state");
660  }
661  *_r[i] = state;
662  }
663 
670  inline virtual void SaveState(const std::string filepath,
671  unsigned int i = 0)
672  {
673  auto f = MakeFile(filepath);
674  if (i >= NSTATE) {
675  LOGERR << "State " << i << " cannot be saved on a '" << name
676  << "' scheme that has " << NSTATE << "states" << endl;
677  throw moordyn::invalid_value_error("Invalid state");
678  }
679  std::vector<uint64_t> data = AS_STATE(_r[i])->Serialize();
680  const uint64_t size = data.size();
681  f.write((char*)&size, sizeof(uint64_t));
682  for (auto v : data) {
683  f.write((char*)&v, sizeof(uint64_t));
684  }
685  f.close();
686  }
687 
696  inline virtual void LoadState(const std::string filepath,
697  unsigned int i = 0)
698  {
699  auto [length, data] = LoadFile(filepath);
700  if (i >= NSTATE) {
701  LOGERR << "State " << i << " cannot be loaded on a '" << name
702  << "' scheme that has " << NSTATE << "states" << endl;
703  throw moordyn::invalid_value_error("Invalid state");
704  }
705  const uint64_t* end = AS_STATE(_r[i])->Deserialize(data);
706  if (data + length != end) {
707  const uint64_t l = end - data;
708  LOGERR << l * sizeof(uint64_t) << " bytes (vs. "
709  << length * sizeof(uint64_t)
710  << " bytes expected) unpacked from '" << filepath << "'"
711  << endl;
712  throw moordyn::mem_error("Mismatching data size");
713  }
714 
715  free(data);
716  }
717 
724  inline state::State* rd(unsigned int i = 0)
725  {
726  if (i >= NDERIV) {
727  LOGERR << "State derivative " << i << " cannot be got on a '"
728  << name << "' scheme that has " << NDERIV
729  << "state derivatives" << endl;
730  throw moordyn::invalid_value_error("Invalid state derivative");
731  }
732  return _rd[i];
733  }
734 
741  virtual std::vector<uint64_t> Serialize(void)
742  {
743  std::vector<uint64_t> data, subdata;
744 
745  data.push_back(io::IO::Serialize(t));
746 
747  // We do not need to save the number of states or derivatives, since
748  // that information is already known by each specific time scheme.
749  // Along the same line, we do not need to same information about the
750  // number of lines, rods and so on. That information is already
751  // collected from the definition file
752  for (unsigned int substep = 0; substep < NSTATE; substep++) {
753  subdata = _r[substep]->Serialize();
754  data.insert(data.end(), subdata.begin(), subdata.end());
755  }
756  for (unsigned int substep = 0; substep < NDERIV; substep++) {
757  subdata = _rd[substep]->Serialize();
758  data.insert(data.end(), subdata.begin(), subdata.end());
759  }
760 
761  return data;
762  }
763 
771  virtual uint64_t* Deserialize(const uint64_t* data)
772  {
773  uint64_t* ptr = (uint64_t*)data;
774  ptr = io::IO::Deserialize(ptr, t);
775 
776  // We did not save the number of states or derivatives, since that
777  // information is already known by each specific time scheme.
778  // Along the same line, we did not save information about the number of
779  // lines, rods and so on
780  for (unsigned int substep = 0; substep < NSTATE; substep++) {
781  ptr = _r[substep]->Deserialize(ptr);
782  }
783  for (unsigned int substep = 0; substep < NDERIV; substep++) {
784  ptr = _rd[substep]->Deserialize(ptr);
785  }
786 
787  return ptr;
788  }
789 
790  protected:
797  : Scheme(log)
798  , waves(waves)
799  {
800  // Register some basic variables that we know are always present
801  // The position, and its associated derivative, have several different
802  // types depending on the instance (e.g. moordyn::vec for lines and
803  // points, moordyn::XYZQuat for rods and bodies), so better using lists
804  // that we can resize on demand
805  for (unsigned int substep = 0; substep < NSTATE; substep++) {
806  _r[substep] = new moordyn::state::State(log);
807  }
808  for (unsigned int substep = 0; substep < NDERIV; substep++) {
809  _rd[substep] = new moordyn::state::State(log);
810  }
811  }
812 
821  void Update(real t_local, unsigned int substep = 0);
822 
827  void CalcStateDeriv(unsigned int substep = 0);
828 
830  std::array<moordyn::state::State*, NSTATE> _r;
831 
833  std::array<moordyn::state::State*, NDERIV> _rd;
834 
836  std::shared_ptr<Waves> waves;
837 
842  typedef struct _mask
843  {
845  std::vector<bool> lines;
847  std::vector<bool> points;
849  std::vector<bool> rods;
851  std::vector<bool> bodies;
852  } mask;
853 
856 };
857 
864 class StationaryScheme final : public SchemeBase<2, 1>
865 {
866  public:
872 
875 
881  void Step(real& dt);
882 
886  inline real Error() const { return _error; }
887 
897  inline size_t NStates() const
898  {
899  size_t n =
900  bodies.size() + rods.size() +
901  points.size(); // one row (state) per object here. <objects>.size()
902  // gives the length of the list, i.e. the number of
903  // that kind of object
904  for (size_t i = 0; i < lines.size(); i++)
905  n += lines[i]->stateN();
906  return n;
907  }
908 
909  private:
918  void MakeStationary(real& dt, unsigned int i = 0, unsigned int id = 0);
919 
924  real _error;
925 
927  real _booster;
928 };
929 
936 class EulerScheme final : public SchemeBase<1, 1>
937 {
938  public:
944 
946  virtual ~EulerScheme() {}
947 
953  virtual void Step(real& dt);
954 };
955 
961 template<unsigned int NSTATE, unsigned int NDERIV>
962 class LocalSchemeBase : public SchemeBase<NSTATE, NDERIV>
963 {
964  public:
966  virtual ~LocalSchemeBase() {}
967 
973  inline void Init()
974  {
976  ComputeDt();
977  }
978 
983  inline virtual void SetState(const state::State& state, unsigned int i = 0)
984  {
986  ComputeDt();
987  }
988 
989  protected:
996  : SchemeBase<NSTATE, NDERIV>(log, waves)
997  {
998  }
999 
1003  void SetCalcMask(real& dt);
1004 
1005  private:
1011  real ComputeDt();
1012 
1015  typedef struct _sdeltat
1016  {
1018  std::vector<real> lines;
1020  std::vector<real> points;
1022  std::vector<real> rods;
1024  std::vector<real> bodies;
1025  } deltat;
1026 
1028  deltat _dt0;
1029 
1031  deltat _dt;
1032 };
1033 
1045 class LocalEulerScheme final : public LocalSchemeBase<1, 1>
1046 {
1047  public:
1053 
1056 
1060  void Step(real& dt);
1061 };
1062 
1070 class HeunScheme final : public SchemeBase<1, 2>
1071 {
1072  public:
1078 
1081 
1087  virtual void Step(real& dt);
1088 };
1089 
1095 class RK2Scheme final : public SchemeBase<2, 2>
1096 {
1097  public:
1103 
1106 
1112  virtual void Step(real& dt);
1113 };
1114 
1123 class RK4Scheme final : public SchemeBase<5, 4>
1124 {
1125  public:
1131 
1134 
1140  virtual void Step(real& dt);
1141 };
1142 
1153 template<unsigned int order, bool local>
1154 class ABScheme final : public LocalSchemeBase<1, 5>
1155 {
1156  public:
1162 
1165 
1171  virtual void Step(real& dt);
1172 
1179  virtual std::vector<uint64_t> Serialize(void)
1180  {
1181  std::vector<uint64_t> data = SchemeBase::Serialize();
1182  // We append the number of available steps
1183  data.push_back(io::IO::Serialize((uint64_t)n_steps));
1184 
1185  return data;
1186  }
1187 
1195  virtual uint64_t* Deserialize(const uint64_t* data)
1196  {
1197  uint64_t* ptr = SchemeBase::Deserialize(data);
1198  uint64_t n;
1199  ptr = io::IO::Deserialize(ptr, n);
1200  n_steps = n;
1201 
1202  return ptr;
1203  }
1204 
1205  private:
1207  unsigned int n_steps;
1208 
1212  inline void shift(unsigned int org)
1213  {
1214  const unsigned int dst = org + 1;
1215  for (unsigned int i = 0; i < lines.size(); i++) {
1216  if (!_calc_mask.lines[i])
1217  continue;
1218  AS_STATE(rd(dst))->get(lines[i]) = AS_STATE(rd(org))->get(lines[i]);
1219  }
1220 
1221  for (unsigned int i = 0; i < points.size(); i++) {
1222  if (!_calc_mask.points[i] && (points[i]->type == Point::FREE))
1223  continue;
1224  AS_STATE(rd(dst))->get(points[i]) =
1225  AS_STATE(rd(org))->get(points[i]);
1226  }
1227 
1228  for (unsigned int i = 0; i < rods.size(); i++) {
1229  if (!_calc_mask.rods[i] && ((rods[i]->type != Rod::FREE) ||
1230  (rods[i]->type != Rod::PINNED)))
1231  continue;
1232  AS_STATE(rd(dst))->get(rods[i]) = AS_STATE(rd(org))->get(rods[i]);
1233  }
1234 
1235  for (unsigned int i = 0; i < bodies.size(); i++) {
1236  if (!_calc_mask.bodies[i] && (bodies[i]->type == Body::FREE))
1237  continue;
1238  AS_STATE(rd(dst))->get(bodies[i]) =
1239  AS_STATE(rd(org))->get(bodies[i]);
1240  }
1241  }
1242 
1245  inline void shift()
1246  {
1247  for (unsigned int i = 0; i < _rd.size() - 1; i++)
1248  shift(i);
1249  }
1250 };
1251 
1257 template<unsigned int NSTATE, unsigned int NDERIV>
1258 class ImplicitSchemeBase : public SchemeBase<NSTATE, NDERIV>
1259 {
1260  public:
1267  WavesRef waves,
1268  unsigned int iters = 10);
1269 
1271  virtual ~ImplicitSchemeBase() {}
1272 
1273  protected:
1277  inline unsigned int iters() const { return _iters; }
1278 
1282  inline real c0() const { return _c0; }
1283 
1287  inline void c0(const real c) { _c0 = c; }
1288 
1292  inline real c1() const { return _c1; }
1293 
1297  inline void c1(const real c) { _c1 = c; }
1298 
1305  real Relax(const unsigned int& iter);
1306 
1307  private:
1309  unsigned int _iters;
1310 
1312  real _c0;
1313 
1315  real _c1;
1316 };
1317 
1325 class ImplicitEulerScheme final : public ImplicitSchemeBase<2, 2>
1326 {
1327  public:
1336  WavesRef waves,
1337  unsigned int iters = 10,
1338  real dt_factor = 0.5);
1339 
1342 
1348  virtual void Step(real& dt);
1349 
1350  private:
1352  real _dt_factor;
1353 };
1354 
1363 class ImplicitNewmarkScheme final : public ImplicitSchemeBase<2, 3>
1364 {
1365  public:
1374  WavesRef waves,
1375  unsigned int iters = 10,
1376  real gamma = 0.5,
1377  real beta = 0.25);
1378 
1381 
1387  virtual void Step(real& dt);
1388 
1389  private:
1407  void MakeNewmark(const real& dt);
1408 
1410  real _gamma;
1412  real _beta;
1413 };
1414 
1428 class ImplicitWilsonScheme final : public ImplicitSchemeBase<2, 3>
1429 {
1430  public:
1439  WavesRef waves,
1440  unsigned int iters = 10,
1441  real theta = 1.37);
1442 
1445 
1451  virtual void Step(real& dt);
1452 
1453  private:
1473  void MakeWilson(const real& tau, const real& dt);
1474 
1476  real _theta;
1477 };
1478 
1490 Scheme*
1491 create_time_scheme(const std::string& name, moordyn::Log* log, WavesRef waves);
1492 
1493 } // ::time
1494 
1495 } // ::moordyn
#define LOGERR
Log an error.
Definition: Log.hpp:69
#define AS_STATE(R)
Definition: Time.hpp:334
A rigid body.
Definition: Body.hpp:72
@ FREE
Is free to move, controlled by MoorDyn.
Definition: Body.hpp:157
@ CPLDPIN
Is coupled pinned, i.e. translational dof are controlled by the user.
Definition: Body.hpp:161
int number
Body number.
Definition: Body.hpp:189
A mooring line.
Definition: Line.hpp:71
int number
Line ID.
Definition: Line.hpp:424
A Logging utility.
Definition: Log.hpp:149
A point for a line endpoint.
Definition: Point.hpp:69
int number
Point number.
Definition: Point.hpp:190
@ FREE
Is free to move, controlled by MoorDyn.
Definition: Point.hpp:159
A cylindrical rod.
Definition: Rod.hpp:65
int number
Rod number.
Definition: Rod.hpp:277
@ PINNED
Definition: Rod.hpp:242
@ FREE
Is free to move, controlled by MoorDyn.
Definition: Rod.hpp:239
A base class for all the entities that must save/load data to/from disk.
Definition: IO.hpp:60
IO(moordyn::Log *log)
Costructor.
Definition: IO.cpp:195
ofstream MakeFile(const std::string filepath) const
Create an output file and write the MoorDyn magic header.
Definition: IO.cpp:236
std::tuple< uint64_t, uint64_t * > LoadFile(const std::string filepath) const
Open an input file and load the data.
Definition: IO.cpp:253
virtual std::vector< uint64_t > Serialize(void)=0
Produce the packed data to be saved.
virtual uint64_t * Deserialize(const uint64_t *data)=0
Unpack the data to restore the Serialized information.
The collection of state variables of the whole system.
Definition: State.hpp:54
Adam-Bashforth time schemes collection.
Definition: Time.hpp:1155
~ABScheme()
Destructor.
Definition: Time.hpp:1164
virtual uint64_t * Deserialize(const uint64_t *data)
Unpack the data to restore the Serialized information.
Definition: Time.hpp:1195
ABScheme(moordyn::Log *log, WavesRef waves)
Constructor.
Definition: Time.cpp:511
virtual void Step(real &dt)
Run a time step.
Definition: Time.cpp:530
virtual std::vector< uint64_t > Serialize(void)
Produce the packed data to be saved.
Definition: Time.hpp:1179
The simplest 1st order Euler's time scheme.
Definition: Time.hpp:937
EulerScheme(moordyn::Log *log, WavesRef waves)
Constructor.
Definition: Time.cpp:284
virtual ~EulerScheme()
Destructor.
Definition: Time.hpp:946
virtual void Step(real &dt)
Run a time step.
Definition: Time.cpp:291
Quasi 2nd order Heun's time scheme.
Definition: Time.hpp:1071
virtual void Step(real &dt)
Run a time step.
Definition: Time.cpp:414
~HeunScheme()
Destructor.
Definition: Time.hpp:1080
HeunScheme(moordyn::Log *log, WavesRef waves)
Constructor.
Definition: Time.cpp:407
Implicit 1st order Euler time scheme.
Definition: Time.hpp:1326
ImplicitEulerScheme(moordyn::Log *log, WavesRef waves, unsigned int iters=10, real dt_factor=0.5)
Constructor.
Definition: Time.cpp:596
virtual ~ImplicitEulerScheme()
Destructor.
Definition: Time.hpp:1341
virtual void Step(real &dt)
Run a time step.
Definition: Time.cpp:609
Implicit Newmark Scheme.
Definition: Time.hpp:1364
~ImplicitNewmarkScheme()
Destructor.
Definition: Time.hpp:1380
virtual void Step(real &dt)
Run a time step.
Definition: Time.cpp:656
ImplicitNewmarkScheme(moordyn::Log *log, WavesRef waves, unsigned int iters=10, real gamma=0.5, real beta=0.25)
Constructor.
Definition: Time.cpp:638
A generic abstract implicit scheme.
Definition: Time.hpp:1259
virtual ~ImplicitSchemeBase()
Destructor.
Definition: Time.hpp:1271
void c1(const real c)
Set the tanh relaxation part coefficient.
Definition: Time.hpp:1297
real c1() const
Get the tanh relaxation part coefficient.
Definition: Time.hpp:1292
real c0() const
Get the constant relaxation part coefficient.
Definition: Time.hpp:1282
real Relax(const unsigned int &iter)
Compute the relaxation factor.
Definition: Time.cpp:588
void c0(const real c)
Set the constant relaxation part coefficient.
Definition: Time.hpp:1287
ImplicitSchemeBase(moordyn::Log *log, WavesRef waves, unsigned int iters=10)
Constructor.
Definition: Time.cpp:576
unsigned int iters() const
Get the number of subiterations.
Definition: Time.hpp:1277
Definition: Time.hpp:1429
~ImplicitWilsonScheme()
Destructor.
Definition: Time.hpp:1444
virtual void Step(real &dt)
Run a time step.
Definition: Time.cpp:761
ImplicitWilsonScheme(moordyn::Log *log, WavesRef waves, unsigned int iters=10, real theta=1.37)
Constructor.
Definition: Time.cpp:746
A modification of the 1st order Euler's time scheme, which is considering different time steps for ea...
Definition: Time.hpp:1046
void Step(real &dt)
Run a time step.
Definition: Time.cpp:396
~LocalEulerScheme()
Destructor.
Definition: Time.hpp:1055
LocalEulerScheme(moordyn::Log *log, WavesRef waves)
Constructor.
Definition: Time.cpp:389
A generic abstract integration scheme.
Definition: Time.hpp:963
virtual ~LocalSchemeBase()
Destructor.
Definition: Time.hpp:966
LocalSchemeBase(moordyn::Log *log, moordyn::WavesRef waves)
Costructor.
Definition: Time.hpp:995
void SetCalcMask(real &dt)
Set the calculation mask.
Definition: Time.cpp:303
void Init()
Create an initial state for all the entities.
Definition: Time.hpp:973
virtual void SetState(const state::State &state, unsigned int i=0)
Resume the simulation from the stationary solution.
Definition: Time.hpp:983
2nd order Runge-Kutta time scheme
Definition: Time.hpp:1096
RK2Scheme(moordyn::Log *log, WavesRef waves)
Constructor.
Definition: Time.cpp:434
~RK2Scheme()
Destructor.
Definition: Time.hpp:1105
virtual void Step(real &dt)
Run a time step.
Definition: Time.cpp:441
4th order Runge-Kutta time scheme
Definition: Time.hpp:1124
virtual void Step(real &dt)
Run a time step.
Definition: Time.cpp:469
RK4Scheme(moordyn::Log *log, WavesRef waves)
Constructor.
Definition: Time.cpp:462
~RK4Scheme()
Destructor.
Definition: Time.hpp:1133
A generic abstract integration scheme.
Definition: Time.hpp:343
mask _calc_mask
The SchemeBase::CalcStateDeriv() mask.
Definition: Time.hpp:855
virtual void AddPoint(Point *obj)
Add a point.
Definition: Time.hpp:454
state::State * rd(unsigned int i=0)
Get the state derivative.
Definition: Time.hpp:724
void Update(real t_local, unsigned int substep=0)
Update all the entities to set the state.
Definition: Time.cpp:42
virtual void AddRod(Rod *obj)
Add a rod.
Definition: Time.hpp:495
virtual uint64_t * Deserialize(const uint64_t *data)
Unpack the data to restore the Serialized information.
Definition: Time.hpp:771
virtual void AddBody(Body *obj)
Add a body.
Definition: Time.hpp:536
virtual unsigned int RemoveBody(Body *obj)
Remove a body.
Definition: Time.hpp:557
SchemeBase(moordyn::Log *log, moordyn::WavesRef waves)
Constructor.
Definition: Time.hpp:796
virtual void Step(real &dt)
Run a time step.
Definition: Time.hpp:624
void CalcStateDeriv(unsigned int substep=0)
Compute the time derivatives and store them.
Definition: Time.cpp:95
virtual unsigned int RemoveLine(Line *obj)
Remove a line.
Definition: Time.hpp:414
virtual unsigned int RemoveRod(Rod *obj)
Remove a rod.
Definition: Time.hpp:516
virtual std::vector< uint64_t > Serialize(void)
Produce the packed data to be saved.
Definition: Time.hpp:741
virtual unsigned int RemovePoint(Point *obj)
Remove a point.
Definition: Time.hpp:475
virtual void Init()
Create an initial state for all the entities.
Definition: Time.hpp:578
std::array< moordyn::state::State *, NDERIV > _rd
The list of state derivatives.
Definition: Time.hpp:833
state::State GetState(unsigned int i=0)
Get the state variable.
Definition: Time.hpp:643
std::shared_ptr< Waves > waves
The waves instance.
Definition: Time.hpp:836
virtual void LoadState(const std::string filepath, unsigned int i=0)
Load the system state from a file.
Definition: Time.hpp:696
std::array< moordyn::state::State *, NSTATE > _r
The list of states.
Definition: Time.hpp:830
virtual void SaveState(const std::string filepath, unsigned int i=0)
Save the system state on a file.
Definition: Time.hpp:670
struct moordyn::time::SchemeBase::_mask mask
A mask to determine which entities shall be computed.
virtual void AddLine(Line *obj)
Add a line.
Definition: Time.hpp:360
virtual void SetState(const state::State &state, unsigned int i=0)
Resume the simulation from the stationary solution.
Definition: Time.hpp:654
state::State * r(unsigned int i=0)
Get the state.
Definition: Time.hpp:633
virtual ~SchemeBase()
Destructor.
Definition: Time.hpp:346
Time scheme abstraction.
Definition: Time.hpp:59
real cfl
Maximum CFL factor.
Definition: Time.hpp:326
virtual void AddPoint(Point *obj)
Add a point.
Definition: Time.hpp:106
virtual void AddLine(Line *obj)
Add a line.
Definition: Time.hpp:73
std::vector< Rod * > rods
The rods.
Definition: Time.hpp:312
virtual unsigned int RemoveLine(Line *obj)
Remove a line.
Definition: Time.hpp:89
virtual void SetState(const moordyn::state::State &state, unsigned int i=0)
Resume the simulation from the stationary solution.
Definition: Time.hpp:269
void Next()
Prepare everything for the next outer time step.
Definition: Time.hpp:235
void SetTime(const real &time)
Set the simulation time.
Definition: Time.hpp:215
std::string name
The scheme name.
Definition: Time.hpp:318
virtual void SaveState(const std::string filepath, unsigned int i=0)
Save the system state on a file.
Definition: Time.hpp:277
real t_local
The local time, within the outer time step.
Definition: Time.hpp:323
Scheme(moordyn::Log *log)
Constructor.
Definition: Time.hpp:295
std::vector< Line * > lines
The lines.
Definition: Time.hpp:306
std::vector< Point * > points
The points.
Definition: Time.hpp:309
virtual void Step(real &dt)
Run a time step.
Definition: Time.hpp:257
real t
The simulation time.
Definition: Time.hpp:321
real GetTime() const
Get the simulation time.
Definition: Time.hpp:209
virtual void AddBody(Body *obj)
Add a body.
Definition: Time.hpp:172
std::vector< Body * > bodies
The bodies.
Definition: Time.hpp:315
virtual unsigned int RemoveBody(Body *obj)
Remove a body.
Definition: Time.hpp:188
virtual moordyn::state::State GetState(unsigned int i=0)=0
Get the state variable.
virtual void AddRod(Rod *obj)
Add a rod.
Definition: Time.hpp:139
virtual ~Scheme()
Destructor.
Definition: Time.hpp:62
void SetGround(Body *obj)
Set the ground body.
Definition: Time.hpp:67
std::string GetName() const
Get the name of the scheme.
Definition: Time.hpp:204
void SetCFL(const real &cfl)
Set the CFL factor.
Definition: Time.hpp:229
virtual void Init()=0
Create an initial state for all the entities.
virtual unsigned int RemoveRod(Rod *obj)
Remove a rod.
Definition: Time.hpp:155
virtual unsigned int RemovePoint(Point *obj)
Remove a point.
Definition: Time.hpp:122
virtual void LoadState(const std::string filepath, unsigned int i=0)
Load the system state from a file.
Definition: Time.hpp:286
real GetCFL() const
Get the CFL factor.
Definition: Time.hpp:224
Body * ground
The ground body.
Definition: Time.hpp:303
A stationary solution.
Definition: Time.hpp:865
~StationaryScheme()
Destructor.
Definition: Time.hpp:874
StationaryScheme(moordyn::Log *log, WavesRef waves)
Constructor.
Definition: Time.cpp:151
real Error() const
Get the error computed at the last time step.
Definition: Time.hpp:886
void Step(real &dt)
Run a time step.
Definition: Time.cpp:176
size_t NStates() const
Compute the number of state variables.
Definition: Time.hpp:897
MoorDyn2 C++ API namespace.
Definition: Body.cpp:27
std::shared_ptr< Waves > WavesRef
Definition: Body.hpp:53
double real
Real numbers wrapper. It is either double or float.
Definition: Misc.hpp:118
A mask to determine which entities shall be computed.
Definition: Time.hpp:843
std::vector< bool > lines
The lines mask.
Definition: Time.hpp:845
std::vector< bool > rods
The rods mask.
Definition: Time.hpp:849
std::vector< bool > bodies
The bodies mask.
Definition: Time.hpp:851
std::vector< bool > points
The points mask.
Definition: Time.hpp:847