x1500.h
Go to the documentation of this file.
1 #pragma once
2 
3 #include "xode.h"
4 #include "xmath.h"
5 #include "xmodel.h"
6 #include "xphysics.h"
7 #include <array>
8 
9 namespace nmx::apps::x1500 {
10 
14 enum class Damping {
15  over = 0, //starke Dämpfung (0)
16  critical = 1, //aperiodischer Grenzfall (1)
17  under = 2 //schwache Dämpfung (2)
18 };
19 
24 class X1500 : public XModel
25 {
26 public:
27  using IValues = std::array<double, 2>;
28 
29  const double mass, k;
30  const double omega0, period0, frequency0;
31  const double beta, gamma;
32  const double x0, v0;
33 
34 public:
42  inline X1500(double mass, double k, double beta, IValues initc)
43  : XModel{ __func__ }
44  , mass{ mass }
45  , k{ k }
46  , omega0{ sqrt(k / mass) }
47  , period0(2 * Math::PI / omega0)
48  , frequency0(1 / period0)
49  , beta{ beta }
50  , gamma{ 0.5 * beta / mass }
51  , x0{ initc[0] }
52  , v0{ initc[1] } {}
53 
59  inline double expfactor(double t) const { return exp(-gamma * t); }
60 
67  inline double acceleration(double x, double v) const {
68  return -2 * gamma * v - pow(omega0, 2) * x;
69  }
70 
75  inline Damping type() const { return type(gamma, omega0); }
76 
83  inline static Damping type(double gm, double omg0) {
84  double gamma2 = pow(gm, 2);
85  double omega02 = pow(omg0, 2);
86  Damping result;
87  // entscheide über den Typ der gedämpften Schwingung
88  if (gamma2 > omega02) {
89  result = Damping::over;
90  } else if (std::abs(gamma2 - omega02) < 1e-6) {
91  result = Damping::critical;
92  } else {
93  result = Damping::under;
94  }
95 
96  return result;
97  }
98 }; //X1500
99 
104 class Overdamped : public X1500
105 {
106 private:
107  double _omega = 0;
108 
109 public:
117  inline Overdamped(double mass, double k, double beta, IValues initc)
118  : X1500{ mass, k, beta, initc } {
120  _omega = sqrt(pow(gamma, 2) - pow(omega0, 2));
121  }
122 
128  inline double x(double t) const {
129  const double phs = omega() * t;
130  const double fac = (x0 / omega());
131  const double trm0 = (omega() * cosh(phs) + gamma * sinh(phs));
132  const double term = fac * trm0;
133  return expfactor(t) * term;
134  }
135 
141  inline double v(double t) const {
142  const double phase = omega() * t;
143  const double trm0 = (x0 / omega()) * sinh(phase);
144  return -pow(omega0, 2) * expfactor(t) * trm0;
145  }
146 
151  inline double omega() const { return _omega; }
152 }; //Overdamped
153 
157 class Critical : public X1500
158 {
159 public:
167  inline Critical(double mass, double k, double beta, IValues initc)
168  : X1500{ mass, k, beta, initc } {
170  }
171 
177  inline double x(double t) const { //
178  return x0 * expfactor(t) * (1 + gamma * t);
179  }
180 
186  inline double v(double t) const { //
187  return -x0 * t * expfactor(t) * pow(gamma, 2);
188  }
189 }; //Critical
190 
194 class Underdamped : public X1500
195 {
196 private:
197  double _phi0, _C, _omega;
198 
199 public:
207  inline Underdamped(double mass, double k, double beta, IValues initc)
208  : X1500{ mass, k, beta, initc } {
210  _omega = sqrt(pow(omega0, 2) - pow(gamma, 2));
211  _phi0 = atan2(omega(), gamma);
212  _C = omega0 * x0 / _omega;
213  }
219  inline double x(double t) const { //
220  return _C * expfactor(t) * sin(omega() * t + _phi0);
221  }
222 
228  inline double v(double t) const {
229  const double phase = omega() * t + _phi0;
230  const double part1 = -gamma * x(t);
231  const double part2 = _C * expfactor(t) * omega() * cos(phase);
232  return part1 + part2;
233  }
234 
239  inline double omega() const { return _omega; }
240 }; //Underdamped
241 
246 class C1500 : public X1500
247 {
248 public:
250  friend Ode;
251  using Data = Data<6>;
252 
253  using X1500::X1500;
254 
255 private:
256  Data _data;
257 
258 public:
266  inline int odefn(double t, const double fin[], double fout[]) {
267  (void) t;
268  fout[0] = fin[1];
269  fout[1] = acceleration(fin[0], fin[1]);
270  return GSL_SUCCESS;
271  }
272 
276  void solve_ode() {
277  Ode ode{ *this, 1e-2, 1e-9, 0 };
278  ode.set_init_conditions(0, { x0, v0 });
279  double t = 0, tmax = 2 * period0, dt = tmax / 100; //Schrittweite
280  while (t < tmax) {
281  _data += { t, ode[0], ode[1] };
282  t += dt;
283  ode.solve(t);
284  }
285  }
286 
290  inline void exec() {
291  //Lösung der Bewegungsgleichung
292  solve_ode();
293  //Hinzufügen der Gesamtenergie
294  for (auto &crow : _data.data()) {
295  const double ekin = Mechanics::kinetic_energy(mass, crow[2]);
296  const double epot = 0.5 * k * pow(crow[1], 2);
297  crow[3] = ekin + epot;
298  }
299  // exakte Werte von x und v
300  auto exactFn = [this](auto cobj) {
301  for (auto &crow : _data.data()) {
302  const double t = crow[0];
303  crow[4] = cobj.x(t);
304  crow[5] = cobj.v(t);
305  }
306  };
307  //rufe das zuständige Rechenmodell auf
308  if (type() == Damping::over) {
309  exactFn(Overdamped(mass, k, beta, { x0, v0 }));
310  } else if (type() == Damping::under) {
311  exactFn(Underdamped(mass, k, beta, { x0, v0 }));
312  } else if (type() == Damping::critical) {
313  exactFn(Critical(mass, k, beta, { x0, v0 }));
314  }
315  }
316 
320  void save_data() {
321  save(_data, Output::plot, static_cast<int>(type()));
322  save(_data.select_total_rows(6), //
324  static_cast<int>(type()));
325  }
326 }; //C1500
327 
331 inline void run() {
332  //gemeinsame Programmparameter
333  const double mass = 1.0;
334  const double x0 = 30.0_mm;
335  const double v0 = 0.0;
336 
337  //starke Dämpfung
338  double beta = 15;
339  double k = 9.0;
340  C1500 cobj0{ mass, k, beta, { x0, v0 } };
341  cobj0.exec();
342  cobj0.save_data();
343 
344  //schwache Dämpfung
345  beta = 1;
346  k = 36.0;
347  C1500 cobj1{ mass, k, beta, { x0, v0 } };
348  cobj1.exec();
349  cobj1.save_data();
350 
351  //aperiodischer Grenzfall
352  beta = 6;
353  k = 9.0;
354  C1500 cobj2{ mass, k, beta, { x0, v0 } };
355  cobj2.exec();
356  cobj2.save_data();
357 }
358 
359 } // namespace nmx::apps::x1500
Underdamped(double mass, double k, double beta, IValues initc)
Underdamped Konstruktor.
Definition: x1500.h:207
double acceleration(double x, double v) const
acceleration
Definition: x1500.h:67
static double kinetic_energy(double mass, double velocity)
kinetic_energy Hilfsfunktion
Definition: xphysics.h:38
Damping
The Damping enum Mögliche Schwingungstypen.
Definition: x1500.h:14
void set_init_conditions(double t, const Array &y)
set_init_conditions lege Anfangsbedingungen fest
Definition: xode.h:133
Damping type() const
type Berechnung des Dämpfungstyps
Definition: x1500.h:75
The X1500 class Harmonische Schwingungen mit Dämpfung (Modellklasse)
Definition: x1500.h:24
X1500(double mass, double k, double beta, IValues initc)
X1500 Konstruktor.
Definition: x1500.h:42
const double mass
Definition: x1500.h:29
double x(double t) const
x Ort als Funktion der Zeit
Definition: x1500.h:177
The Odeiv2 class numerische Lösung eines Systems von N Differenzialgleichungen Schnittstelle zur gsl...
Definition: xode.h:20
static Damping type(double gm, double omg0)
type Hilfsfunktion zur Ermittlung des Dämpfungstyps
Definition: x1500.h:83
The XModel class Basisklasse speichert eine ID in Form einer Zeichenkette enthält Hilfsfunktionen zur...
Definition: xmodel.h:22
#define nmx_msg
Definition: xerror.h:113
std::array< double, 2 > IValues
Definition: x1500.h:27
static void error_if_not(const std::string &s, bool arg)
error_if_not Fehler wenn Bedingung nicht erfüllt ist
Definition: xerror.h:63
double v(double t) const
v Geschwindigkeit als Funktion der Zeit
Definition: x1500.h:228
double x(double t) const
x Ort als Funktion der Zeit
Definition: x1500.h:219
const double period0
Definition: x1500.h:30
int odefn(double t, const double fin[], double fout[])
odefn Transformation in ein System von linearen Dgl
Definition: x1500.h:266
const double gamma
Definition: x1500.h:31
double expfactor(double t) const
expfactor Hilfsfunktion
Definition: x1500.h:59
double x(double t) const
x Ort als Funktion der Zeit
Definition: x1500.h:128
double omega() const
omega Kreisfrequenz
Definition: x1500.h:151
void exec()
exec numerische Berechnung der Daten
Definition: x1500.h:290
void solve_ode()
solve_ode numerische Lösung der Bewegungsgleichung
Definition: x1500.h:276
Overdamped(double mass, double k, double beta, IValues initc)
Overdamped Konstruktor.
Definition: x1500.h:117
double v(double t) const
v Geschwindigkeit als Funktion der Zeit
Definition: x1500.h:141
void run()
run Berechnung von Beispieldaten
Definition: x1500.h:331
The Critical class Aperiodischer Grenzfall (Rechenmodell)
Definition: x1500.h:157
double v(double t) const
v Geschwindigkeit als Funktion der Zeit
Definition: x1500.h:186
const double x0
Definition: x1500.h:32
The Underdamped class Schwache Dämpfung (Rechenmodell)
Definition: x1500.h:194
double fac(size_t n)
fac Berechnung von n! exakt oder mit einer Näherungsformel
Definition: x014.h:65
The X1500 class Harmonische Schwingungen mit Dämpfung.
Definition: x1500.h:246
void save_data()
save_data Ausgabe der Daten im Tabellen und Grafikformat
Definition: x1500.h:320
static constexpr double PI
Definition: xmath.h:11
static const Format latex
Definition: xoutput.h:17
The Overdamped class starke Dämpfung (Rechenmodell)
Definition: x1500.h:104
static const Format plot
Definition: xoutput.h:18
double omega() const
omega
Definition: x1500.h:239
Critical(double mass, double k, double beta, IValues initc)
Critical Konstruktor.
Definition: x1500.h:167