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

void v_InitObject (const Array< OneD, MultiRegions::ExpListSharedPtr > &pFields, const unsigned int &pNumForcingFields, const TiXmlElement *pForce) override
 
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_InitObject (const Array< OneD, MultiRegions::ExpListSharedPtr > &pFields, const unsigned int &pNumForcingFields, const TiXmlElement *pForce)=0
 
virtual SOLVER_UTILS_EXPORT 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)=0
 
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
 

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:48

Member Function Documentation

◆ CheckIsFromFile()

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

Definition at line 1066 of file ForcingMovingBody.cpp.

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

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:53

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 227 of file ForcingMovingBody.cpp.

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

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 679 of file ForcingMovingBody.cpp.

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

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 1216 of file ForcingMovingBody.cpp.

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

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 551 of file ForcingMovingBody.cpp.

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

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 1048 of file ForcingMovingBody.cpp.

1049{
1050 size_t nlevels = input.size();
1051
1052 Array<OneD, NekDouble> tmp;
1053 tmp = input[nlevels - 1];
1054
1055 for (size_t n = nlevels - 1; n > 0; --n)
1056 {
1057 input[n] = input[n - 1];
1058 }
1059
1060 input[0] = tmp;
1061}

Referenced by EvaluateStructDynModel().

◆ SetDynEqCoeffMatrix()

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

Definition at line 943 of file ForcingMovingBody.cpp.

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

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 103 of file ForcingMovingBody.cpp.

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

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.

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

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:197
ForcingFactory & GetForcingFactory()
Declaration of the forcing factory singleton.
Definition: Forcing.cpp:42

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 129 of file ForcingMovingBody.h.

◆ m_CoeffMat_A

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

matrices in Newmart-beta method

Definition at line 137 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 139 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 149 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 135 of file ForcingMovingBody.h.

Referenced by EvaluateStructDynModel(), and InitialiseCableModel().

◆ m_FFT

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

Definition at line 125 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 141 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 133 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 145 of file ForcingMovingBody.h.

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

◆ m_kinvis

NekDouble Nektar::ForcingMovingBody::m_kinvis
private

fluid viscous

Definition at line 122 of file ForcingMovingBody.h.

Referenced by InitialiseCableModel().

◆ m_lhom

NekDouble Nektar::ForcingMovingBody::m_lhom
private

length ratio of the cable

Definition at line 121 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 143 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 131 of file ForcingMovingBody.h.

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

◆ m_MovBodyfilter

FilterMovingBodySharedPtr Nektar::ForcingMovingBody::m_MovBodyfilter
private

Definition at line 127 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 115 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 116 of file ForcingMovingBody.h.

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

◆ m_outputFrequency

unsigned int Nektar::ForcingMovingBody::m_outputFrequency
private

Definition at line 151 of file ForcingMovingBody.h.

◆ m_structdamp

NekDouble Nektar::ForcingMovingBody::m_structdamp
private

damping ratio of the cable

Definition at line 120 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 119 of file ForcingMovingBody.h.

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

◆ m_timestep

NekDouble Nektar::ForcingMovingBody::m_timestep
private

time step

Definition at line 123 of file ForcingMovingBody.h.

Referenced by InitialiseCableModel(), and SetDynEqCoeffMatrix().

◆ m_vdim

size_t Nektar::ForcingMovingBody::m_vdim
private

vibration dimension

Definition at line 117 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 147 of file ForcingMovingBody.h.

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