Nektar++
Static Public Member Functions | Static Public Attributes | Protected Member Functions | Protected Attributes | Private Member Functions | Private Attributes | Friends | List of all members
Nektar::ForcingMovingBody Class Reference

#include <ForcingMovingBody.h>

Inheritance diagram for Nektar::ForcingMovingBody:
[legend]

Static Public Member Functions

static SolverUtils::ForcingSharedPtr create (const LibUtilities::SessionReaderSharedPtr &pSession, const std::weak_ptr< SolverUtils::EquationSystem > &pEquation, const Array< OneD, MultiRegions::ExpListSharedPtr > &pFields, const unsigned int &pNumForcingFields, const TiXmlElement *pForce)
 Creates an instance of this class. More...
 
- Static Public Member Functions inherited from Nektar::SolverUtils::Forcing
static SOLVER_UTILS_EXPORT std::vector< ForcingSharedPtrLoad (const LibUtilities::SessionReaderSharedPtr &pSession, const std::weak_ptr< EquationSystem > &pEquation, const Array< OneD, MultiRegions::ExpListSharedPtr > &pFields, const unsigned int &pNumForcingFields=0)
 

Static Public Attributes

static std::string className
 Name of the class. More...
 

Protected Member Functions

virtual void v_InitObject (const Array< OneD, MultiRegions::ExpListSharedPtr > &pFields, const unsigned int &pNumForcingFields, const TiXmlElement *pForce) override
 
virtual void v_Apply (const Array< OneD, MultiRegions::ExpListSharedPtr > &fields, const Array< OneD, Array< OneD, NekDouble >> &inarray, Array< OneD, Array< OneD, NekDouble >> &outarray, const NekDouble &time) override
 
- Protected Member Functions inherited from Nektar::SolverUtils::Forcing
SOLVER_UTILS_EXPORT Forcing (const LibUtilities::SessionReaderSharedPtr &pSession, const std::weak_ptr< EquationSystem > &pEquation)
 Constructor. More...
 
virtual SOLVER_UTILS_EXPORT void v_PreApply (const Array< OneD, MultiRegions::ExpListSharedPtr > &fields, const Array< OneD, Array< OneD, NekDouble >> &inarray, Array< OneD, Array< OneD, NekDouble >> &outarray, const NekDouble &time)
 
virtual SOLVER_UTILS_EXPORT void v_ApplyCoeff (const Array< OneD, MultiRegions::ExpListSharedPtr > &fields, const Array< OneD, Array< OneD, NekDouble >> &inarray, Array< OneD, Array< OneD, NekDouble >> &outarray, const NekDouble &time)
 
SOLVER_UTILS_EXPORT SessionFunctionSharedPtr GetFunction (const Array< OneD, MultiRegions::ExpListSharedPtr > &pFields, const LibUtilities::SessionReaderSharedPtr &pSession, std::string pName, bool pCache=false)
 Get a SessionFunction by name. More...
 
SOLVER_UTILS_EXPORT void EvaluateTimeFunction (LibUtilities::SessionReaderSharedPtr pSession, std::string pFieldName, Array< OneD, NekDouble > &pArray, const std::string &pFunctionName, NekDouble pTime=NekDouble(0))
 
SOLVER_UTILS_EXPORT void EvaluateTimeFunction (const NekDouble pTime, const LibUtilities::EquationSharedPtr &pEqn, Array< OneD, NekDouble > &pArray)
 

Protected Attributes

GlobalMapping::MappingSharedPtr m_mapping
 
- Protected Attributes inherited from Nektar::SolverUtils::Forcing
LibUtilities::SessionReaderSharedPtr m_session
 Session reader. More...
 
const std::weak_ptr< EquationSystemm_equ
 Weak pointer to equation system using this forcing. More...
 
Array< OneD, Array< OneD, NekDouble > > m_Forcing
 Evaluated forcing function. More...
 
int m_NumVariable
 Number of variables. More...
 
std::map< std::string, SolverUtils::SessionFunctionSharedPtrm_sessionFunctions
 Map of known SessionFunctions. More...
 

Private Member Functions

 ForcingMovingBody (const LibUtilities::SessionReaderSharedPtr &pSession, const std::weak_ptr< SolverUtils::EquationSystem > &pEquation)
 
void CheckIsFromFile (const TiXmlElement *pForce)
 
void InitialiseCableModel (const LibUtilities::SessionReaderSharedPtr &pSession, const Array< OneD, MultiRegions::ExpListSharedPtr > &pFields)
 
void InitialiseFilter (const LibUtilities::SessionReaderSharedPtr &pSession, const Array< OneD, MultiRegions::ExpListSharedPtr > &pFields, const TiXmlElement *pForce)
 
void Newmark_betaSolver (const Array< OneD, MultiRegions::ExpListSharedPtr > &pFields, Array< OneD, NekDouble > &FcePhysinArray, Array< OneD, NekDouble > &MotPhysinArray)
 
void EvaluateStructDynModel (const Array< OneD, MultiRegions::ExpListSharedPtr > &pFields, Array< OneD, NekDouble > &Hydroforces, NekDouble time)
 
void SetDynEqCoeffMatrix (const Array< OneD, MultiRegions::ExpListSharedPtr > &pFields)
 
void RollOver (Array< OneD, Array< OneD, NekDouble >> &input)
 

Private Attributes

size_t m_movingBodyCalls
 number of times the movbody have been called More...
 
size_t m_np
 number of planes per processors More...
 
size_t m_vdim
 vibration dimension More...
 
NekDouble m_structrho
 mass of the cable per unit length More...
 
NekDouble m_structdamp
 damping ratio of the cable More...
 
NekDouble m_lhom
 length ratio of the cable More...
 
NekDouble m_kinvis
 fluid viscous More...
 
NekDouble m_timestep
 time step More...
 
LibUtilities::NektarFFTSharedPtr m_FFT
 
FilterMovingBodySharedPtr m_MovBodyfilter
 
Array< OneD, NekDoublem_Aeroforces
 storage for the cable's force(x,y) variables More...
 
Array< OneD, Array< OneD, NekDouble > > m_MotionVars
 storage for the cable's motion(x,y) variables More...
 
Array< OneD, Array< OneD, Array< OneD, NekDouble > > > m_fV
 fictitious velocity storage More...
 
Array< OneD, Array< OneD, Array< OneD, NekDouble > > > m_fA
 fictitious acceleration storage More...
 
Array< OneD, DNekMatSharedPtrm_CoeffMat_A
 matrices in Newmart-beta method More...
 
Array< OneD, DNekMatSharedPtrm_CoeffMat_B
 matrices in Newmart-beta method More...
 
Array< OneD, std::string > m_funcName
 [0] is displacements, [1] is velocities, [2] is accelerations More...
 
Array< OneD, std::string > m_motion
 motion direction: [0] is 'x' and [1] is 'y' More...
 
Array< OneD, bool > m_IsFromFile
 do determine if the the body motion come from an extern file More...
 
Array< OneD, Array< OneD, NekDouble > > m_zta
 Store the derivatives of motion variables in x-direction. More...
 
Array< OneD, Array< OneD, NekDouble > > m_eta
 Store the derivatives of motion variables in y-direction. More...
 
unsigned int m_outputFrequency
 
Array< OneD, std::ofstream > m_outputStream
 
std::string m_outputFile_fce
 
std::string m_outputFile_mot
 

Friends

class MemoryManager< ForcingMovingBody >
 

Additional Inherited Members

- Public Member Functions inherited from Nektar::SolverUtils::Forcing
virtual SOLVER_UTILS_EXPORT ~Forcing ()
 
SOLVER_UTILS_EXPORT void InitObject (const Array< OneD, MultiRegions::ExpListSharedPtr > &pFields, const unsigned int &pNumForcingFields, const TiXmlElement *pForce)
 Initialise the forcing object. More...
 
SOLVER_UTILS_EXPORT void Apply (const Array< OneD, MultiRegions::ExpListSharedPtr > &fields, const Array< OneD, Array< OneD, NekDouble >> &inarray, Array< OneD, Array< OneD, NekDouble >> &outarray, const NekDouble &time)
 Apply the forcing. More...
 
SOLVER_UTILS_EXPORT void PreApply (const Array< OneD, MultiRegions::ExpListSharedPtr > &fields, const Array< OneD, Array< OneD, NekDouble >> &inarray, Array< OneD, Array< OneD, NekDouble >> &outarray, const NekDouble &time)
 Change the advection velocity before applying the forcing. For example, subtracting the frame velocity from the advection velocity in the MovingRefercenceFrame. More...
 
SOLVER_UTILS_EXPORT void ApplyCoeff (const Array< OneD, MultiRegions::ExpListSharedPtr > &fields, const Array< OneD, Array< OneD, NekDouble >> &inarray, Array< OneD, Array< OneD, NekDouble >> &outarray, const NekDouble &time)
 Apply the forcing. More...
 
SOLVER_UTILS_EXPORT const Array< OneD, const Array< OneD, NekDouble > > & GetForces ()
 
SOLVER_UTILS_EXPORT Array< OneD, Array< OneD, NekDouble > > & UpdateForces ()
 

Detailed Description

Definition at line 49 of file ForcingMovingBody.h.

Constructor & Destructor Documentation

◆ ForcingMovingBody()

Nektar::ForcingMovingBody::ForcingMovingBody ( const LibUtilities::SessionReaderSharedPtr pSession,
const std::weak_ptr< SolverUtils::EquationSystem > &  pEquation 
)
private

Definition at line 48 of file ForcingMovingBody.cpp.

51  : Forcing(pSession, pEquation)
52 {
53 }
SOLVER_UTILS_EXPORT Forcing(const LibUtilities::SessionReaderSharedPtr &pSession, const std::weak_ptr< EquationSystem > &pEquation)
Constructor.
Definition: Forcing.cpp:50

Member Function Documentation

◆ CheckIsFromFile()

void Nektar::ForcingMovingBody::CheckIsFromFile ( const TiXmlElement *  pForce)
private

Definition at line 1076 of file ForcingMovingBody.cpp.

1077 {
1078 
1079  m_funcName = Array<OneD, std::string>(3);
1080  m_motion = Array<OneD, std::string>(2);
1081  m_motion[0] = "x";
1082  m_motion[1] = "y";
1083 
1084  m_IsFromFile = Array<OneD, bool>(6);
1085  // Loading the x-dispalcement (m_zta) and the y-displacement (m_eta)
1086  // Those two variables are bith functions of z and t and the may come
1087  // from an equation (forced vibration) or from another solver which, given
1088  // the aerodynamic forces at the previous step, calculates the
1089  // displacements.
1090 
1091  // Get the body displacement: m_zta and m_eta
1092  const TiXmlElement *funcNameElmt_D =
1093  pForce->FirstChildElement("DISPLACEMENTS");
1094  ASSERTL0(funcNameElmt_D,
1095  "MOVINGBODYFORCE tag has to specify a function name which "
1096  "prescribes the body displacement as d(z,t).");
1097 
1098  m_funcName[0] = funcNameElmt_D->GetText();
1099  ASSERTL0(m_session->DefinesFunction(m_funcName[0]),
1100  "Function '" + m_funcName[0] + "' not defined.");
1101 
1102  // Get the body velocity of movement: d(m_zta)/dt and d(m_eta)/dt
1103  const TiXmlElement *funcNameElmt_V =
1104  pForce->FirstChildElement("VELOCITIES");
1105  ASSERTL0(funcNameElmt_D,
1106  "MOVINGBODYFORCE tag has to specify a function name which "
1107  "prescribes the body velocity of movement as v(z,t).");
1108 
1109  m_funcName[1] = funcNameElmt_V->GetText();
1110  ASSERTL0(m_session->DefinesFunction(m_funcName[1]),
1111  "Function '" + m_funcName[1] + "' not defined.");
1112 
1113  // Get the body acceleration: dd(m_zta)/ddt and dd(m_eta)/ddt
1114  const TiXmlElement *funcNameElmt_A =
1115  pForce->FirstChildElement("ACCELERATIONS");
1116  ASSERTL0(funcNameElmt_A,
1117  "MOVINGBODYFORCE tag has to specify a function name which "
1118  "prescribes the body acceleration as a(z,t).");
1119 
1120  m_funcName[2] = funcNameElmt_A->GetText();
1121  ASSERTL0(m_session->DefinesFunction(m_funcName[2]),
1122  "Function '" + m_funcName[2] + "' not defined.");
1123 
1125 
1126  // Check Displacement x
1127  vType = m_session->GetFunctionType(m_funcName[0], m_motion[0]);
1129  {
1130  m_IsFromFile[0] = false;
1131  }
1132  else if (vType == LibUtilities::eFunctionTypeFile)
1133  {
1134  m_IsFromFile[0] = true;
1135  }
1136  else
1137  {
1138  ASSERTL0(false, "The displacements in x must be specified via an "
1139  "equation <E> or a file <F>");
1140  }
1141 
1142  // Check Displacement y
1143  vType = m_session->GetFunctionType(m_funcName[0], m_motion[1]);
1145  {
1146  m_IsFromFile[1] = false;
1147  }
1148  else if (vType == LibUtilities::eFunctionTypeFile)
1149  {
1150  m_IsFromFile[1] = true;
1151  }
1152  else
1153  {
1154  ASSERTL0(false, "The displacements in y must be specified via an "
1155  "equation <E> or a file <F>");
1156  }
1157 
1158  // Check Velocity x
1159  vType = m_session->GetFunctionType(m_funcName[1], m_motion[0]);
1161  {
1162  m_IsFromFile[2] = false;
1163  }
1164  else if (vType == LibUtilities::eFunctionTypeFile)
1165  {
1166  m_IsFromFile[2] = true;
1167  }
1168  else
1169  {
1170  ASSERTL0(false, "The velocities in x must be specified via an equation "
1171  "<E> or a file <F>");
1172  }
1173 
1174  // Check Velocity y
1175  vType = m_session->GetFunctionType(m_funcName[1], m_motion[1]);
1177  {
1178  m_IsFromFile[3] = false;
1179  }
1180  else if (vType == LibUtilities::eFunctionTypeFile)
1181  {
1182  m_IsFromFile[3] = true;
1183  }
1184  else
1185  {
1186  ASSERTL0(false, "The velocities in y must be specified via an equation "
1187  "<E> or a file <F>");
1188  }
1189 
1190  // Check Acceleration x
1191  vType = m_session->GetFunctionType(m_funcName[2], m_motion[0]);
1193  {
1194  m_IsFromFile[4] = false;
1195  }
1196  else if (vType == LibUtilities::eFunctionTypeFile)
1197  {
1198  m_IsFromFile[4] = true;
1199  }
1200  else
1201  {
1202  ASSERTL0(false, "The accelerations in x must be specified via an "
1203  "equation <E> or a file <F>");
1204  }
1205 
1206  // Check Acceleration y
1207  vType = m_session->GetFunctionType(m_funcName[2], m_motion[1]);
1209  {
1210  m_IsFromFile[5] = false;
1211  }
1212  else if (vType == LibUtilities::eFunctionTypeFile)
1213  {
1214  m_IsFromFile[5] = true;
1215  }
1216  else
1217  {
1218  ASSERTL0(false, "The accelerations in y must be specified via an "
1219  "equation <E> or a file <F>");
1220  }
1221 }
#define ASSERTL0(condition, msg)
Definition: ErrorUtil.hpp:215
Array< OneD, std::string > m_funcName
[0] is displacements, [1] is velocities, [2] is accelerations
Array< OneD, bool > m_IsFromFile
do determine if the the body motion come from an extern file
Array< OneD, std::string > m_motion
motion direction: [0] is 'x' and [1] is 'y'
LibUtilities::SessionReaderSharedPtr m_session
Session reader.
Definition: Forcing.h:116

References ASSERTL0, Nektar::LibUtilities::eFunctionTypeExpression, Nektar::LibUtilities::eFunctionTypeFile, m_funcName, m_IsFromFile, m_motion, and Nektar::SolverUtils::Forcing::m_session.

Referenced by v_InitObject().

◆ create()

static SolverUtils::ForcingSharedPtr Nektar::ForcingMovingBody::create ( const LibUtilities::SessionReaderSharedPtr pSession,
const std::weak_ptr< SolverUtils::EquationSystem > &  pEquation,
const Array< OneD, MultiRegions::ExpListSharedPtr > &  pFields,
const unsigned int &  pNumForcingFields,
const TiXmlElement *  pForce 
)
inlinestatic

Creates an instance of this class.

Definition at line 55 of file ForcingMovingBody.h.

60  {
63  pEquation);
64  p->InitObject(pFields, pNumForcingFields, pForce);
65  return p;
66  }
static std::shared_ptr< DataType > AllocateSharedPtr(const Args &...args)
Allocate a shared pointer from the memory pool.
SOLVER_UTILS_EXPORT typedef std::shared_ptr< Forcing > ForcingSharedPtr
A shared pointer to an EquationSystem object.
Definition: Forcing.h:52

References Nektar::MemoryManager< DataType >::AllocateSharedPtr(), Nektar::SolverUtils::ForcingSharedPtr, and CellMLToNektar.cellml_metadata::p.

◆ EvaluateStructDynModel()

void Nektar::ForcingMovingBody::EvaluateStructDynModel ( const Array< OneD, MultiRegions::ExpListSharedPtr > &  pFields,
Array< OneD, NekDouble > &  Hydroforces,
NekDouble  time 
)
private

Definition at line 229 of file ForcingMovingBody.cpp.

232 {
233  boost::ignore_unused(time);
234 
235  LibUtilities::CommSharedPtr vcomm = pFields[0]->GetComm();
236  size_t colrank = vcomm->GetColumnComm()->GetRank();
237  size_t nproc = vcomm->GetColumnComm()->GetSize();
238 
239  bool homostrip;
240  m_session->MatchSolverInfo("HomoStrip", "True", homostrip, false);
241 
242  // number of structral modes and number of strips
243  size_t npts, nstrips;
244  if (!homostrip) // full resolutions
245  {
246  npts = m_session->GetParameter("HomModesZ");
247  }
248  else
249  {
250  m_session->LoadParameter("HomStructModesZ", npts);
251  m_session->LoadParameter("Strip_Z", nstrips);
252 
253  // ASSERTL0(nstrips < = npts,
254  // "the number of struct. modes must be larger than that of the
255  // strips.");
256  }
257 
258  // the hydrodynamic forces
259  Array<OneD, Array<OneD, NekDouble>> fces(2);
260  // forces in x-direction
261  fces[0] = Array<OneD, NekDouble>(npts, 0.0);
262  // forces in y-direction
263  fces[1] = Array<OneD, NekDouble>(npts, 0.0);
264 
265  // fill the force vectors
266  if (colrank == 0)
267  {
268  if (!homostrip) // full resolutions
269  {
270  Vmath::Vcopy(m_np, Hydroforces, 1, fces[0], 1);
271  Vmath::Vcopy(m_np, Hydroforces + m_np, 1, fces[1], 1);
272  }
273  else // strip modelling
274  {
275  fces[0][0] = Hydroforces[0];
276  fces[1][0] = Hydroforces[m_np];
277  }
278 
279  if (!homostrip) // full resolutions
280  {
281  Array<OneD, NekDouble> tmp(2 * m_np);
282  for (size_t i = 1; i < nproc; ++i)
283  {
284  vcomm->GetColumnComm()->Recv(i, tmp);
285  for (size_t n = 0; n < m_np; n++)
286  {
287  for (size_t j = 0; j < 2; ++j)
288  {
289  fces[j][i * m_np + n] = tmp[j * m_np + n];
290  }
291  }
292  }
293  }
294  else // strip modelling
295  // if the body is submerged partly, the fces are filled partly
296  // by the flow induced forces
297  {
298  Array<OneD, NekDouble> tmp(2);
299  for (size_t i = 1; i < nstrips; ++i)
300  {
301  vcomm->GetColumnComm()->Recv(i, tmp);
302 
303  for (size_t j = 0; j < 2; ++j)
304  {
305  fces[j][i] = tmp[j];
306  }
307  }
308  }
309  }
310  else
311  {
312  if (!homostrip) // full resolutions
313  {
314  vcomm->GetColumnComm()->Send(0, Hydroforces);
315  }
316  else // strip modelling
317  {
318  for (size_t i = 1; i < nstrips; ++i)
319  {
320  if (colrank == i)
321  {
322  Array<OneD, NekDouble> tmp(2);
323  tmp[0] = Hydroforces[0];
324  tmp[1] = Hydroforces[m_np];
325  vcomm->GetColumnComm()->Send(0, tmp);
326  }
327  }
328  }
329  }
330 
331  if (colrank == 0)
332  {
333  // Fictitious mass method used to stablize the explicit coupling at
334  // relatively lower mass ratio
335  bool fictmass;
336  m_session->MatchSolverInfo("FictitiousMassMethod", "True", fictmass,
337  false);
338  if (fictmass)
339  {
340  NekDouble fictrho, fictdamp;
341  m_session->LoadParameter("FictMass", fictrho);
342  m_session->LoadParameter("FictDamp", fictdamp);
343 
344  static NekDouble Betaq_Coeffs[2][2] = {{1.0, 0.0}, {2.0, -1.0}};
345 
346  // only consider second order approximation for fictitious variables
347  size_t intOrder = 2;
348  size_t nint = min(m_movingBodyCalls + 1, intOrder);
349  size_t nlevels = m_fV[0].size();
350 
351  for (size_t i = 0; i < m_motion.size(); ++i)
352  {
353  RollOver(m_fV[i]);
354  RollOver(m_fA[i]);
355 
356  size_t Voffset = npts;
357  size_t Aoffset = 2 * npts;
358 
359  Vmath::Vcopy(npts, m_MotionVars[i] + Voffset, 1, m_fV[i][0], 1);
360  Vmath::Vcopy(npts, m_MotionVars[i] + Aoffset, 1, m_fA[i][0], 1);
361 
362  // Extrapolate to n+1
363  Vmath::Smul(npts, Betaq_Coeffs[nint - 1][nint - 1],
364  m_fV[i][nint - 1], 1, m_fV[i][nlevels - 1], 1);
365  Vmath::Smul(npts, Betaq_Coeffs[nint - 1][nint - 1],
366  m_fA[i][nint - 1], 1, m_fA[i][nlevels - 1], 1);
367 
368  for (size_t n = 0; n < nint - 1; ++n)
369  {
370  Vmath::Svtvp(npts, Betaq_Coeffs[nint - 1][n], m_fV[i][n], 1,
371  m_fV[i][nlevels - 1], 1, m_fV[i][nlevels - 1],
372  1);
373  Vmath::Svtvp(npts, Betaq_Coeffs[nint - 1][n], m_fA[i][n], 1,
374  m_fA[i][nlevels - 1], 1, m_fA[i][nlevels - 1],
375  1);
376  }
377 
378  // Add the fictitious forces on the RHS of the equation
379  Vmath::Svtvp(npts, fictdamp, m_fV[i][nlevels - 1], 1, fces[i],
380  1, fces[i], 1);
381  Vmath::Svtvp(npts, fictrho, m_fA[i][nlevels - 1], 1, fces[i], 1,
382  fces[i], 1);
383  }
384  }
385  }
386  // structural solver is implemented on the root process
387  if (colrank == 0)
388  {
389  // Tensioned cable model is evaluated in wave space
390  for (size_t n = 0, cn = 1; n < m_vdim; n++, cn--)
391  {
392  Newmark_betaSolver(pFields, fces[cn], m_MotionVars[cn]);
393  }
394  }
395 
396  Array<OneD, NekDouble> Motvars(2 * 2 * m_np);
397  // send physical coeffients to all planes of each processor
398  if (!homostrip) // full resolutions
399  {
400  Array<OneD, NekDouble> tmp(2 * 2 * m_np);
401 
402  if (colrank != 0)
403  {
404  vcomm->GetColumnComm()->Recv(0, tmp);
405  Vmath::Vcopy(2 * 2 * m_np, tmp, 1, Motvars, 1);
406  }
407  else
408  {
409  for (size_t i = 1; i < nproc; ++i)
410  {
411  for (size_t j = 0; j < 2; j++) // moving dimensions
412  {
413  for (size_t k = 0; k < 2; k++) // disp. and vel.
414  {
415  for (size_t n = 0; n < m_np; n++)
416  {
417  tmp[j * 2 * m_np + k * m_np + n] =
418  m_MotionVars[j][k * npts + i * m_np + n];
419  }
420  }
421  }
422  vcomm->GetColumnComm()->Send(i, tmp);
423  }
424 
425  for (size_t j = 0; j < 2; j++)
426  {
427  for (size_t k = 0; k < 2; k++)
428  {
429  for (size_t n = 0; n < m_np; n++)
430  {
431  tmp[j * 2 * m_np + k * m_np + n] =
432  m_MotionVars[j][k * npts + n];
433  }
434  Vmath::Vcopy(2 * 2 * m_np, tmp, 1, Motvars, 1);
435  }
436  }
437  }
438  }
439  else // strip modelling
440  {
441  Array<OneD, NekDouble> tmp(2 * 2);
442 
443  if (colrank != 0)
444  {
445  for (size_t j = 1; j < nproc / nstrips; j++)
446  {
447  if (colrank == j * nstrips)
448  {
449  vcomm->GetColumnComm()->Recv(0, tmp);
450 
451  for (size_t plane = 0; plane < m_np; plane++)
452  {
453  for (size_t var = 0; var < 2; var++)
454  {
455  for (size_t k = 0; k < 2; k++)
456  {
457  Motvars[var * 2 * m_np + k * m_np + plane] =
458  tmp[var * 2 + k];
459  }
460  }
461  }
462  }
463  }
464 
465  for (size_t i = 1; i < nstrips; i++)
466  {
467  for (size_t j = 0; j < nproc / nstrips; j++)
468  {
469  if (colrank == i + j * nstrips)
470  {
471  vcomm->GetColumnComm()->Recv(0, tmp);
472 
473  for (size_t plane = 0; plane < m_np; plane++)
474  {
475  for (size_t var = 0; var < 2; var++)
476  {
477  for (size_t k = 0; k < 2; k++)
478  {
479  Motvars[var * 2 * m_np + k * m_np + plane] =
480  tmp[var * 2 + k];
481  }
482  }
483  }
484  }
485  }
486  }
487  }
488  else
489  {
490  for (size_t j = 0; j < 2; ++j)
491  {
492  for (size_t k = 0; k < 2; ++k)
493  {
494  tmp[j * 2 + k] = m_MotionVars[j][k * npts];
495  }
496  }
497 
498  for (size_t j = 1; j < nproc / nstrips; j++)
499  {
500  vcomm->GetColumnComm()->Send(j * nstrips, tmp);
501  }
502 
503  for (size_t plane = 0; plane < m_np; plane++)
504  {
505  for (size_t j = 0; j < 2; j++)
506  {
507  for (size_t k = 0; k < 2; ++k)
508  {
509  Motvars[j * 2 * m_np + k * m_np + plane] =
510  m_MotionVars[j][k * npts];
511  }
512  }
513  }
514 
515  for (size_t i = 1; i < nstrips; ++i)
516  {
517  for (size_t j = 0; j < 2; ++j)
518  {
519  for (size_t k = 0; k < 2; ++k)
520  {
521  tmp[j * 2 + k] = m_MotionVars[j][i + k * npts];
522  }
523  }
524 
525  for (size_t j = 0; j < nproc / nstrips; j++)
526  {
527  vcomm->GetColumnComm()->Send(i + j * nstrips, tmp);
528  }
529  }
530  }
531  }
532 
533  // Set the m_forcing term based on the motion of the cable
534  for (size_t var = 0; var < 2; var++)
535  {
536  for (size_t plane = 0; plane < m_np; plane++)
537  {
538  size_t n = pFields[0]->GetPlane(plane)->GetTotPoints();
539 
540  Array<OneD, NekDouble> tmp;
541 
542  size_t offset = plane * n;
543  size_t xoffset = var * m_np + plane;
544  size_t yoffset = 2 * m_np + xoffset;
545 
546  Vmath::Fill(n, Motvars[xoffset], tmp = m_zta[var] + offset, 1);
547  Vmath::Fill(n, Motvars[yoffset], tmp = m_eta[var] + offset, 1);
548  }
549  }
550 }
Array< OneD, Array< OneD, NekDouble > > m_zta
Store the derivatives of motion variables in x-direction.
size_t m_np
number of planes per processors
Array< OneD, Array< OneD, NekDouble > > m_eta
Store the derivatives of motion variables in y-direction.
Array< OneD, Array< OneD, Array< OneD, NekDouble > > > m_fV
fictitious velocity storage
Array< OneD, Array< OneD, Array< OneD, NekDouble > > > m_fA
fictitious acceleration storage
size_t m_vdim
vibration dimension
Array< OneD, Array< OneD, NekDouble > > m_MotionVars
storage for the cable's motion(x,y) variables
void RollOver(Array< OneD, Array< OneD, NekDouble >> &input)
size_t m_movingBodyCalls
number of times the movbody have been called
void Newmark_betaSolver(const Array< OneD, MultiRegions::ExpListSharedPtr > &pFields, Array< OneD, NekDouble > &FcePhysinArray, Array< OneD, NekDouble > &MotPhysinArray)
std::shared_ptr< Comm > CommSharedPtr
Pointer to a Communicator object.
Definition: Comm.h:54
double NekDouble
void Svtvp(int n, const T alpha, const T *x, const int incx, const T *y, const int incy, T *z, const int incz)
svtvp (scalar times vector plus vector): z = alpha*x + y
Definition: Vmath.cpp:622
void Smul(int n, const T alpha, const T *x, const int incx, T *y, const int incy)
Scalar multiply y = alpha*x.
Definition: Vmath.cpp:248
void Fill(int n, const T alpha, T *x, const int incx)
Fill a vector with a constant value.
Definition: Vmath.cpp:45
void Vcopy(int n, const T *x, const int incx, T *y, const int incy)
Definition: Vmath.cpp:1255

References Vmath::Fill(), m_eta, m_fA, m_fV, m_motion, m_MotionVars, m_movingBodyCalls, m_np, Nektar::SolverUtils::Forcing::m_session, m_vdim, m_zta, Newmark_betaSolver(), RollOver(), Vmath::Smul(), Vmath::Svtvp(), and Vmath::Vcopy().

Referenced by v_Apply().

◆ InitialiseCableModel()

void Nektar::ForcingMovingBody::InitialiseCableModel ( const LibUtilities::SessionReaderSharedPtr pSession,
const Array< OneD, MultiRegions::ExpListSharedPtr > &  pFields 
)
private

Definition at line 685 of file ForcingMovingBody.cpp.

688 {
689  boost::ignore_unused(pSession, pFields);
690 
691  m_movingBodyCalls = 0;
692  m_session->LoadParameter("Kinvis", m_kinvis);
693  m_session->LoadParameter("TimeStep", m_timestep, 0.01);
694 
695  LibUtilities::CommSharedPtr vcomm = pFields[0]->GetComm();
696  size_t colrank = vcomm->GetColumnComm()->GetRank();
697  size_t nproc = vcomm->GetColumnComm()->GetSize();
698 
699  // number of structral modes
700  size_t npts;
701  bool homostrip;
702  m_session->MatchSolverInfo("HomoStrip", "True", homostrip, false);
703 
704  if (!homostrip) // full resolutions
705  {
706  npts = m_session->GetParameter("HomModesZ");
707  }
708  else
709  {
710  m_session->LoadParameter("HomStructModesZ", npts);
711  }
712 
713  m_MotionVars = Array<OneD, Array<OneD, NekDouble>>(2);
714  m_MotionVars[0] = Array<OneD, NekDouble>(3 * npts, 0.0);
715  m_MotionVars[1] = Array<OneD, NekDouble>(3 * npts, 0.0);
716 
717  Array<OneD, unsigned int> ZIDs;
718  ZIDs = pFields[0]->GetZIDs();
719  m_np = ZIDs.size();
720 
721  std::string vibtype = m_session->GetSolverInfo("VibrationType");
722 
723  if (boost::iequals(vibtype, "Constrained"))
724  {
725  m_vdim = 1;
726  }
727  else if (boost::iequals(vibtype, "Free"))
728  {
729  m_vdim = 2;
730  }
731  else if (boost::iequals(vibtype, "Forced"))
732  {
733  m_vdim = 0;
734  return;
735  }
736 
737  if (!homostrip)
738  {
739  m_session->LoadParameter("LZ", m_lhom);
740  int nplanes = m_session->GetParameter("HomModesZ");
742  nplanes);
743  }
744  else
745  {
746  int nstrips;
747  NekDouble DistStrip;
748 
749  m_session->LoadParameter("DistStrip", DistStrip);
750  m_session->LoadParameter("Strip_Z", nstrips);
751  m_lhom = nstrips * DistStrip;
753  nstrips);
754  }
755 
756  // load the structural dynamic parameters from xml file
757  m_session->LoadParameter("StructRho", m_structrho);
758  m_session->LoadParameter("StructDamp", m_structdamp, 0.0);
759 
760  // Identify whether the fictitious mass method is active for explicit
761  // coupling of fluid solver and structural dynamics solver
762  bool fictmass;
763  m_session->MatchSolverInfo("FictitiousMassMethod", "True", fictmass, false);
764  if (fictmass)
765  {
766  NekDouble fictrho, fictdamp;
767  m_session->LoadParameter("FictMass", fictrho);
768  m_session->LoadParameter("FictDamp", fictdamp);
769  m_structrho += fictrho;
770  m_structdamp += fictdamp;
771 
772  // Storage array of Struct Velocity and Acceleration used for
773  // extrapolation of fictitious force
774  m_fV = Array<OneD, Array<OneD, Array<OneD, NekDouble>>>(2);
775  m_fA = Array<OneD, Array<OneD, Array<OneD, NekDouble>>>(2);
776  for (size_t i = 0; i < m_motion.size(); ++i)
777  {
778  m_fV[i] = Array<OneD, Array<OneD, NekDouble>>(2);
779  m_fA[i] = Array<OneD, Array<OneD, NekDouble>>(2);
780 
781  for (size_t n = 0; n < 2; ++n)
782  {
783  m_fV[i][n] = Array<OneD, NekDouble>(npts, 0.0);
784  m_fA[i][n] = Array<OneD, NekDouble>(npts, 0.0);
785  }
786  }
787  }
788 
789  // Setting the coefficient matrices for solving structural dynamic ODEs
790  SetDynEqCoeffMatrix(pFields);
791 
792  // Set initial condition for cable's motion
793  size_t cnt = 0;
794 
795  for (size_t j = 0; j < m_funcName.size(); j++)
796  {
797  // loading from the specified files through inputstream
798  if (m_IsFromFile[cnt] && m_IsFromFile[cnt + 1])
799  {
800  std::ifstream inputStream;
801  size_t nzpoints;
802 
803  if (homostrip)
804  {
805  m_session->LoadParameter("HomStructModesZ", nzpoints);
806  }
807  else
808  {
809  nzpoints = pFields[0]->GetHomogeneousBasis()->GetNumModes();
810  }
811 
812  if (vcomm->GetRank() == 0)
813  {
814  std::string filename =
815  m_session->GetFunctionFilename(m_funcName[j], m_motion[0]);
816 
817  // Open intputstream for cable motions
818  inputStream.open(filename.c_str());
819 
820  // Import the head string from the file
821  Array<OneD, std::string> tmp(9);
822  for (size_t n = 0; n < tmp.size(); n++)
823  {
824  inputStream >> tmp[n];
825  }
826 
827  NekDouble time, z_cds;
828  // Import the motion variables from the file
829  for (size_t n = 0; n < nzpoints; n++)
830  {
831  inputStream >> setprecision(6) >> time;
832  inputStream >> setprecision(6) >> z_cds;
833  inputStream >> setprecision(8) >> m_MotionVars[0][n];
834  inputStream >> setprecision(8) >>
835  m_MotionVars[0][n + nzpoints];
836  inputStream >> setprecision(8) >>
837  m_MotionVars[0][n + 2 * nzpoints];
838  inputStream >> setprecision(8) >> m_MotionVars[1][n];
839  inputStream >> setprecision(8) >>
840  m_MotionVars[1][n + nzpoints];
841  inputStream >> setprecision(8) >>
842  m_MotionVars[1][n + 2 * nzpoints];
843  }
844  // Close inputstream for cable motions
845  inputStream.close();
846  }
847  cnt = cnt + 2;
848  }
849  else // Evaluate from the functions specified in xml file
850  {
851  if (!homostrip)
852  {
853  size_t nzpoints =
854  pFields[0]->GetHomogeneousBasis()->GetNumModes();
855  Array<OneD, NekDouble> z_coords(nzpoints, 0.0);
856  Array<OneD, const NekDouble> pts =
857  pFields[0]->GetHomogeneousBasis()->GetZ();
858 
859  Vmath::Smul(nzpoints, m_lhom / 2.0, pts, 1, z_coords, 1);
860  Vmath::Sadd(nzpoints, m_lhom / 2.0, z_coords, 1, z_coords, 1);
861 
862  Array<OneD, NekDouble> x0(m_np, 0.0);
863  Array<OneD, NekDouble> x1(m_np, 0.0);
864  Array<OneD, NekDouble> x2(m_np, 0.0);
865  for (size_t plane = 0; plane < m_np; plane++)
866  {
867  x2[plane] = z_coords[ZIDs[plane]];
868  }
869 
870  Array<OneD, NekDouble> tmp(m_np, 0.0);
871  Array<OneD, NekDouble> tmp0(m_np, 0.0);
872  Array<OneD, NekDouble> tmp1(m_np, 0.0);
873  LibUtilities::EquationSharedPtr ffunc0, ffunc1;
874 
875  ffunc0 = m_session->GetFunction(m_funcName[j], m_motion[0]);
876  ffunc1 = m_session->GetFunction(m_funcName[j], m_motion[1]);
877  ffunc0->Evaluate(x0, x1, x2, 0.0, tmp0);
878  ffunc1->Evaluate(x0, x1, x2, 0.0, tmp1);
879 
880  size_t offset = j * npts;
881  Vmath::Vcopy(m_np, tmp0, 1, tmp = m_MotionVars[0] + offset, 1);
882  Vmath::Vcopy(m_np, tmp1, 1, tmp = m_MotionVars[1] + offset, 1);
883 
884  if (colrank == 0)
885  {
886  for (size_t i = 1; i < nproc; ++i)
887  {
888  vcomm->GetColumnComm()->Recv(i, tmp0);
889  vcomm->GetColumnComm()->Recv(i, tmp1);
890  Vmath::Vcopy(m_np, tmp0, 1,
891  tmp = m_MotionVars[0] + offset + i * m_np,
892  1);
893  Vmath::Vcopy(m_np, tmp1, 1,
894  tmp = m_MotionVars[1] + offset + i * m_np,
895  1);
896  }
897  }
898  else
899  {
900  vcomm->GetColumnComm()->Send(0, tmp0);
901  vcomm->GetColumnComm()->Send(0, tmp1);
902  }
903  }
904  else
905  {
906  if (colrank == 0)
907  {
908  size_t nstrips;
909  m_session->LoadParameter("Strip_Z", nstrips);
910 
911  ASSERTL0(
912  m_session->DefinesSolverInfo("USEFFT"),
913  "Fourier transformation of cable motion is currently "
914  "implemented only for FFTW module.");
915 
916  NekDouble DistStrip;
917  m_session->LoadParameter("DistStrip", DistStrip);
918 
919  Array<OneD, NekDouble> x0(npts, 0.0);
920  Array<OneD, NekDouble> x1(npts, 0.0);
921  Array<OneD, NekDouble> x2(npts, 0.0);
922  Array<OneD, NekDouble> tmp(npts, 0.0);
923  Array<OneD, NekDouble> tmp0(npts, 0.0);
924  Array<OneD, NekDouble> tmp1(npts, 0.0);
925  for (size_t plane = 0; plane < npts; plane++)
926  {
927  x2[plane] = plane * DistStrip;
928  }
929  LibUtilities::EquationSharedPtr ffunc0, ffunc1;
930  ffunc0 = m_session->GetFunction(m_funcName[j], m_motion[0]);
931  ffunc1 = m_session->GetFunction(m_funcName[j], m_motion[1]);
932  ffunc0->Evaluate(x0, x1, x2, 0.0, tmp0);
933  ffunc1->Evaluate(x0, x1, x2, 0.0, tmp1);
934 
935  size_t offset = j * npts;
936  Vmath::Vcopy(npts, tmp0, 1, tmp = m_MotionVars[0] + offset,
937  1);
938  Vmath::Vcopy(npts, tmp1, 1, tmp = m_MotionVars[1] + offset,
939  1);
940  }
941  }
942 
943  cnt = cnt + 2;
944  }
945  }
946 }
NekDouble m_lhom
length ratio of the cable
NekDouble m_kinvis
fluid viscous
void SetDynEqCoeffMatrix(const Array< OneD, MultiRegions::ExpListSharedPtr > &pFields)
NekDouble m_structrho
mass of the cable per unit length
NekDouble m_timestep
time step
LibUtilities::NektarFFTSharedPtr m_FFT
NekDouble m_structdamp
damping ratio of the cable
tBaseSharedPtr CreateInstance(tKey idKey, tParam... args)
Create an instance of the class referred to by idKey.
Definition: NekFactory.hpp:144
NektarFFTFactory & GetNektarFFTFactory()
Definition: NektarFFT.cpp:69
std::shared_ptr< Equation > EquationSharedPtr
Definition: Equation.h:129
void Sadd(int n, const T alpha, const T *x, const int incx, T *y, const int incy)
Add scalar y = alpha + x.
Definition: Vmath.cpp:384

References ASSERTL0, Nektar::LibUtilities::NekFactory< tKey, tBase, tParam >::CreateInstance(), Nektar::LibUtilities::GetNektarFFTFactory(), m_fA, m_FFT, m_funcName, m_fV, m_IsFromFile, m_kinvis, m_lhom, m_motion, m_MotionVars, m_movingBodyCalls, m_np, Nektar::SolverUtils::Forcing::m_session, m_structdamp, m_structrho, m_timestep, m_vdim, Vmath::Sadd(), SetDynEqCoeffMatrix(), Vmath::Smul(), and Vmath::Vcopy().

Referenced by v_InitObject().

◆ InitialiseFilter()

void Nektar::ForcingMovingBody::InitialiseFilter ( const LibUtilities::SessionReaderSharedPtr pSession,
const Array< OneD, MultiRegions::ExpListSharedPtr > &  pFields,
const TiXmlElement *  pForce 
)
private

Definition at line 1226 of file ForcingMovingBody.cpp.

1230 {
1231  // Get the outputfile name, output frequency and
1232  // the boundary's ID for the cable's wall
1233  std::string typeStr = pForce->Attribute("TYPE");
1234  std::map<std::string, std::string> vParams;
1235 
1236  const TiXmlElement *param = pForce->FirstChildElement("PARAM");
1237  while (param)
1238  {
1239  ASSERTL0(param->Attribute("NAME"),
1240  "Missing attribute 'NAME' for parameter in filter " + typeStr +
1241  "'.");
1242  std::string nameStr = param->Attribute("NAME");
1243 
1244  ASSERTL0(param->GetText(), "Empty value string for param.");
1245  std::string valueStr = param->GetText();
1246 
1247  vParams[nameStr] = valueStr;
1248 
1249  param = param->NextSiblingElement("PARAM");
1250  }
1251 
1252  // Creat the filter for MovingBody, where we performed the calculation of
1253  // fluid forces and write both the aerodynamic forces and motion variables
1254  // into the output files
1256  pSession, m_equ, vParams);
1257 
1258  // Initialise the object of MovingBody filter
1259  m_MovBodyfilter->Initialise(pFields, 0.0);
1260 }
FilterMovingBodySharedPtr m_MovBodyfilter
const std::weak_ptr< EquationSystem > m_equ
Weak pointer to equation system using this forcing.
Definition: Forcing.h:118

References Nektar::MemoryManager< DataType >::AllocateSharedPtr(), ASSERTL0, Nektar::SolverUtils::Forcing::m_equ, and m_MovBodyfilter.

Referenced by v_InitObject().

◆ Newmark_betaSolver()

void Nektar::ForcingMovingBody::Newmark_betaSolver ( const Array< OneD, MultiRegions::ExpListSharedPtr > &  pFields,
Array< OneD, NekDouble > &  FcePhysinArray,
Array< OneD, NekDouble > &  MotPhysinArray 
)
private

Definition at line 555 of file ForcingMovingBody.cpp.

558 {
559  boost::ignore_unused(pFields);
560 
561  std::string supptype = m_session->GetSolverInfo("SupportType");
562 
563  size_t npts = HydroForces.size();
564 
565  Array<OneD, Array<OneD, NekDouble>> fft_i(4);
566  Array<OneD, Array<OneD, NekDouble>> fft_o(4);
567 
568  for (size_t i = 0; i < 4; i++)
569  {
570  fft_i[i] = Array<OneD, NekDouble>(npts, 0.0);
571  fft_o[i] = Array<OneD, NekDouble>(npts, 0.0);
572  }
573 
574  Vmath::Vcopy(npts, HydroForces, 1, fft_i[0], 1);
575  for (size_t i = 0; i < 3; i++)
576  {
577  Vmath::Vcopy(npts, BodyMotions + i * npts, 1, fft_i[i + 1], 1);
578  }
579 
580  // Implement Fourier transformation of the motion variables
581  if (boost::iequals(supptype, "Free-Free"))
582  {
583  for (size_t j = 0; j < 4; ++j)
584  {
585  m_FFT->FFTFwdTrans(fft_i[j], fft_o[j]);
586  }
587  }
588  else if (boost::iequals(supptype, "Pinned-Pinned"))
589  {
590  // TODO:
591  size_t N = fft_i[0].size();
592 
593  for (size_t var = 0; var < 4; var++)
594  {
595  for (size_t i = 0; i < N; i++)
596  {
597  fft_o[var][i] = 0;
598 
599  for (size_t k = 0; k < N; k++)
600  {
601  fft_o[var][i] +=
602  fft_i[var][k] * sin(M_PI / (N) * (k + 1 / 2) * (i + 1));
603  }
604  }
605  }
606  }
607  else
608  {
609  ASSERTL0(false, "Unrecognized support type for cable's motion");
610  }
611 
612  // solve the ODE in the wave space
613  for (size_t i = 0; i < npts; ++i)
614  {
615  size_t nrows = 3;
616 
617  Array<OneD, NekDouble> tmp0, tmp1, tmp2;
618  tmp0 = Array<OneD, NekDouble>(3, 0.0);
619  tmp1 = Array<OneD, NekDouble>(3, 0.0);
620  tmp2 = Array<OneD, NekDouble>(3, 0.0);
621 
622  for (size_t var = 0; var < 3; var++)
623  {
624  tmp0[var] = fft_o[var + 1][i];
625  }
626 
627  tmp2[0] = fft_o[0][i];
628 
629  Blas::Dgemv('N', nrows, nrows, 1.0, &(m_CoeffMat_B[i]->GetPtr())[0],
630  nrows, &tmp0[0], 1, 0.0, &tmp1[0], 1);
631  Blas::Dgemv('N', nrows, nrows, 1.0 / m_structrho,
632  &(m_CoeffMat_A[i]->GetPtr())[0], nrows, &tmp2[0], 1, 1.0,
633  &tmp1[0], 1);
634 
635  for (size_t var = 0; var < 3; var++)
636  {
637  fft_i[var][i] = tmp1[var];
638  }
639  }
640 
641  // get physical coeffients via Backward fourier transformation of wave
642  // coefficients
643  if (boost::iequals(supptype, "Free-Free"))
644  {
645  for (size_t var = 0; var < 3; var++)
646  {
647  m_FFT->FFTBwdTrans(fft_i[var], fft_o[var]);
648  }
649  }
650  else if (boost::iequals(supptype, "Pinned-Pinned"))
651  {
652  // TODO:
653  size_t N = fft_i[0].size();
654 
655  for (size_t var = 0; var < 3; var++)
656  {
657  for (size_t i = 0; i < N; i++)
658  {
659  fft_o[var][i] = 0;
660 
661  for (size_t k = 0; k < N; k++)
662  {
663  fft_o[var][i] += fft_i[var][k] *
664  sin(M_PI / (N) * (k + 1) * (i + 1 / 2)) *
665  2 / N;
666  }
667  }
668  }
669  }
670  else
671  {
672  ASSERTL0(false, "Unrecognized support type for cable's motion");
673  }
674 
675  for (size_t i = 0; i < 3; i++)
676  {
677  Array<OneD, NekDouble> tmp(npts, 0.0);
678  Vmath::Vcopy(npts, fft_o[i], 1, tmp = BodyMotions + i * npts, 1);
679  }
680 }
Array< OneD, DNekMatSharedPtr > m_CoeffMat_A
matrices in Newmart-beta method
Array< OneD, DNekMatSharedPtr > m_CoeffMat_B
matrices in Newmart-beta method
static void Dgemv(const char &trans, const int &m, const int &n, const double &alpha, const double *a, const int &lda, const double *x, const int &incx, const double &beta, double *y, const int &incy)
BLAS level 2: Matrix vector multiply y = A x where A[m x n].
Definition: Blas.hpp:246

References ASSERTL0, Blas::Dgemv(), m_CoeffMat_A, m_CoeffMat_B, m_FFT, Nektar::SolverUtils::Forcing::m_session, m_structrho, and Vmath::Vcopy().

Referenced by EvaluateStructDynModel().

◆ RollOver()

void Nektar::ForcingMovingBody::RollOver ( Array< OneD, Array< OneD, NekDouble >> &  input)
private

Function to roll time-level storages to the next step layout. The stored data associated with the oldest time-level (not required anymore) are moved to the top, where they will be overwritten as the solution process progresses.

Definition at line 1058 of file ForcingMovingBody.cpp.

1059 {
1060  size_t nlevels = input.size();
1061 
1062  Array<OneD, NekDouble> tmp;
1063  tmp = input[nlevels - 1];
1064 
1065  for (size_t n = nlevels - 1; n > 0; --n)
1066  {
1067  input[n] = input[n - 1];
1068  }
1069 
1070  input[0] = tmp;
1071 }

Referenced by EvaluateStructDynModel().

◆ SetDynEqCoeffMatrix()

void Nektar::ForcingMovingBody::SetDynEqCoeffMatrix ( const Array< OneD, MultiRegions::ExpListSharedPtr > &  pFields)
private

Definition at line 951 of file ForcingMovingBody.cpp.

953 {
954  boost::ignore_unused(pFields);
955 
956  size_t nplanes;
957 
958  bool homostrip;
959  m_session->MatchSolverInfo("HomoStrip", "True", homostrip, false);
960 
961  if (!homostrip)
962  {
963  nplanes = m_session->GetParameter("HomModesZ");
964  }
965  else
966  {
967  m_session->LoadParameter("Strip_Z", nplanes);
968  }
969 
970  m_CoeffMat_A = Array<OneD, DNekMatSharedPtr>(nplanes);
971  m_CoeffMat_B = Array<OneD, DNekMatSharedPtr>(nplanes);
972 
973  NekDouble tmp1, tmp2, tmp3;
974  NekDouble tmp4, tmp5, tmp6, tmp7;
975 
976  // load the structural dynamic parameters from xml file
977  NekDouble cabletension;
978  NekDouble bendingstiff;
979  NekDouble structstiff;
980  m_session->LoadParameter("StructStiff", structstiff, 0.0);
981  m_session->LoadParameter("CableTension", cabletension, 0.0);
982  m_session->LoadParameter("BendingStiff", bendingstiff, 0.0);
983 
984  tmp1 = m_timestep * m_timestep;
985  tmp2 = structstiff / m_structrho;
986  tmp3 = m_structdamp / m_structrho;
987  tmp4 = cabletension / m_structrho;
988  tmp5 = bendingstiff / m_structrho;
989 
990  // solve the ODE in the wave space for cable motion to obtain disp, vel and
991  // accel
992 
993  std::string supptype = m_session->GetSolverInfo("SupportType");
994 
995  for (size_t plane = 0; plane < nplanes; plane++)
996  {
997  int nel = 3;
998  m_CoeffMat_A[plane] =
1000  m_CoeffMat_B[plane] =
1002 
1003  // Initialised to avoid compiler warnings.
1004  unsigned int K = 0;
1005  NekDouble beta = 0.0;
1006 
1007  if (boost::iequals(supptype, "Free-Free"))
1008  {
1009  K = plane / 2;
1010  beta = 2.0 * M_PI / m_lhom;
1011  }
1012  else if (boost::iequals(supptype, "Pinned-Pinned"))
1013  {
1014  K = plane + 1;
1015  beta = M_PI / m_lhom;
1016  }
1017  else
1018  {
1019  ASSERTL0(false, "Unrecognized support type for cable's motion");
1020  }
1021 
1022  tmp6 = beta * K;
1023  tmp6 = tmp6 * tmp6;
1024  tmp7 = tmp6 * tmp6;
1025  tmp7 = tmp2 + tmp4 * tmp6 + tmp5 * tmp7;
1026 
1027  (*m_CoeffMat_A[plane])(0, 0) = tmp7;
1028  (*m_CoeffMat_A[plane])(0, 1) = tmp3;
1029  (*m_CoeffMat_A[plane])(0, 2) = 1.0;
1030  (*m_CoeffMat_A[plane])(1, 0) = 0.0;
1031  (*m_CoeffMat_A[plane])(1, 1) = 1.0;
1032  (*m_CoeffMat_A[plane])(1, 2) = -m_timestep / 2.0;
1033  (*m_CoeffMat_A[plane])(2, 0) = 1.0;
1034  (*m_CoeffMat_A[plane])(2, 1) = 0.0;
1035  (*m_CoeffMat_A[plane])(2, 2) = -tmp1 / 4.0;
1036  (*m_CoeffMat_B[plane])(0, 0) = 0.0;
1037  (*m_CoeffMat_B[plane])(0, 1) = 0.0;
1038  (*m_CoeffMat_B[plane])(0, 2) = 0.0;
1039  (*m_CoeffMat_B[plane])(1, 0) = 0.0;
1040  (*m_CoeffMat_B[plane])(1, 1) = 1.0;
1041  (*m_CoeffMat_B[plane])(1, 2) = m_timestep / 2.0;
1042  (*m_CoeffMat_B[plane])(2, 0) = 1.0;
1043  (*m_CoeffMat_B[plane])(2, 1) = m_timestep;
1044  (*m_CoeffMat_B[plane])(2, 2) = tmp1 / 4.0;
1045 
1046  m_CoeffMat_A[plane]->Invert();
1047  (*m_CoeffMat_B[plane]) =
1048  (*m_CoeffMat_A[plane]) * (*m_CoeffMat_B[plane]);
1049  }
1050 }
@ beta
Gauss Radau pinned at x=-1,.
Definition: PointsType.h:61

References Nektar::MemoryManager< DataType >::AllocateSharedPtr(), ASSERTL0, Nektar::LibUtilities::beta, m_CoeffMat_A, m_CoeffMat_B, m_lhom, Nektar::SolverUtils::Forcing::m_session, m_structdamp, m_structrho, and m_timestep.

Referenced by InitialiseCableModel().

◆ v_Apply()

void Nektar::ForcingMovingBody::v_Apply ( const Array< OneD, MultiRegions::ExpListSharedPtr > &  fields,
const Array< OneD, Array< OneD, NekDouble >> &  inarray,
Array< OneD, Array< OneD, NekDouble >> &  outarray,
const NekDouble time 
)
overrideprotectedvirtual

Implements Nektar::SolverUtils::Forcing.

Definition at line 104 of file ForcingMovingBody.cpp.

108 {
109  boost::ignore_unused(inarray, outarray);
110 
111  // Update the forces from the calculation of fluid field, which is
112  // implemented in the movingbody filter
113  Array<OneD, NekDouble> Hydroforces(2 * m_np, 0.0);
114  m_MovBodyfilter->UpdateForce(m_session, pFields, Hydroforces, time);
115 
116  // for "free" type (m_vdim = 2), the cable vibrates both in streamwise and
117  // crossflow dimections, for "constrained" type (m_vdim = 1), the cable only
118  // vibrates in crossflow dimection, and for "forced" type (m_vdim = 0), the
119  // calbe vibrates specifically along a given function or file
120  if (m_vdim == 1 || m_vdim == 2)
121  {
122  // For free vibration case, displacements, velocities and acceleartions
123  // are obtained through solving structure dynamic model
124  EvaluateStructDynModel(pFields, Hydroforces, time);
125 
126  // Convert result to format required by mapping
127  size_t physTot = pFields[0]->GetTotPoints();
128  Array<OneD, Array<OneD, NekDouble>> coords(3);
129  Array<OneD, Array<OneD, NekDouble>> coordsVel(3);
130  for (size_t i = 0; i < 3; i++)
131  {
132  coords[i] = Array<OneD, NekDouble>(physTot, 0.0);
133  coordsVel[i] = Array<OneD, NekDouble>(physTot, 0.0);
134  }
135  // Get original coordinates
136  pFields[0]->GetCoords(coords[0], coords[1], coords[2]);
137 
138  // Add displacement to coordinates
139  Vmath::Vadd(physTot, coords[0], 1, m_zta[0], 1, coords[0], 1);
140  Vmath::Vadd(physTot, coords[1], 1, m_eta[0], 1, coords[1], 1);
141  // Copy velocities
142  Vmath::Vcopy(physTot, m_zta[1], 1, coordsVel[0], 1);
143  Vmath::Vcopy(physTot, m_eta[1], 1, coordsVel[1], 1);
144 
145  // Update mapping
146  m_mapping->UpdateMapping(time, coords, coordsVel);
147  }
148  else if (m_vdim == 0)
149  {
150  // For forced vibration case, load from specified file or function
151  size_t cnt = 0;
152  for (size_t j = 0; j < m_funcName.size(); j++)
153  {
154  if (m_IsFromFile[cnt] && m_IsFromFile[cnt + 1])
155  {
156  ASSERTL0(false, "Motion loading from file needs specific "
157  "implementation: Work in Progress!");
158  }
159  else
160  {
161  GetFunction(pFields, m_session, m_funcName[j], true)
162  ->Evaluate(m_motion[0], m_zta[j], time);
163  GetFunction(pFields, m_session, m_funcName[j], true)
164  ->Evaluate(m_motion[1], m_eta[j], time);
165  cnt = cnt + 2;
166  }
167  }
168 
169  // Update mapping
170  m_mapping->UpdateMapping(time);
171 
172  // Convert result from mapping
173  size_t physTot = pFields[0]->GetTotPoints();
174  Array<OneD, Array<OneD, NekDouble>> coords(3);
175  Array<OneD, Array<OneD, NekDouble>> coordsVel(3);
176  for (size_t i = 0; i < 3; i++)
177  {
178  coords[i] = Array<OneD, NekDouble>(physTot, 0.0);
179  coordsVel[i] = Array<OneD, NekDouble>(physTot, 0.0);
180  }
181  // Get original coordinates
182  pFields[0]->GetCoords(coords[0], coords[1], coords[2]);
183 
184  // Get Coordinates and coord velocity from mapping
185  m_mapping->GetCartesianCoordinates(m_zta[0], m_eta[0], coords[2]);
186  m_mapping->GetCoordVelocity(coordsVel);
187 
188  // Calculate displacement
189  Vmath::Vsub(physTot, m_zta[0], 1, coords[0], 1, m_zta[0], 1);
190  Vmath::Vsub(physTot, m_eta[0], 1, coords[1], 1, m_eta[0], 1);
191 
192  Vmath::Vcopy(physTot, coordsVel[0], 1, m_zta[1], 1);
193  Vmath::Vcopy(physTot, coordsVel[1], 1, m_eta[1], 1);
194 
195  for (size_t var = 0; var < 3; var++)
196  {
197  for (size_t plane = 0; plane < m_np; plane++)
198  {
199  size_t n = pFields[0]->GetPlane(plane)->GetTotPoints();
200  size_t offset = plane * n;
201  size_t Offset = var * m_np + plane;
202 
203  m_MotionVars[0][Offset] = m_zta[var][offset];
204  m_MotionVars[1][Offset] = m_eta[var][offset];
205  }
206  }
207  }
208  else
209  {
210  ASSERTL0(false, "Unrecogized vibration type for cable's dynamic model");
211  }
212 
213  LibUtilities::CommSharedPtr vcomm = pFields[0]->GetComm();
214  size_t colrank = vcomm->GetColumnComm()->GetRank();
215  // Pass the variables of the cable's motion to the movingbody filter
216  if (colrank == 0)
217  {
218  size_t n = m_MotionVars[0].size();
219  Array<OneD, NekDouble> tmpArray(2 * n), tmp(n);
220  Vmath::Vcopy(n, m_MotionVars[0], 1, tmpArray, 1);
221  Vmath::Vcopy(n, m_MotionVars[1], 1, tmp = tmpArray + n, 1);
222  m_MovBodyfilter->UpdateMotion(m_session, pFields, tmpArray, time);
223  }
224 }
GlobalMapping::MappingSharedPtr m_mapping
void EvaluateStructDynModel(const Array< OneD, MultiRegions::ExpListSharedPtr > &pFields, Array< OneD, NekDouble > &Hydroforces, NekDouble time)
SOLVER_UTILS_EXPORT SessionFunctionSharedPtr GetFunction(const Array< OneD, MultiRegions::ExpListSharedPtr > &pFields, const LibUtilities::SessionReaderSharedPtr &pSession, std::string pName, bool pCache=false)
Get a SessionFunction by name.
Definition: Forcing.cpp:190
void Vadd(int n, const T *x, const int incx, const T *y, const int incy, T *z, const int incz)
Add vector z = x+y.
Definition: Vmath.cpp:359
void Vsub(int n, const T *x, const int incx, const T *y, const int incy, T *z, const int incz)
Subtract vector z = x-y.
Definition: Vmath.cpp:419

References ASSERTL0, EvaluateStructDynModel(), Nektar::SolverUtils::Forcing::GetFunction(), m_eta, m_funcName, m_IsFromFile, m_mapping, m_motion, m_MotionVars, m_MovBodyfilter, m_np, Nektar::SolverUtils::Forcing::m_session, m_vdim, m_zta, Vmath::Vadd(), Vmath::Vcopy(), and Vmath::Vsub().

◆ v_InitObject()

void Nektar::ForcingMovingBody::v_InitObject ( const Array< OneD, MultiRegions::ExpListSharedPtr > &  pFields,
const unsigned int &  pNumForcingFields,
const TiXmlElement *  pForce 
)
overrideprotectedvirtual

Implements Nektar::SolverUtils::Forcing.

Definition at line 55 of file ForcingMovingBody.cpp.

58 {
59  boost::ignore_unused(pNumForcingFields);
60 
61  // Just 3D homogenous 1D problems can use this techinque
62  ASSERTL0(pFields[0]->GetExpType() == MultiRegions::e3DH1D,
63  "Moving body implemented just for 3D Homogenous 1D expansions.");
64 
65  // At this point we know in the xml file where those quantities
66  // are declared (equation or file) - via a function name which is now
67  // stored in funcNameD etc. We need now to fill in with this info the
68  // m_zta and m_eta vectors (actuallythey are matrices) Array to control if
69  // the motion is determined by an equation or is from a file.(not Nektar++)
70  // check if we need to load a file or we have an equation
71  CheckIsFromFile(pForce);
72 
73  // Initialise movingbody filter
74  InitialiseFilter(m_session, pFields, pForce);
75 
76  // Initialise the cable model
78 
79  // Load mapping
81  m_mapping->SetTimeDependent(true);
82 
83  if (m_vdim > 0)
84  {
85  m_mapping->SetFromFunction(false);
86  }
87 
88  m_zta = Array<OneD, Array<OneD, NekDouble>>(3);
89  m_eta = Array<OneD, Array<OneD, NekDouble>>(3);
90  // What are this bi-dimensional vectors
91  // ------------------------------------------ m_zta[0] = m_zta | m_eta[0] =
92  // m_eta | m_zta[1] = d(m_zta)/dt |
93  // m_eta[1] = d(m_eta)/dt | m_zta[2] = dd(m_zta)/ddtt |
94  // m_eta[2] = dd(m_eta)/ddtt |
95  //--------------------------------------------------------------------------------
96  size_t phystot = pFields[0]->GetTotPoints();
97  for (size_t i = 0; i < m_zta.size(); i++)
98  {
99  m_zta[i] = Array<OneD, NekDouble>(phystot, 0.0);
100  m_eta[i] = Array<OneD, NekDouble>(phystot, 0.0);
101  }
102 }
void CheckIsFromFile(const TiXmlElement *pForce)
void InitialiseCableModel(const LibUtilities::SessionReaderSharedPtr &pSession, const Array< OneD, MultiRegions::ExpListSharedPtr > &pFields)
void InitialiseFilter(const LibUtilities::SessionReaderSharedPtr &pSession, const Array< OneD, MultiRegions::ExpListSharedPtr > &pFields, const TiXmlElement *pForce)
static GLOBAL_MAPPING_EXPORT MappingSharedPtr Load(const LibUtilities::SessionReaderSharedPtr &pSession, const Array< OneD, MultiRegions::ExpListSharedPtr > &pFields)
Return a pointer to the mapping, creating it on first call.
Definition: Mapping.cpp:270

References ASSERTL0, CheckIsFromFile(), Nektar::MultiRegions::e3DH1D, InitialiseCableModel(), InitialiseFilter(), Nektar::GlobalMapping::Mapping::Load(), m_eta, m_mapping, Nektar::SolverUtils::Forcing::m_session, m_vdim, and m_zta.

Friends And Related Function Documentation

◆ MemoryManager< ForcingMovingBody >

friend class MemoryManager< ForcingMovingBody >
friend

Definition at line 1 of file ForcingMovingBody.h.

Member Data Documentation

◆ className

std::string Nektar::ForcingMovingBody::className
static
Initial value:
=
"MovingBody", ForcingMovingBody::create, "Moving Body Forcing")
static SolverUtils::ForcingSharedPtr create(const LibUtilities::SessionReaderSharedPtr &pSession, const std::weak_ptr< SolverUtils::EquationSystem > &pEquation, const Array< OneD, MultiRegions::ExpListSharedPtr > &pFields, const unsigned int &pNumForcingFields, const TiXmlElement *pForce)
Creates an instance of this class.
tKey RegisterCreatorFunction(tKey idKey, CreatorFunction classCreator, std::string pDesc="")
Register a class with the factory.
Definition: NekFactory.hpp:198
ForcingFactory & GetForcingFactory()
Declaration of the forcing factory singleton.
Definition: Forcing.cpp:44

Name of the class.

Definition at line 69 of file ForcingMovingBody.h.

◆ m_Aeroforces

Array<OneD, NekDouble> Nektar::ForcingMovingBody::m_Aeroforces
private

storage for the cable's force(x,y) variables

Definition at line 130 of file ForcingMovingBody.h.

◆ m_CoeffMat_A

Array<OneD, DNekMatSharedPtr> Nektar::ForcingMovingBody::m_CoeffMat_A
private

matrices in Newmart-beta method

Definition at line 138 of file ForcingMovingBody.h.

Referenced by Newmark_betaSolver(), and SetDynEqCoeffMatrix().

◆ m_CoeffMat_B

Array<OneD, DNekMatSharedPtr> Nektar::ForcingMovingBody::m_CoeffMat_B
private

matrices in Newmart-beta method

Definition at line 140 of file ForcingMovingBody.h.

Referenced by Newmark_betaSolver(), and SetDynEqCoeffMatrix().

◆ m_eta

Array<OneD, Array<OneD, NekDouble> > Nektar::ForcingMovingBody::m_eta
private

Store the derivatives of motion variables in y-direction.

Definition at line 150 of file ForcingMovingBody.h.

Referenced by EvaluateStructDynModel(), v_Apply(), and v_InitObject().

◆ m_fA

Array<OneD, Array<OneD, Array<OneD, NekDouble> > > Nektar::ForcingMovingBody::m_fA
private

fictitious acceleration storage

Definition at line 136 of file ForcingMovingBody.h.

Referenced by EvaluateStructDynModel(), and InitialiseCableModel().

◆ m_FFT

LibUtilities::NektarFFTSharedPtr Nektar::ForcingMovingBody::m_FFT
private

Definition at line 126 of file ForcingMovingBody.h.

Referenced by InitialiseCableModel(), and Newmark_betaSolver().

◆ m_funcName

Array<OneD, std::string> Nektar::ForcingMovingBody::m_funcName
private

[0] is displacements, [1] is velocities, [2] is accelerations

Definition at line 142 of file ForcingMovingBody.h.

Referenced by CheckIsFromFile(), InitialiseCableModel(), and v_Apply().

◆ m_fV

Array<OneD, Array<OneD, Array<OneD, NekDouble> > > Nektar::ForcingMovingBody::m_fV
private

fictitious velocity storage

Definition at line 134 of file ForcingMovingBody.h.

Referenced by EvaluateStructDynModel(), and InitialiseCableModel().

◆ m_IsFromFile

Array<OneD, bool> Nektar::ForcingMovingBody::m_IsFromFile
private

do determine if the the body motion come from an extern file

Definition at line 146 of file ForcingMovingBody.h.

Referenced by CheckIsFromFile(), InitialiseCableModel(), and v_Apply().

◆ m_kinvis

NekDouble Nektar::ForcingMovingBody::m_kinvis
private

fluid viscous

Definition at line 123 of file ForcingMovingBody.h.

Referenced by InitialiseCableModel().

◆ m_lhom

NekDouble Nektar::ForcingMovingBody::m_lhom
private

length ratio of the cable

Definition at line 122 of file ForcingMovingBody.h.

Referenced by InitialiseCableModel(), and SetDynEqCoeffMatrix().

◆ m_mapping

GlobalMapping::MappingSharedPtr Nektar::ForcingMovingBody::m_mapping
protected

Definition at line 73 of file ForcingMovingBody.h.

Referenced by v_Apply(), and v_InitObject().

◆ m_motion

Array<OneD, std::string> Nektar::ForcingMovingBody::m_motion
private

motion direction: [0] is 'x' and [1] is 'y'

Definition at line 144 of file ForcingMovingBody.h.

Referenced by CheckIsFromFile(), EvaluateStructDynModel(), InitialiseCableModel(), and v_Apply().

◆ m_MotionVars

Array<OneD, Array<OneD, NekDouble> > Nektar::ForcingMovingBody::m_MotionVars
private

storage for the cable's motion(x,y) variables

Definition at line 132 of file ForcingMovingBody.h.

Referenced by EvaluateStructDynModel(), InitialiseCableModel(), and v_Apply().

◆ m_MovBodyfilter

FilterMovingBodySharedPtr Nektar::ForcingMovingBody::m_MovBodyfilter
private

Definition at line 128 of file ForcingMovingBody.h.

Referenced by InitialiseFilter(), and v_Apply().

◆ m_movingBodyCalls

size_t Nektar::ForcingMovingBody::m_movingBodyCalls
private

number of times the movbody have been called

Definition at line 116 of file ForcingMovingBody.h.

Referenced by EvaluateStructDynModel(), and InitialiseCableModel().

◆ m_np

size_t Nektar::ForcingMovingBody::m_np
private

number of planes per processors

Definition at line 117 of file ForcingMovingBody.h.

Referenced by EvaluateStructDynModel(), InitialiseCableModel(), and v_Apply().

◆ m_outputFile_fce

std::string Nektar::ForcingMovingBody::m_outputFile_fce
private

Definition at line 154 of file ForcingMovingBody.h.

◆ m_outputFile_mot

std::string Nektar::ForcingMovingBody::m_outputFile_mot
private

Definition at line 155 of file ForcingMovingBody.h.

◆ m_outputFrequency

unsigned int Nektar::ForcingMovingBody::m_outputFrequency
private

Definition at line 152 of file ForcingMovingBody.h.

◆ m_outputStream

Array<OneD, std::ofstream> Nektar::ForcingMovingBody::m_outputStream
private

Definition at line 153 of file ForcingMovingBody.h.

◆ m_structdamp

NekDouble Nektar::ForcingMovingBody::m_structdamp
private

damping ratio of the cable

Definition at line 121 of file ForcingMovingBody.h.

Referenced by InitialiseCableModel(), and SetDynEqCoeffMatrix().

◆ m_structrho

NekDouble Nektar::ForcingMovingBody::m_structrho
private

mass of the cable per unit length

Definition at line 120 of file ForcingMovingBody.h.

Referenced by InitialiseCableModel(), Newmark_betaSolver(), and SetDynEqCoeffMatrix().

◆ m_timestep

NekDouble Nektar::ForcingMovingBody::m_timestep
private

time step

Definition at line 124 of file ForcingMovingBody.h.

Referenced by InitialiseCableModel(), and SetDynEqCoeffMatrix().

◆ m_vdim

size_t Nektar::ForcingMovingBody::m_vdim
private

vibration dimension

Definition at line 118 of file ForcingMovingBody.h.

Referenced by EvaluateStructDynModel(), InitialiseCableModel(), v_Apply(), and v_InitObject().

◆ m_zta

Array<OneD, Array<OneD, NekDouble> > Nektar::ForcingMovingBody::m_zta
private

Store the derivatives of motion variables in x-direction.

Definition at line 148 of file ForcingMovingBody.h.

Referenced by EvaluateStructDynModel(), v_Apply(), and v_InitObject().