VM2D  1.12
Vortex methods for 2D flows simulation
Mechanics2DRigidOscillPart.cpp
Go to the documentation of this file.
1 /*--------------------------------*- VM2D -*-----------------*---------------*\
2 | ## ## ## ## #### ##### | | Version 1.12 |
3 | ## ## ### ### ## ## ## ## | VM2D: Vortex Method | 2024/01/14 |
4 | ## ## ## # ## ## ## ## | for 2D Flow Simulation *----------------*
5 | #### ## ## ## ## ## | Open Source Code |
6 | ## ## ## ###### ##### | https://www.github.com/vortexmethods/VM2D |
7 | |
8 | Copyright (C) 2017-2024 I. Marchevsky, K. Sokol, E. Ryatina, A. Kolganova |
9 *-----------------------------------------------------------------------------*
10 | File name: Mechanics2DRigidOscillPart.cpp |
11 | Info: Source code of VM2D |
12 | |
13 | This file is part of VM2D. |
14 | VM2D is free software: you can redistribute it and/or modify it |
15 | under the terms of the GNU General Public License as published by |
16 | the Free Software Foundation, either version 3 of the License, or |
17 | (at your option) any later version. |
18 | |
19 | VM2D is distributed in the hope that it will be useful, but WITHOUT |
20 | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
21 | FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
22 | for more details. |
23 | |
24 | You should have received a copy of the GNU General Public License |
25 | along with VM2D. If not, see <http://www.gnu.org/licenses/>. |
26 \*---------------------------------------------------------------------------*/
27 
28 
41 
42 #include "Airfoil2D.h"
43 #include "Boundary2D.h"
44 #include "MeasureVP2D.h"
45 #include "Passport2D.h"
46 #include "StreamParser.h"
47 #include "Velocity2D.h"
48 #include "Wake2D.h"
49 #include "World2D.h"
50 
51 using namespace VM2D;
52 
53 MechanicsRigidOscillPart::MechanicsRigidOscillPart(const World2D& W_, size_t numberInPassport_)
54  :
55  Mechanics(W_, numberInPassport_, 0, true, false, false),
56  Vx0(0.0),
57  Vy0(0.0),
58  x0(W_.getAirfoil(numberInPassport_).rcm[0]),
59  y0(W_.getAirfoil(numberInPassport_).rcm[1])
60  //bx(0.0 * 0.731),
61  //by(0.0 * 0.731)
62 {
63  Vx = Vx0;
64  Vy = Vy0;
65 
66  x = x0;
67  y = y0;
68 
69  VxOld = Vx0;
70  VyOld = Vy0;
71 
72  xOld = x0;
73  yOld = y0;
74 
76  Initialize({ 0.0, 0.0 }, W_.getAirfoil(numberInPassport_).rcm, 0.0, W_.getAirfoil(numberInPassport_).phiAfl);
77 };
78 
79 //Вычисление гидродинамической силы, действующей на профиль
81 {
82  W.getTimestat().timeGetHydroDynamForce.first += omp_get_wtime();
83 
84  const double& dt = W.getPassport().timeDiscretizationProperties.dt;
85 
86  hydroDynamForce = { 0.0, 0.0 };
87  hydroDynamMoment = 0.0;
88 
89  viscousForce = { 0.0, 0.0 };
90  viscousMoment = 0.0;
91 
92  Point2D hDFGam = { 0.0, 0.0 }; //гидродинамические силы, обусловленные Gamma_k
93  Point2D hDFdelta = { 0.0, 0.0 }; //гидродинамические силы, обусловленные delta_k
94  double hDMdelta = 0.0;
95 
96 
97  Point2D deltaVstep;
98  if (W.getPassport().airfoilParams[numberInPassport].addedMass.length2() > 0)
99  deltaVstep = { 0.0, 0.0 }; //Для итерационной процедуры
100  else
101  deltaVstep = { Vx - VxOld, Vy - VyOld }; //Для безытерационной процедуры
102 
103  for (size_t i = 0; i < afl.getNumberOfPanels(); ++i)
104  {
106  double deltaK = boundary.sheets.freeVortexSheet(i, 0) * afl.len[i] - afl.gammaThrough[i] + (deltaVstep & afl.tau[i]) * afl.len[i];
107  Point2D rK = 0.5 * (afl.getR(i + 1) + afl.getR(i)) - afl.rcm;
108 
109  hDFdelta += deltaK * Point2D({ -rK[1], rK[0] });
110  hDMdelta += 0.5 * deltaK * rK.length2();
111  }
112 
113  const double rho = W.getPassport().physicalProperties.rho;
114 
115  hydroDynamForce = (rho / dt) * hDFdelta;
116  hydroDynamMoment = (rho / dt) * hDMdelta;
117 
118  if ((W.getPassport().physicalProperties.nu > 0.0)/* && (W.currentStep > 0)*/)
119  for (size_t i = 0; i < afl.getNumberOfPanels(); ++i)
120  {
121  Point2D rK = 0.5 * (afl.getR(i + 1) + afl.getR(i)) - afl.rcm;
122  viscousForce += rho * afl.viscousStress[i] * afl.tau[i];
123  viscousMoment += rho * (afl.viscousStress[i] * afl.tau[i]) & rK;
124  }
125 
126  W.getTimestat().timeGetHydroDynamForce.second += omp_get_wtime();
127 }// GetHydroDynamForce()
128 
129 // Вычисление скорости центра масс
131 {
132  return { Vx, Vy};
133  //return{ 0.0, 0.0 };
134 }//VeloOfAirfoilRcm(...)
135 
136 // Вычисление положения центра масс
138 {
139  return{ x, y };
140  //return{ 0.0, 0.0 };
141 }//PositionOfAirfoilRcm(...)
142 
144 {
145  return 0.0;
146 }//AngularVelocityOfAirfoil(...)
147 
149 {
150  return afl.phiAfl;
151 }//AngleOfAirfoil(...)
152 
153 // Вычисление скоростей начал панелей
155 {
156  Point2D veloRcm = VeloOfAirfoilRcm(currTime);
157  afl.setV(veloRcm);
158 }//VeloOfAirfoilPanels(...)
159 
160 
162 {
163  Point2D meff;
164  if (W.getPassport().airfoilParams[numberInPassport].addedMass.length2() > 0)
165  meff = Point2D{ m + W.getPassport().airfoilParams[numberInPassport].addedMass[0], m + W.getPassport().airfoilParams[numberInPassport].addedMass[1] };
166  else
167  meff = Point2D{ m, m };
168 
169  VxOld = Vx;
170  VyOld = Vy;
171 
172  xOld = x;
173  yOld = y;
174 
175  double dx, dVx, dy, dVy;
176 
177  //W.getInfo('t') << "k = " << k << std::endl;
178 
179 
180  if (ky > 0)
181  {
183  numvector<double, 2> kk[4];
184  kk[0] = { Vy, (hydroDynamForce[1] - 2.0 * by * Vy - ky * y) / meff[1]};
185  kk[1] = { Vy + 0.5 * dt * kk[0][1], (hydroDynamForce[1] - 2.0 * by * (Vy + 0.5 * dt * kk[0][1]) - ky * (y + 0.5 * dt * kk[0][0])) / meff[1]};
186  kk[2] = { Vy + 0.5 * dt * kk[1][1], (hydroDynamForce[1] - 2.0 * by * (Vy + 0.5 * dt * kk[1][1]) - ky * (y + 0.5 * dt * kk[1][0])) / meff[1
187  ]};
188  kk[3] = { Vy + dt * kk[2][1], (hydroDynamForce[1] - 2.0 * by * (Vy + dt * kk[2][1]) - ky * (y + dt * kk[2][0])) / meff[1]};
189 
190  dy = dt * (kk[0][0] + 2. * kk[1][0] + 2. * kk[2][0] + kk[3][0]) / 6.0;
191  dVy = dt * (kk[0][1] + 2. * kk[1][1] + 2. * kk[2][1] + kk[3][1]) / 6.0;
192  }
193  else
194  {
195  dy = 0.0;
196  dVy = 0.0;
197  }
198 
199 
200  if (kx > 0)
201  {
203  numvector<double, 2> kk[4];
204  kk[0] = { Vx, (hydroDynamForce[0] - 2.0 * bx * Vx - kx * x) / meff[0]};
205  kk[1] = { Vx + 0.5 * dt * kk[0][1], (hydroDynamForce[0] - 2.0 * bx * (Vx + 0.5 * dt * kk[0][1]) - kx * (x + 0.5 * dt * kk[0][0])) / meff[0]};
206  kk[2] = { Vx + 0.5 * dt * kk[1][1], (hydroDynamForce[0] - 2.0 * bx * (Vx + 0.5 * dt * kk[1][1]) - kx * (x + 0.5 * dt * kk[1][0])) / meff[0]};
207  kk[3] = { Vx + dt * kk[2][1], (hydroDynamForce[0] - 2.0 * bx * (Vx + dt * kk[2][1]) - kx * (x + dt * kk[2][0])) / meff[0]};
208 
209  dx = dt * (kk[0][0] + 2. * kk[1][0] + 2. * kk[2][0] + kk[3][0]) / 6.0;
210  dVx = dt * (kk[0][1] + 2. * kk[1][1] + 2. * kk[2][1] + kk[3][1]) / 6.0;
211  }
212  else
213  {
214  dx = 0.0;
215  dVx = 0.0;
216  }
217 
218  afl.Move({ dx, dy });
219  Vcm[0] += dVx;
220  Vcm[1] += dVy;
221 
222  x += dx;
223  y += dy;
224 
225  Vx += dVx;
226  Vy += dVy;
227 
228 }//Move()
229 
231 {
232  Point2D meff;
233  if (W.getPassport().airfoilParams[numberInPassport].addedMass.length2() > 0)
234  //#ifdef addm
235  meff = Point2D{ m + W.getPassport().airfoilParams[numberInPassport].addedMass[0], m + W.getPassport().airfoilParams[numberInPassport].addedMass[1] };
236  //#else
237  else
238  meff = Point2D{ m, m };
239  //double meff = m;
240  //#endif
241 
242 
243 
244  VxOld = Vx;
245  VyOld = Vy;
246 
247  xOld = x;
248  yOld = y;
249 
250  double dx, dVx, dy, dVy;
251 
252  //W.getInfo('t') << "k = " << k << std::endl;
253 
254 
255  if (ky > 0)
256  {
258  numvector<double, 2> kk[4];
259  kk[0] = { Vy, (hydroDynamForce[1] - 2.0 * by * Vy - ky * y) / meff[1]};
260  kk[1] = { Vy + 0.5 * dt * kk[0][1], (hydroDynamForce[1] - 2.0 * by * (Vy + 0.5 * dt * kk[0][1]) - ky * (y + 0.5 * dt * kk[0][0])) / meff[1]};
261  kk[2] = { Vy + 0.5 * dt * kk[1][1], (hydroDynamForce[1] - 2.0 * by * (Vy + 0.5 * dt * kk[1][1]) - ky * (y + 0.5 * dt * kk[1][0])) / meff[1]};
262  kk[3] = { Vy + dt * kk[2][1], (hydroDynamForce[1] - 2.0 * by * (Vy + dt * kk[2][1]) - ky * (y + dt * kk[2][0])) / meff[1]};
263 
264  dy = dt * (kk[0][0] + 2. * kk[1][0] + 2. * kk[2][0] + kk[3][0]) / 6.0;
265  dVy = dt * (kk[0][1] + 2. * kk[1][1] + 2. * kk[2][1] + kk[3][1]) / 6.0;
266  }
267  else
268  {
269  dy = 0.0;
270  dVy = 0.0;
271  }
272 
273 
274  if (kx > 0)
275  {
277  numvector<double, 2> kk[4];
278  kk[0] = { Vx, (hydroDynamForce[0] - 2.0 * bx * Vx - kx * x) / meff[0]};
279  kk[1] = { Vx + 0.5 * dt * kk[0][1], (hydroDynamForce[0] - 2.0 * bx * (Vx + 0.5 * dt * kk[0][1]) - kx * (x + 0.5 * dt * kk[0][0])) / meff[0]};
280  kk[2] = { Vx + 0.5 * dt * kk[1][1], (hydroDynamForce[0] - 2.0 * bx * (Vx + 0.5 * dt * kk[1][1]) - kx * (x + 0.5 * dt * kk[1][0])) / meff[0]};
281  kk[3] = { Vx + dt * kk[2][1], (hydroDynamForce[0] - 2.0 * bx * (Vx + dt * kk[2][1]) - kx * (x + dt * kk[2][0])) / meff[0]};
282 
283  dx = dt * (kk[0][0] + 2. * kk[1][0] + 2. * kk[2][0] + kk[3][0]) / 6.0;
284  dVx = dt * (kk[0][1] + 2. * kk[1][1] + 2. * kk[2][1] + kk[3][1]) / 6.0;
285  }
286  else
287  {
288  dx = 0.0;
289  dVx = 0.0;
290  }
291 
292  //afl.Move({ dx, dy });
293  Vcm[0] += dVx;
294  Vcm[1] += dVy;
295 
296  //x += dx;
297  //y += dy;
298 
299  Vx += dVx;
300  Vy += dVy;
301 
302 }//Move()
303 
304 
305 /*
306 void MechanicsRigidOscillPart::RecalcU(Point2D forcePrev) //ИК
307 {
308  double dx, dVx, dy, dVy;
309 
310 #ifdef addm
311  double meff = m;// +W.getPassport().physicalProperties.rho * PI * 0.5 * 0.5;
312 #else
313  double meff = m;
314 #endif
315 
316  //W.getInfo('t') << "k = " << k << std::endl;
317 
318  Point2D force = 1.0 * forcePrev;// +0.5 * Qiter;
319 
320  if (ky > 0)
321  {
322  double dt = W.getPassport().timeDiscretizationProperties.dt;
323  numvector<double, 2> kk[4];
324  kk[0] = { Vy, (force[1] - 2.0*by * Vy - ky * y) / meff };
325  kk[1] = { Vy + 0.5 * dt * kk[0][1], (force[1] - 2.0 * by * (Vy + 0.5 * dt * kk[0][1]) - ky * (y + 0.5 * dt * kk[0][0])) / meff };
326  kk[2] = { Vy + 0.5 * dt * kk[1][1], (force[1] - 2.0 * by * (Vy + 0.5 * dt * kk[1][1]) - ky * (y + 0.5 * dt * kk[1][0])) / meff };
327  kk[3] = { Vy + dt * kk[2][1], (force[1] - 2.0 * by * (Vy + dt * kk[2][1]) - ky * (y + dt * kk[2][0])) / meff };
328 
329  dy = dt * (kk[0][0] + 2. * kk[1][0] + 2. * kk[2][0] + kk[3][0]) / 6.0;
330  dVy = dt * (kk[0][1] + 2. * kk[1][1] + 2. * kk[2][1] + kk[3][1]) / 6.0;
331  }
332  else
333  {
334  dy = 0.0;
335  dVy = 0.0;
336  }
337 
338 
339  if (kx > 0)
340  {
341  double dt = W.getPassport().timeDiscretizationProperties.dt;
342  numvector<double, 2> kk[4];
343  kk[0] = { Vx, (force[0] - 2.0 * bx * Vx - kx * x) / meff };
344  kk[1] = { Vx + 0.5 * dt * kk[0][1], (force[0] - 2.0 * bx * (Vx + 0.5 * dt * kk[0][1]) - kx * (x + 0.5 * dt * kk[0][0])) / meff };
345  kk[2] = { Vx + 0.5 * dt * kk[1][1], (force[0] - 2.0 * bx * (Vx + 0.5 * dt * kk[1][1]) - kx * (x + 0.5 * dt * kk[1][0])) / meff };
346  kk[3] = { Vx + dt * kk[2][1], (force[0] - 2.0 * bx * (Vx + dt * kk[2][1]) - kx * (x + dt * kk[2][0])) / meff };
347 
348  dx = dt * (kk[0][0] + 2. * kk[1][0] + 2. * kk[2][0] + kk[3][0]) / 6.0;
349  dVx = dt * (kk[0][1] + 2. * kk[1][1] + 2. * kk[2][1] + kk[3][1]) / 6.0;
350  }
351  else
352  {
353  dx = 0.0;
354  dVx = 0.0;
355  }
356 
357 
358 
359  //afl.Move({ 0.0, dy });
360  //Vcm[1] += du;
361 
362  //y += dy;
363  Vx = VxIter + 0.5 * dVx;
364  Vy = VyIter + 0.5 * dVy;
365 }//RecalcU()
366 */
367 
368 
369 #ifdef BRIDGE
371 {
372  mechParamsParser->get("m", m);
373 
374  W.getInfo('i') << "mass " << "m = " << m << std::endl;
375 
376  mechParamsParser->get("b", b);
377 
378  W.getInfo('i') << "damping " << "b = " << b << std::endl;
379 
380 
381  mechParamsParser->get("k", k);
382 
383 // std::vector<double> sh;
384 // mechParamsParser->get("sh", sh);
385 
386 // k = m * 4.0 * PI * PI * sh[1] * sh[1] * W.getPassport().physicalProperties.vInf.length2();
387 
388  W.getInfo('i') << "rigidity k = " << k << std::endl;
389 }//ReadSpecificParametersFromDictionary()
390 #endif
391 
392 //template <typename T>
393 //inline T sqr(T x)
394 //{ return x * x; }
395 
396 #ifdef INITIAL
398 {
399  mechParamsParser->get("m", m);
400 
401  W.getInfo('i') << "mass " << "m = " << m << std::endl;
402 
403  std::vector<double> sh;
404  mechParamsParser->get("sh", sh);
405  mechParamsParser->get("sh", sh);
406 
407 
408 
411 
412  W.getInfo('i') << "rigidity kx = " << kx << std::endl;
413  W.getInfo('i') << "rigidity ky = " << ky << std::endl;
414 
415  std::vector<double> zeta;
416  mechParamsParser->get("zeta", zeta);//Логарифмический декремент
417 
418  bx = zeta[0] / (2.0 * PI) * sqrt(kx * m);
419  by = zeta[1] / (2.0 * PI) * sqrt(ky * m);
420 
421  W.getInfo('i') << "damping bx = " << bx << std::endl;
422  W.getInfo('i') << "damping by = " << by << std::endl;
423 
424 
425 }//ReadSpecificParametersFromDictionary()
426 #endif
const double & freeVortexSheet(size_t n, size_t moment) const
Definition: Sheet2D.h:99
Point2D viscousForce
Вектор силы и момент вязкого трения, действующие на профиль
Definition: Mechanics2D.h:146
Заголовочный файл с описанием класса Passport (двумерный) и cоответствующими структурами ...
std::vector< double > viscousStress
Касательные напряжения на панелях профиля
Definition: Airfoil2D.h:188
Times & getTimestat() const
Возврат ссылки на временную статистику выполнения шага расчета по времени
Definition: World2D.h:242
void Initialize(Point2D Vcm0_, Point2D Rcm0_, double Wcm0_, double Phi0_)
Задание начального положения и начальной скорости
Definition: Mechanics2D.cpp:89
virtual void GetHydroDynamForce() override
Вычисление гидродинамической силы, действующей на профиль
Шаблонный класс, определяющий вектор фиксированной длины Фактически представляет собой массив...
Definition: numvector.h:95
const double PI
Число .
Definition: defs.h:73
Заголовочный файл с описанием класса Wake.
const Boundary & boundary
Definition: Mechanics2D.h:91
Заголовочный файл с описанием класса World2D.
double kx
параметр жесткости механической системы
double bx
параметр демпфирования механической системы
MechanicsRigidOscillPart(const World2D &W_, size_t numberInPassport_)
Конструктор
double hydroDynamMoment
Definition: Mechanics2D.h:143
Заголовочный файл с описанием класса Airfoil.
double xOld
отклонение профиля с предыдущего шага
const double x0
начальное отклонение профиля
std::vector< double > gammaThrough
Суммарные циркуляции вихрей, пересекших панели профиля на прошлом шаге
Definition: Airfoil2D.h:196
double x
текущее отклонение профиля
double nu
Коэффициент кинематической вязкости среды
Definition: Passport2D.h:96
PhysicalProperties physicalProperties
Структура с физическими свойствами задачи
Definition: Passport2D.h:296
const Point2D & getR(size_t q) const
Возврат константной ссылки на вершину профиля
Definition: Airfoil2D.h:101
const double Vx0
начальная скорость профиля
size_t getNumberOfPanels() const
Возврат количества панелей на профиле
Definition: Airfoil2D.h:139
auto length2() const -> typename std::remove_const< typename std::remove_reference< decltype(this->data[0])>::type >::type
Вычисление квадрата нормы (длины) вектора
Definition: numvector.h:383
double dt
Шаг по времени
Definition: PassportGen.h:65
double VxOld
скорость профиля с предыдущего шага
const size_t numberInPassport
Номер профиля в паспорте
Definition: Mechanics2D.h:82
T sqr(T x)
Возведение числа в квадрат
Definition: defs.h:430
TimeDiscretizationProperties timeDiscretizationProperties
Структура с параметрами процесса интегрирования по времени
Definition: PassportGen.h:127
Заголовочный файл с описанием класса MechanicsRigidOscillPart.
Point2D vInf
Скоростью набегающего потока
Definition: Passport2D.h:78
timePeriod timeGetHydroDynamForce
Начало и конец процесса вычисления нагрузок
Definition: Times2D.h:92
double rho
Плотность потока
Definition: Passport2D.h:75
Definition: Airfoil2D.h:45
Заголовочный файл с описанием класса StreamParser.
Airfoil & afl
Definition: Mechanics2D.h:87
Класс, опеделяющий двумерный вектор
Definition: Point2D.h:75
std::vector< Point2D > tau
Касательные к панелям профиля
Definition: Airfoil2D.h:182
std::unique_ptr< VMlib::StreamParser > mechParamsParser
Умный указатель на парсер параметров механической системы
Definition: Mechanics2D.h:98
VMlib::LogStream & getInfo() const
Возврат ссылки на объект LogStream Используется в техничеcких целях для организации вывода ...
Definition: WorldGen.h:74
Sheet sheets
Слои на профиле
Definition: Boundary2D.h:95
virtual Point2D PositionOfAirfoilRcm(double currTime) override
Вычисление положения центра масс профиля
Заголовочный файл с описанием класса MeasureVP.
double phiAfl
Поворот профиля
Definition: Airfoil2D.h:80
const World2D & W
Константная ссылка на решаемую задачу
Definition: Mechanics2D.h:79
const Passport & getPassport() const
Возврат константной ссылки на паспорт
Definition: World2D.h:222
virtual double AngleOfAirfoil(double currTime) override
Вычисление угла поворота профиля
Point2D rcm
Положение центра масс профиля
Definition: Airfoil2D.h:77
void setV(const Point2D &vel)
Установка постоянной скорости всех вершин профиля
Definition: Airfoil2D.h:121
double Vx
текущая скорость профиля
double viscousMoment
Definition: Mechanics2D.h:147
virtual Point2D VeloOfAirfoilRcm(double currTime) override
Вычисление скорости центра масс профиля
const Airfoil & getAirfoil(size_t i) const
Возврат константной ссылки на объект профиля
Definition: World2D.h:130
Класс, опеделяющий текущую решаемую задачу
Definition: World2D.h:68
std::vector< AirfoilParams > airfoilParams
Список структур с параметрами профилей
Definition: Passport2D.h:280
std::vector< double > len
Длины панелей профиля
Definition: Airfoil2D.h:185
virtual void VeloOfAirfoilPanels(double currTime) override
Вычисление скоростей начал панелей
Заголовочный файл с описанием класса Velocity.
virtual double AngularVelocityOfAirfoil(double currTime) override
Вычисление угловой скорости профиля
double m
масса профиля
Point2D hydroDynamForce
Вектор гидродинамической силы и момент, действующие на профиль
Definition: Mechanics2D.h:142
virtual void ReadSpecificParametersFromDictionary() override
Чтение параметров конкретной механической системы
virtual void Move(const Point2D &dr)=0
Перемещение профиля
Заголовочный файл с описанием класса Boundary.
virtual void Move() override
Перемещение профиля в соответствии с законом
Абстрактный класс, определяющий вид механической системы
Definition: Mechanics2D.h:71