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

#include <ForcingMovingReferenceFrame.h>

Inheritance diagram for Nektar::SolverUtils::ForcingMovingReferenceFrame:
[legend]

Static Public Member Functions

static SOLVER_UTILS_EXPORT ForcingSharedPtr create (const LibUtilities::SessionReaderSharedPtr &pSession, const std::weak_ptr< 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 classNameBody
 Name of the class. More...
 

Protected Member Functions

SOLVER_UTILS_EXPORT void v_InitObject (const Array< OneD, MultiRegions::ExpListSharedPtr > &pFields, const unsigned int &pNumForcingFields, const TiXmlElement *pForce) override
 Initialise the forcing module. More...
 
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) override
 Adds the body force, -Omega X u. More...
 
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) 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)
 

Private Member Functions

 ForcingMovingReferenceFrame (const LibUtilities::SessionReaderSharedPtr &pSession, const std::weak_ptr< EquationSystem > &pEquation)
 
 ~ForcingMovingReferenceFrame (void) override
 
void Update (const Array< OneD, MultiRegions::ExpListSharedPtr > &pFields, const NekDouble &time)
 Updates the forcing array with the current required forcing. More...
 
void UpdateRotMat ()
 
void CheckForRestartTime (const Array< OneD, MultiRegions::ExpListSharedPtr > &pFields, NekDouble &time)
 
void addRotation (int npoints, const Array< OneD, Array< OneD, NekDouble > > &inarray0, NekDouble angVelScale, const Array< OneD, Array< OneD, NekDouble > > &inarray1, Array< OneD, Array< OneD, NekDouble > > &outarray)
 outarray = inarray0 + angVelScale Omega x inarray1 More...
 
void InitBodySolver (const TiXmlElement *pForce, const int dim, const int rank, const NekDouble time)
 
void SolveBodyMotion (Array< OneD, Array< OneD, NekDouble > > &bodyVel, const Array< OneD, NekDouble > &forcebody, std::map< int, NekDouble > &Dirs)
 
void LoadParameters (const TiXmlElement *pForce, const NekDouble time)
 
NekDouble EvaluateExpression (std::string expression)
 
void InitialiseFilter (const LibUtilities::SessionReaderSharedPtr &pSession, const Array< OneD, MultiRegions::ExpListSharedPtr > &pFields, const TiXmlElement *pForce)
 
void UpdateBoundaryConditions (NekDouble time)
 Set velocity boundary condition at the next time step. More...
 

Private Attributes

Array< OneD, NekDoublem_pivotPoint
 
Array< OneD, NekDoublem_travelWave
 
FrameTransform m_frame
 
std::map< int, LibUtilities::EquationSharedPtrm_frameVelFunction
 
std::map< int, LibUtilities::EquationSharedPtrm_extForceFunction
 
std::ofstream m_outputStream
 
int m_rank
 
Array< OneD, bool > m_hasVel
 
Array< OneD, bool > m_hasOmega
 
Array< OneD, NekDoublem_velXYZ
 
Array< OneD, NekDoublem_velxyz
 
Array< OneD, NekDoublem_omegaXYZ
 
Array< OneD, NekDoublem_omegaxyz
 
Array< OneD, Array< OneD, NekDouble > > m_coords
 
Array< OneD, NekDoublem_extForceXYZ
 
Array< OneD, NekDoublem_disp
 
bn::ublas::matrix< NekDoublem_ProjMatZ
 
NekDouble m_startTime
 
NekDouble m_timestep
 
bool m_hasRotation
 
bool m_isH1d
 
bool m_hasPlane0
 
bool m_isH2d
 
bool m_hasFreeMotion
 
NekInt m_spacedim
 
NekInt m_expdim
 
unsigned int m_index
 
unsigned int m_outputFrequency
 
Newmark_BetaSolver m_bodySolver
 
Array< OneD, Array< OneD, NekDouble > > m_bodyVel
 
std::set< int > m_DirDoFs
 
FilterAeroForcesSharedPtr m_aeroforceFilter
 

Friends

class MemoryManager< ForcingMovingReferenceFrame >
 

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 ()
 
- 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...
 

Detailed Description

Definition at line 100 of file ForcingMovingReferenceFrame.h.

Constructor & Destructor Documentation

◆ ForcingMovingReferenceFrame()

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

Definition at line 66 of file ForcingMovingReferenceFrame.cpp.

69 : Forcing(pSession, pEquation)
70{
71}
SOLVER_UTILS_EXPORT Forcing(const LibUtilities::SessionReaderSharedPtr &pSession, const std::weak_ptr< EquationSystem > &pEquation)
Constructor.
Definition: Forcing.cpp:48

◆ ~ForcingMovingReferenceFrame()

Nektar::SolverUtils::ForcingMovingReferenceFrame::~ForcingMovingReferenceFrame ( void  )
overrideprivate

Member Function Documentation

◆ addRotation()

void Nektar::SolverUtils::ForcingMovingReferenceFrame::addRotation ( int  npoints,
const Array< OneD, Array< OneD, NekDouble > > &  inarray0,
NekDouble  angVelScale,
const Array< OneD, Array< OneD, NekDouble > > &  inarray1,
Array< OneD, Array< OneD, NekDouble > > &  outarray 
)
private

outarray = inarray0 + angVelScale Omega x inarray1

Definition at line 840 of file ForcingMovingReferenceFrame.cpp.

845{
846 ASSERTL0(&inarray1 != &outarray, "inarray1 and outarray "
847 "should not be the same.");
848
849 // TODO: In case of having support for all three components of Omega,
850 // they should be transformed into the rotating frame first!
851
852 // In case that the inarray0 and outarry are different, to avoid using
853 // un-initialized array, copy the array first
854 if (&inarray0 != &outarray)
855 {
856 ASSERTL0(inarray0.size() == outarray.size(),
857 "inarray0 and outarray must have same dimentions");
858 for (int i = 0; i < inarray0.size(); ++i)
859 {
860 Vmath::Vcopy(nPnts, inarray0[i], 1, outarray[i], 1);
861 }
862 }
863
864 if (m_spacedim >= 2 && m_hasOmega[2])
865 {
866 NekDouble cp = m_omegaxyz[2] * angVelScale;
867 NekDouble cm = -1. * cp;
868
869 Vmath::Svtvp(nPnts, cm, inarray1[1], 1, outarray[0], 1, outarray[0], 1);
870 Vmath::Svtvp(nPnts, cp, inarray1[0], 1, outarray[1], 1, outarray[1], 1);
871 }
872
873 if (m_spacedim == 3 && m_hasOmega[0])
874 {
875 NekDouble cp = m_omegaxyz[0] * angVelScale;
876 NekDouble cm = -1. * cp;
877
878 Vmath::Svtvp(nPnts, cp, inarray1[1], 1, outarray[2], 1, outarray[2], 1);
879 Vmath::Svtvp(nPnts, cm, inarray1[2], 1, outarray[1], 1, outarray[1], 1);
880 }
881
882 if (m_spacedim == 3 && m_hasOmega[1])
883 {
884 NekDouble cp = m_omegaxyz[1] * angVelScale;
885 NekDouble cm = -1. * cp;
886
887 Vmath::Svtvp(nPnts, cp, inarray1[2], 1, outarray[0], 1, outarray[0], 1);
888 Vmath::Svtvp(nPnts, cm, inarray1[0], 1, outarray[2], 1, outarray[2], 1);
889 }
890}
#define ASSERTL0(condition, msg)
Definition: ErrorUtil.hpp:208
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 Vcopy(int n, const T *x, const int incx, T *y, const int incy)
Definition: Vmath.hpp:825

References ASSERTL0, m_hasOmega, m_omegaxyz, m_spacedim, Vmath::Svtvp(), and Vmath::Vcopy().

Referenced by v_Apply(), and v_PreApply().

◆ CheckForRestartTime()

void Nektar::SolverUtils::ForcingMovingReferenceFrame::CheckForRestartTime ( const Array< OneD, MultiRegions::ExpListSharedPtr > &  pFields,
NekDouble time 
)
private

Definition at line 949 of file ForcingMovingReferenceFrame.cpp.

951{
952 std::map<std::string, std::string> fieldMetaDataMap;
953 if (m_session->DefinesFunction("InitialConditions"))
954 {
955 for (int i = 0; i < pFields.size(); ++i)
956 {
958
959 vType = m_session->GetFunctionType("InitialConditions",
960 m_session->GetVariable(i));
961
963 {
964 std::string filename = m_session->GetFunctionFilename(
965 "InitialConditions", m_session->GetVariable(i));
966
967 fs::path pfilename(filename);
968
969 // redefine path for parallel file which is in directory
970 if (fs::is_directory(pfilename))
971 {
972 fs::path metafile("Info.xml");
973 fs::path fullpath = pfilename / metafile;
974 filename = LibUtilities::PortablePath(fullpath);
975 }
978 fld->ImportFieldMetaData(filename, fieldMetaDataMap);
979
980 // check to see if time is defined
981 if (fieldMetaDataMap != LibUtilities::NullFieldMetaDataMap)
982 {
983 std::string strt = "Time";
984 if (fieldMetaDataMap.find(strt) != fieldMetaDataMap.end())
985 {
986 time = boost::lexical_cast<NekDouble>(
987 fieldMetaDataMap[strt]);
988 break;
989 }
990 }
991 }
992 }
993 }
994}
static std::shared_ptr< FieldIO > CreateForFile(const LibUtilities::SessionReaderSharedPtr session, const std::string &filename)
Construct a FieldIO object for a given input filename.
Definition: FieldIO.cpp:224
LibUtilities::SessionReaderSharedPtr m_session
Session reader.
Definition: Forcing.h:115
std::shared_ptr< FieldIO > FieldIOSharedPtr
Definition: FieldIO.h:322
static std::string PortablePath(const fs::path &path)
create portable path on different platforms for std::filesystem path.
Definition: Filesystem.hpp:56
static FieldMetaDataMap NullFieldMetaDataMap
Definition: FieldIO.h:51

References Nektar::LibUtilities::FieldIO::CreateForFile(), Nektar::LibUtilities::eFunctionTypeFile, Nektar::SolverUtils::Forcing::m_session, Nektar::LibUtilities::NullFieldMetaDataMap, and Nektar::LibUtilities::PortablePath().

Referenced by v_InitObject().

◆ create()

static SOLVER_UTILS_EXPORT ForcingSharedPtr Nektar::SolverUtils::ForcingMovingReferenceFrame::create ( const LibUtilities::SessionReaderSharedPtr pSession,
const std::weak_ptr< 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 107 of file ForcingMovingReferenceFrame.h.

112 {
115 pSession, pEquation);
116 p->InitObject(pFields, pNumForcingFields, pForce);
117 return p;
118 }
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.

◆ EvaluateExpression()

NekDouble Nektar::SolverUtils::ForcingMovingReferenceFrame::EvaluateExpression ( std::string  expression)
private

Definition at line 204 of file ForcingMovingReferenceFrame.cpp.

206{
207 NekDouble value = 0.;
208 try
209 {
210 LibUtilities::Equation expession(m_session->GetInterpreter(),
211 expression);
212 value = expession.Evaluate();
213 }
214 catch (const std::runtime_error &)
215 {
216 NEKERROR(ErrorUtil::efatal, "Error evaluating expression" + expression);
217 }
218 return value;
219}
#define NEKERROR(type, msg)
Assert Level 0 – Fundamental assert which is used whether in FULLDEBUG, DEBUG or OPT compilation mode...
Definition: ErrorUtil.hpp:202

References Nektar::ErrorUtil::efatal, Nektar::LibUtilities::Equation::Evaluate(), Nektar::SolverUtils::Forcing::m_session, and NEKERROR.

Referenced by InitBodySolver(), and LoadParameters().

◆ InitBodySolver()

void Nektar::SolverUtils::ForcingMovingReferenceFrame::InitBodySolver ( const TiXmlElement *  pForce,
const int  dim,
const int  rank,
const NekDouble  time 
)
private

Definition at line 363 of file ForcingMovingReferenceFrame.cpp.

366{
367 int NumDof = dim + 1;
368 std::set<int> DirBCs;
369 const TiXmlElement *mssgTag;
370 std::string mssgStr;
371 // read free motion DoFs
372 m_DirDoFs.clear();
373 for (int i = 0; i < NumDof; ++i)
374 {
375 m_DirDoFs.insert(i);
376 }
377 mssgTag = pForce->FirstChildElement("MOTIONPRESCRIBED");
378 if (mssgTag)
379 {
380 std::vector<std::string> values;
381 mssgStr = mssgTag->GetText();
382 ParseUtils::GenerateVector(mssgStr, values);
383 ASSERTL0(values.size() >= NumDof,
384 "MOTIONPRESCRIBED vector should be of size " +
385 std::to_string(NumDof));
386 for (int i = 0; i < NumDof; ++i)
387 {
388 if (EvaluateExpression(values[i]) == 0)
389 {
390 m_DirDoFs.erase(i);
391 if (i < dim)
392 {
393 m_hasVel[i] = true;
394 }
395 else if (i == dim)
396 {
397 m_hasOmega[2] = true;
398 }
399 }
400 }
401 }
402 m_hasFreeMotion = m_DirDoFs.size() < NumDof;
403 // read mass matrix
406 mssgTag = pForce->FirstChildElement("MASS");
407 ASSERTL0(m_DirDoFs.size() == NumDof || mssgTag, "Mass matrix is required.");
408 if (mssgTag)
409 {
410 std::vector<std::string> values;
411 mssgStr = mssgTag->GetText();
412 ParseUtils::GenerateVector(mssgStr, values);
413 ASSERTL0(values.size() >= NumDof * NumDof,
414 "Mass matrix should be of size " + std::to_string(NumDof) +
415 "X" + std::to_string(NumDof));
416 for (int i = 0; i < NumDof; ++i)
417 {
418 for (int j = 0; j < NumDof; ++j)
419 {
420 M->SetValue(i, j, EvaluateExpression(values[i * NumDof + j]));
421 }
422 }
423 }
424 // read damping matrix
427 mssgTag = pForce->FirstChildElement("DAMPING");
428 if (mssgTag)
429 {
430 std::vector<std::string> values;
431 mssgStr = mssgTag->GetText();
432 ParseUtils::GenerateVector(mssgStr, values);
433 ASSERTL0(values.size() >= NumDof * NumDof,
434 "Damping matrix should be of size " + std::to_string(NumDof) +
435 "X" + std::to_string(NumDof));
436 for (int i = 0; i < NumDof; ++i)
437 {
438 for (int j = 0; j < NumDof; ++j)
439 {
440 C->SetValue(i, j, EvaluateExpression(values[i * NumDof + j]));
441 }
442 }
443 }
444 // read rigidity matrix
447 mssgTag = pForce->FirstChildElement("RIGIDITY");
448 if (mssgTag)
449 {
450 std::vector<std::string> values;
451 mssgStr = mssgTag->GetText();
452 ParseUtils::GenerateVector(mssgStr, values);
453 ASSERTL0(values.size() >= NumDof * NumDof,
454 "Rigidity matrix should be of size " + std::to_string(NumDof) +
455 "X" + std::to_string(NumDof));
456 for (int i = 0; i < NumDof; ++i)
457 {
458 for (int j = 0; j < NumDof; ++j)
459 {
460 K->SetValue(i, j, EvaluateExpression(values[i * NumDof + j]));
461 }
462 }
463 }
464 // read Newmark Beta paramters
465 m_timestep = m_session->GetParameter("TimeStep");
466 NekDouble beta = 0.25;
467 NekDouble gamma = 0.75;
468 if (m_session->DefinesParameter("NewmarkBeta"))
469 {
470 beta = m_session->GetParameter("NewmarkBeta");
471 }
472 if (m_session->DefinesParameter("NewmarkGamma"))
473 {
474 gamma = m_session->GetParameter("NewmarkGamma");
475 }
477 // OutputFile
478 string filename;
479 mssgTag = pForce->FirstChildElement("OutputFile");
480 if (mssgTag)
481 {
482 filename = mssgTag->GetText();
483 }
484 else
485 {
486 filename = m_session->GetSessionName();
487 }
488 if (!(filename.length() >= 4 &&
489 filename.substr(filename.length() - 4) == ".mrf"))
490 {
491 filename += ".mrf";
492 }
493 if (rank == 0)
494 {
495 m_outputStream.open(filename.c_str());
496 if (dim == 2)
497 {
499 << "Variables = t, x, ux, ax, y, uy, ay, theta, omega, domega"
500 << endl;
501 }
502 else if (dim == 3)
503 {
504 m_outputStream << "Variables = t, x, ux, ax, y, uy, ay, z, uz, az, "
505 "theta, omega, domega"
506 << endl;
507 }
508 }
509 // output frequency
510 m_index = 0;
512 mssgTag = pForce->FirstChildElement("OutputFrequency");
513 if (mssgTag)
514 {
515 std::vector<std::string> values;
516 mssgStr = mssgTag->GetText();
517 m_outputFrequency = round(EvaluateExpression(mssgStr));
518 }
520 "OutputFrequency should be greater than zero.");
521 // initialize displacement velocity
522 m_bodyVel = Array<OneD, Array<OneD, NekDouble>>(3);
523 for (size_t i = 0; i < 3; ++i)
524 {
525 m_bodyVel[i] = Array<OneD, NekDouble>(NumDof, 0.);
526 }
527 for (int i = 0; i < m_spacedim; ++i)
528 {
529 m_bodyVel[0][i] = m_disp[i];
530 }
531 m_bodyVel[0][NumDof - 1] = m_disp[5];
532 for (auto it : m_frameVelFunction)
533 {
534 if (it.first < 3)
535 {
536 m_bodyVel[1][it.first] = it.second->Evaluate(0., 0., 0., time);
537 }
538 else if (it.first == 5)
539 {
540 m_bodyVel[1][NumDof - 1] = it.second->Evaluate(0., 0., 0., time);
541 }
542 }
543}
static bool GenerateVector(const std::string &str, std::vector< T > &out)
Takes a comma-separated string and converts it to entries in a vector.
Definition: ParseUtils.cpp:130
std::map< int, LibUtilities::EquationSharedPtr > m_frameVelFunction
void SetNewmarkBeta(NekDouble beta, NekDouble gamma, NekDouble dt, DNekMatSharedPtr M, DNekMatSharedPtr C, DNekMatSharedPtr K, std::set< int > DirDoFs)
@ beta
Gauss Radau pinned at x=-1,.
Definition: PointsType.h:59
std::shared_ptr< DNekMat > DNekMatSharedPtr
Definition: NekTypeDefs.hpp:75

References Nektar::MemoryManager< DataType >::AllocateSharedPtr(), ASSERTL0, Nektar::LibUtilities::beta, Nektar::eFULL, EvaluateExpression(), Nektar::ParseUtils::GenerateVector(), m_bodySolver, m_bodyVel, m_DirDoFs, m_disp, m_frameVelFunction, m_hasFreeMotion, m_hasOmega, m_hasVel, m_index, m_outputFrequency, m_outputStream, Nektar::SolverUtils::Forcing::m_session, m_spacedim, m_timestep, and Nektar::SolverUtils::Newmark_BetaSolver::SetNewmarkBeta().

Referenced by v_InitObject().

◆ InitialiseFilter()

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

Definition at line 996 of file ForcingMovingReferenceFrame.cpp.

1000{
1001 std::map<std::string, std::string> vParams;
1002 vParams["OutputFile"] = ".dummyfilename";
1003 const TiXmlElement *param = pForce->FirstChildElement("BOUNDARY");
1004 ASSERTL0(param, "Body surface should be assigned");
1005 vParams["Boundary"] = param->GetText();
1007 pSession, m_equ, vParams);
1008 m_aeroforceFilter->Initialise(pFields, 0.0);
1009}
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, m_aeroforceFilter, and Nektar::SolverUtils::Forcing::m_equ.

Referenced by v_InitObject().

◆ LoadParameters()

void Nektar::SolverUtils::ForcingMovingReferenceFrame::LoadParameters ( const TiXmlElement *  pForce,
const NekDouble  time 
)
private

Definition at line 221 of file ForcingMovingReferenceFrame.cpp.

223{
224 const TiXmlElement *funcNameElmt;
225 // load frame velocity
226 funcNameElmt = pForce->FirstChildElement("FRAMEVELOCITY");
227 if (funcNameElmt)
228 {
229 std::string FuncName = funcNameElmt->GetText();
230 ASSERTL0(m_session->DefinesFunction(FuncName),
231 "Function '" + FuncName + "' is not defined in the session.");
232 // linear velocity
233 for (int i = 0; i < m_spacedim; ++i)
234 {
235 std::string var = m_session->GetVariable(i);
236 if (m_session->DefinesFunction(FuncName, var))
237 {
238 m_frameVelFunction[i] = m_session->GetFunction(FuncName, var);
239 m_hasVel[i] = true;
240 }
241 }
242 // angular velocities
243 m_hasRotation = false;
244 std::vector<std::string> angularVar = {"Omega_x", "Omega_y", "Omega_z"};
245 for (int i = 0; i < 3; ++i)
246 {
247 std::string var = angularVar[i];
248 if (m_session->DefinesFunction(FuncName, var))
249 {
250 m_frameVelFunction[i + 3] =
251 m_session->GetFunction(FuncName, var);
252 m_hasOmega[i] = true;
253 m_hasRotation = true;
254 }
255 }
256 // TODO: add the support for general rotation
257 for (int i = 0; i < 2; ++i)
258 {
259 ASSERTL0(!m_hasOmega[i], "Currently only Omega_z is supported");
260 }
261 }
262 if (m_expdim == 1)
263 {
264 m_hasRotation = false;
265 }
266
267 // load external force
268 funcNameElmt = pForce->FirstChildElement("EXTERNALFORCE");
269 if (funcNameElmt)
270 {
271 std::string FuncName = funcNameElmt->GetText();
272 if (m_session->DefinesFunction(FuncName))
273 {
274 std::vector<std::string> forceVar = {"fx", "fy", "fz"};
275 for (int i = 0; i < m_spacedim; ++i)
276 {
277 std::string var = forceVar[i];
278 if (m_session->DefinesFunction(FuncName, var))
279 {
281 m_session->GetFunction(FuncName, var);
282 }
283 }
284 std::vector<std::string> momentVar = {"Mx", "My", "Mz"};
285 for (int i = 0; i < 3; ++i)
286 {
287 std::string var = momentVar[i];
288 if (m_session->DefinesFunction(FuncName, var))
289 {
290 m_extForceFunction[i + 3] =
291 m_session->GetFunction(FuncName, var);
292 }
293 }
294 }
295 }
296
297 // load pitching pivot
298 const TiXmlElement *pivotElmt = pForce->FirstChildElement("PIVOTPOINT");
299 if (pivotElmt)
300 {
301 std::vector<std::string> values;
302 std::string mssgStr = pivotElmt->GetText();
303 ParseUtils::GenerateVector(mssgStr, values);
304 for (int j = 0; j < m_spacedim; ++j)
305 {
306 m_pivotPoint[j] = EvaluateExpression(values[j]);
307 m_disp[6 + j] = m_pivotPoint[j];
308 }
309 }
310
311 // load travelling wave speed
312 const TiXmlElement *TWSElmt =
313 pForce->FirstChildElement("TRAVELINGWAVESPEED");
314 if (TWSElmt)
315 {
316 std::vector<std::string> values;
317 std::string mssgStr = TWSElmt->GetText();
318 ParseUtils::GenerateVector(mssgStr, values);
319 for (int j = 0; j < m_spacedim; ++j)
320 {
321 NekDouble tmp = EvaluateExpression(values[j]);
322 if (fabs(tmp) > NekConstants::kNekMachineEpsilon)
323 {
324 m_travelWave[j] = tmp;
325 m_hasVel[j] = true;
326 }
327 }
328 }
329
330 // load initial displacement
331 std::map<int, LibUtilities::EquationSharedPtr> initDisplacement;
332 funcNameElmt = pForce->FirstChildElement("INITIALDISPLACEMENT");
333 if (funcNameElmt)
334 {
335 std::string FuncName = funcNameElmt->GetText();
336 ASSERTL0(m_session->DefinesFunction(FuncName),
337 "Function '" + FuncName + "' is not defined in the session.");
338 // linear displacement
339 std::vector<std::string> dispVar = {"x", "y", "z"};
340 for (int i = 0; i < m_spacedim; ++i)
341 {
342 std::string var = dispVar[i];
343 if (m_session->DefinesFunction(FuncName, var))
344 {
345 m_disp[i] = m_session->GetFunction(FuncName, var)
346 ->Evaluate(0., 0., 0., time);
347 }
348 }
349 // angular displacement
350 std::vector<std::string> angleVar = {"theta_x", "theta_y", "theta_z"};
351 for (int i = 0; i < 3; ++i)
352 {
353 std::string var = angleVar[i];
354 if (m_session->DefinesFunction(FuncName, var))
355 {
356 m_disp[i + 3] =
357 m_session->GetFunction(FuncName, var)->Evaluate();
358 }
359 }
360 }
361}
std::map< int, LibUtilities::EquationSharedPtr > m_extForceFunction
static const NekDouble kNekMachineEpsilon

References ASSERTL0, EvaluateExpression(), Nektar::ParseUtils::GenerateVector(), Nektar::NekConstants::kNekMachineEpsilon, m_disp, m_expdim, m_extForceFunction, m_frameVelFunction, m_hasOmega, m_hasRotation, m_hasVel, m_pivotPoint, Nektar::SolverUtils::Forcing::m_session, m_spacedim, and m_travelWave.

Referenced by v_InitObject().

◆ SolveBodyMotion()

void Nektar::SolverUtils::ForcingMovingReferenceFrame::SolveBodyMotion ( Array< OneD, Array< OneD, NekDouble > > &  bodyVel,
const Array< OneD, NekDouble > &  forcebody,
std::map< int, NekDouble > &  Dirs 
)
private

Definition at line 637 of file ForcingMovingReferenceFrame.cpp.

640{
641 if (!m_hasRotation || Dirs.find(m_spacedim) != Dirs.end())
642 {
643 Array<OneD, NekDouble> force(6, 0.), tmp;
644 if (Dirs.find(m_spacedim) != Dirs.end())
645 {
646 Array<OneD, NekDouble> angle(3, 0.);
647 angle[2] =
648 bodyVel[0][m_spacedim] +
649 0.5 * m_timestep * (bodyVel[1][m_spacedim] + Dirs[m_spacedim]);
650 m_frame.SetAngle(angle);
651 m_frame.BodyToInerital(3, forcebody, force);
652 m_frame.BodyToInerital(3, forcebody + 3, tmp = force + 3);
653 }
654 else
655 {
656 Vmath::Vcopy(6, forcebody, 1, force, 1);
657 }
658 for (int i = 0; i < m_spacedim; ++i)
659 {
660 force[i] += m_extForceXYZ[i];
661 }
662 force[m_spacedim] = force[5] + m_extForceXYZ[5];
663 m_bodySolver.Solve(bodyVel, force, Dirs);
664 }
665 else
666 {
667 Array<OneD, Array<OneD, NekDouble>> tmpbodyVel(bodyVel.size());
668 for (size_t i = 0; i < bodyVel.size(); ++i)
669 {
670 tmpbodyVel[i] = Array<OneD, NekDouble>(bodyVel[i].size());
671 }
672 Array<OneD, NekDouble> angle(3, 0.);
673 angle[2] = bodyVel[0][m_spacedim];
674 for (int iter = 0; iter < 2; ++iter)
675 {
676 // copy initial condition
677 for (size_t i = 0; i < bodyVel.size(); ++i)
678 {
679 Vmath::Vcopy(bodyVel[i].size(), bodyVel[i], 1, tmpbodyVel[i],
680 1);
681 }
682 Array<OneD, NekDouble> force(6, 0.), tmp;
683 m_frame.SetAngle(angle);
684 m_frame.BodyToInerital(3, forcebody, force);
685 m_frame.BodyToInerital(3, forcebody + 3, tmp = force + 3);
686 for (int i = 0; i < m_spacedim; ++i)
687 {
688 force[i] += m_extForceXYZ[i];
689 }
690 force[m_spacedim] = force[5] + m_extForceXYZ[5];
691 m_bodySolver.Solve(tmpbodyVel, force, Dirs);
692 angle[2] = tmpbodyVel[0][m_spacedim];
693 }
694 // copy final results
695 for (size_t i = 0; i < bodyVel.size(); ++i)
696 {
697 Vmath::Vcopy(bodyVel[i].size(), tmpbodyVel[i], 1, bodyVel[i], 1);
698 }
699 }
700}
void SetAngle(const Array< OneD, NekDouble > theta)
void BodyToInerital(const int dim, const Array< OneD, NekDouble > &body, Array< OneD, NekDouble > &inertial)
void Solve(Array< OneD, Array< OneD, NekDouble > > u, Array< OneD, NekDouble > force, std::map< int, NekDouble > motionPrescribed)

References Nektar::SolverUtils::FrameTransform::BodyToInerital(), m_bodySolver, m_extForceXYZ, m_frame, m_hasRotation, m_spacedim, m_timestep, Nektar::SolverUtils::FrameTransform::SetAngle(), Nektar::SolverUtils::Newmark_BetaSolver::Solve(), and Vmath::Vcopy().

Referenced by Update(), and UpdateBoundaryConditions().

◆ Update()

void Nektar::SolverUtils::ForcingMovingReferenceFrame::Update ( const Array< OneD, MultiRegions::ExpListSharedPtr > &  pFields,
const NekDouble time 
)
private

Updates the forcing array with the current required forcing.

Parameters
pFields
time

Definition at line 550 of file ForcingMovingReferenceFrame.cpp.

553{
554 // compute the velociites whos functions are provided in inertial frame
555 for (auto it : m_frameVelFunction)
556 {
557 if (it.first < 3)
558 {
559 m_velXYZ[it.first] = it.second->Evaluate(0., 0., 0., time);
560 }
561 else
562 {
563 m_omegaXYZ[it.first - 3] = it.second->Evaluate(0., 0., 0., time);
564 }
565 }
566 for (auto it : m_extForceFunction)
567 {
568 m_extForceXYZ[it.first] = it.second->Evaluate(0., 0., 0., time);
569 }
570 auto equ = m_equ.lock();
571 ASSERTL0(equ, "Weak pointer to the equation system is expired");
572 auto FluidEq = std::dynamic_pointer_cast<FluidInterface>(equ);
573 if (time > m_startTime)
574 {
575 Array<OneD, NekDouble> forcebody(6, 0.); // fluid force
576 std::map<int, NekDouble> Dirs; // prescribed Motion
577 for (auto it : m_DirDoFs)
578 {
579 if (it < m_spacedim)
580 {
581 Dirs[it] = m_velXYZ[it];
582 }
583 else if (it == m_spacedim)
584 {
585 Dirs[it] = m_omegaXYZ[2];
586 }
587 }
588 if (m_hasFreeMotion)
589 {
590 m_aeroforceFilter->GetForces(pFields, NullNekDouble1DArray, time);
591 }
592 FluidEq->GetAeroForce(forcebody);
593 SolveBodyMotion(m_bodyVel, forcebody, Dirs);
594 }
595 if (m_rank == 0 && m_index % m_outputFrequency == 0)
596 {
597 m_outputStream << boost::format("%25.19e") % time << " ";
598 for (size_t i = 0; i < m_bodyVel[0].size(); ++i)
599 {
600 m_outputStream << boost::format("%25.19e") % m_bodyVel[0][i] << " "
601 << boost::format("%25.19e") % m_bodyVel[1][i] << " "
602 << boost::format("%25.19e") % m_bodyVel[2][i] << " ";
603 }
604 m_outputStream << endl;
605 }
606 // overwirte m_omegaXYZ with u, also update theta
607 for (int i = 0; i < m_spacedim; ++i)
608 {
609 m_velXYZ[i] = m_bodyVel[1][i];
610 }
612 for (int i = 0; i < m_spacedim; ++i)
613 {
614 m_disp[i] = m_bodyVel[0][i] + m_travelWave[i] * time;
615 }
616 m_disp[5] = m_bodyVel[0][m_spacedim];
617
618 // include the effect of rotation
619 if (m_hasRotation)
620 {
621 UpdateRotMat();
625 }
626 else
627 {
628 // for translation only,
629 for (int i = 0; i < m_spacedim; ++i)
630 {
631 m_velxyz[i] = m_velXYZ[i];
632 }
633 }
634 ++m_index;
635}
void SolveBodyMotion(Array< OneD, Array< OneD, NekDouble > > &bodyVel, const Array< OneD, NekDouble > &forcebody, std::map< int, NekDouble > &Dirs)
void IneritalToBody(const int dim, Array< OneD, NekDouble > &body, const Array< OneD, NekDouble > &inertial)
static Array< OneD, NekDouble > NullNekDouble1DArray

References ASSERTL0, CellMLToNektar.pycml::format, Nektar::SolverUtils::FrameTransform::IneritalToBody(), m_aeroforceFilter, m_bodyVel, m_DirDoFs, m_disp, Nektar::SolverUtils::Forcing::m_equ, m_extForceFunction, m_extForceXYZ, m_frame, m_frameVelFunction, m_hasFreeMotion, m_hasRotation, m_index, m_omegaXYZ, m_omegaxyz, m_outputFrequency, m_outputStream, m_rank, m_spacedim, m_startTime, m_travelWave, m_velXYZ, m_velxyz, Nektar::NullNekDouble1DArray, Nektar::SolverUtils::FrameTransform::SetAngle(), SolveBodyMotion(), and UpdateRotMat().

Referenced by v_PreApply().

◆ UpdateBoundaryConditions()

void Nektar::SolverUtils::ForcingMovingReferenceFrame::UpdateBoundaryConditions ( NekDouble  time)
private

Set velocity boundary condition at the next time step.

Definition at line 741 of file ForcingMovingReferenceFrame.cpp.

742{
743 time += m_timestep;
744 // compute the velocities whose functions are provided in inertial frame
745 for (auto it : m_frameVelFunction)
746 {
747 if (it.first < 3)
748 {
749 m_velXYZ[it.first] = it.second->Evaluate(0., 0., 0., time);
750 }
751 else
752 {
753 m_omegaXYZ[it.first - 3] = it.second->Evaluate(0., 0., 0., time);
754 }
755 }
756 for (auto it : m_extForceFunction)
757 {
758 m_extForceXYZ[it.first] = it.second->Evaluate(0., 0., 0., time);
759 }
760 std::map<int, NekDouble> Dirs; // prescribed Motion
761 for (auto it : m_DirDoFs)
762 {
763 if (it < m_spacedim)
764 {
765 Dirs[it] = m_velXYZ[it];
766 }
767 else if (it == m_spacedim)
768 {
769 Dirs[it] = m_omegaXYZ[2];
770 }
771 }
772
773 auto equ = m_equ.lock();
774 ASSERTL0(equ, "Weak pointer to the equation system is expired");
775 auto FluidEq = std::dynamic_pointer_cast<FluidInterface>(equ);
776 Array<OneD, NekDouble> forcebody(6, 0.); // fluid force
777 FluidEq->GetAeroForce(forcebody);
778
779 Array<OneD, Array<OneD, NekDouble>> bodyVel(m_bodyVel.size());
780 for (size_t i = 0; i < m_bodyVel.size(); ++i)
781 {
782 bodyVel[i] = Array<OneD, NekDouble>(m_bodyVel[i].size());
783 }
784 // copy initial condition
785 for (size_t i = 0; i < m_bodyVel.size(); ++i)
786 {
787 Vmath::Vcopy(m_bodyVel[i].size(), m_bodyVel[i], 1, bodyVel[i], 1);
788 }
789 SolveBodyMotion(bodyVel, forcebody, Dirs);
790 // to stablize the velocity bcs, use the old values if extrapolation is
791 // involved
792 for (size_t i = 0; i < bodyVel[0].size(); ++i)
793 {
794 if (Dirs.find(i) == Dirs.end())
795 {
796 for (size_t k = 0; k < bodyVel.size(); ++k)
797 {
798 bodyVel[k][i] = m_bodyVel[k][i];
799 }
800 }
801 }
802 // set displacements at the next time step
803 for (int i = 0; i < m_spacedim; ++i)
804 {
805 m_disp[i] = bodyVel[0][i] + m_travelWave[i] * time;
806 }
807 m_disp[5] = bodyVel[0][m_spacedim];
808 // copy the velocities and rotation matrix for enforcing bc
809 // copy linear and angular velocities and accelerations
810 Array<OneD, NekDouble> vel(12, 0.0), tmp;
811 for (int i = 0; i < m_spacedim; ++i)
812 {
813 vel[i] = bodyVel[1][i];
814 vel[i + 6] = bodyVel[2][i];
815 }
816 vel[5] = bodyVel[1][m_spacedim];
817 vel[11] = bodyVel[2][m_spacedim];
818 if (m_hasRotation)
819 {
820 UpdateRotMat();
822 m_frame.IneritalToBody(3, vel, vel);
823 m_frame.IneritalToBody(3, tmp = vel + 6, vel + 6);
824 }
825
826 // to set the boundary condition of the next time step
827 // update the frame velocities
828 FluidEq->SetMovingFrameVelocities(vel);
829 // update the projection matrix
830 FluidEq->SetMovingFrameProjectionMat(m_ProjMatZ);
831 // update the frame angle (with respect to the inertial frame)
832 // this angle is used to update the meta data,
833 // on the other hand, for boundary conditions the projection matrix is used
834 FluidEq->SetMovingFrameDisp(m_disp);
835}

References ASSERTL0, Nektar::SolverUtils::FrameTransform::IneritalToBody(), m_bodyVel, m_DirDoFs, m_disp, Nektar::SolverUtils::Forcing::m_equ, m_extForceFunction, m_extForceXYZ, m_frame, m_frameVelFunction, m_hasRotation, m_omegaXYZ, m_ProjMatZ, m_spacedim, m_timestep, m_travelWave, m_velXYZ, Nektar::SolverUtils::FrameTransform::SetAngle(), SolveBodyMotion(), UpdateRotMat(), and Vmath::Vcopy().

Referenced by v_Apply().

◆ UpdateRotMat()

void Nektar::SolverUtils::ForcingMovingReferenceFrame::UpdateRotMat ( )
private

Definition at line 702 of file ForcingMovingReferenceFrame.cpp.

703{
704 // update the rotation matrix
705 NekDouble sn, cs;
706 sn = sin(m_disp[5]);
707 cs = cos(m_disp[5]);
708
709 m_ProjMatZ(0, 0) = cs;
710 m_ProjMatZ(0, 1) = sn;
711 m_ProjMatZ(1, 0) = -sn;
712 m_ProjMatZ(1, 1) = cs;
713 m_ProjMatZ(2, 2) = 1.0;
714}

References m_disp, and m_ProjMatZ.

Referenced by Update(), and UpdateBoundaryConditions().

◆ v_Apply()

void Nektar::SolverUtils::ForcingMovingReferenceFrame::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

Adds the body force, -Omega X u.

Parameters
fields
inarray
outarray
time

Implements Nektar::SolverUtils::Forcing.

Definition at line 723 of file ForcingMovingReferenceFrame.cpp.

727{
728 // If there is no rotation, body force is zero,
729 // nothing needs to be done here.
730 if (m_hasRotation)
731 {
732 int npoints = fields[0]->GetNpoints();
733 addRotation(npoints, outarray, -1., inarray, outarray);
734 }
736}
void addRotation(int npoints, const Array< OneD, Array< OneD, NekDouble > > &inarray0, NekDouble angVelScale, const Array< OneD, Array< OneD, NekDouble > > &inarray1, Array< OneD, Array< OneD, NekDouble > > &outarray)
outarray = inarray0 + angVelScale Omega x inarray1
void UpdateBoundaryConditions(NekDouble time)
Set velocity boundary condition at the next time step.

References addRotation(), m_hasRotation, and UpdateBoundaryConditions().

◆ v_InitObject()

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

Initialise the forcing module.

Parameters
pFields
pNumForcingFields
pForce

Implements Nektar::SolverUtils::Forcing.

Definition at line 87 of file ForcingMovingReferenceFrame.cpp.

91{
92 m_session->MatchSolverInfo("Homogeneous", "1D", m_isH1d, false);
93 m_session->MatchSolverInfo("Homogeneous", "2D", m_isH2d, false);
94 bool singleMode, halfMode;
95 m_session->MatchSolverInfo("ModeType", "SingleMode", singleMode, false);
96 m_session->MatchSolverInfo("ModeType", "HalfMode", halfMode, false);
97 if (singleMode || halfMode)
98 {
99 m_isH1d = false;
100 }
101
102 int npoints = pFields[0]->GetNpoints();
103 m_expdim = m_isH2d ? 1 : pFields[0]->GetGraph()->GetMeshDimension();
104 m_spacedim = m_expdim + (m_isH1d ? 1 : 0) + (m_isH2d ? 2 : 0);
106
107 m_hasPlane0 = true;
108 if (m_isH1d)
109 {
110 m_hasPlane0 = pFields[0]->GetZIDs()[0] == 0;
111 }
112
113 // initialize variables
114 m_velXYZ = Array<OneD, NekDouble>(3, 0.0);
115 m_velxyz = Array<OneD, NekDouble>(3, 0.0);
116 m_omegaXYZ = Array<OneD, NekDouble>(3, 0.0);
117 m_omegaxyz = Array<OneD, NekDouble>(3, 0.0);
118 m_extForceXYZ = Array<OneD, NekDouble>(6, 0.0);
119 m_hasVel = Array<OneD, bool>(3, false);
120 m_hasOmega = Array<OneD, bool>(3, false);
121 m_disp = Array<OneD, NekDouble>(9, 0.0);
122 m_pivotPoint = Array<OneD, NekDouble>(3, 0.0);
123 m_travelWave = Array<OneD, NekDouble>(3, 0.);
124
125 // initialize time
126 NekDouble time = 0.;
127 CheckForRestartTime(pFields, time);
128 m_startTime = time;
129 // load moving frame infomation
130 LoadParameters(pForce, time);
131 if (m_hasRotation)
132 {
133 m_coords = Array<OneD, Array<OneD, NekDouble>>(3);
134 for (int j = 0; j < m_spacedim; ++j)
135 {
136 m_coords[j] = Array<OneD, NekDouble>(npoints);
137 }
138 pFields[0]->GetCoords(m_coords[0], m_coords[1], m_coords[2]);
139 // move the origin to the pivot point
140 for (int i = 0; i < m_spacedim; ++i)
141 {
142 Vmath::Sadd(npoints, -m_pivotPoint[i], m_coords[i], 1, m_coords[i],
143 1);
144 }
145 }
146
147 // init body solver
148 m_rank = pFields[0]->GetComm()->GetRank();
149 InitBodySolver(pForce, m_spacedim, m_rank, time);
150
151 // Initialize theta with the data from NS class
152 // This ensure correct moving coordinate orientation with respect to the
153 // stationary inertial frame when we restart the simulation
154 auto equ = m_equ.lock();
155 ASSERTL0(equ, "Weak pointer to the equation system is expired");
156 auto FluidEq = std::dynamic_pointer_cast<FluidInterface>(equ);
157 FluidEq->SetMovingFrameDisp(m_disp);
158
159 // initiate the rotation matrix to zero,
160 // Note that the rotation matrix is assumed for the rotation around z axis
161 // TODO: Generalize this for the 3D case with possiblity of rotation around
162 // each of axis. Probabley we only can support rotation around one axis. In
163 // that case the generalization means the user can provide Omega for one of
164 // x, y or z axis. Not sure how complicated to consider a general axis of
165 // rotation
166 //
167 // Note that these rotation matrices should be extrinsic rotations
168 m_ProjMatZ = bn::ublas::zero_matrix<NekDouble>(3, 3);
169 // populate the rotation matrix R(z)
170 {
171 NekDouble sn, cs;
172 sn = sin(m_disp[5]);
173 cs = cos(m_disp[5]);
174
175 m_ProjMatZ(0, 0) = cs;
176 m_ProjMatZ(0, 1) = sn;
177 m_ProjMatZ(1, 0) = -1. * sn;
178 m_ProjMatZ(1, 1) = cs;
179 m_ProjMatZ(2, 2) = 1.0;
180 }
181 // account for the effect of rotation
182 // Omega_X results in having v and w even if not defined by user
183 // Omega_Y results in having u and w even if not defined by user
184 // Omega_Z results in having u and v even if not defined by user
185 //
186 for (int i = 0; i < 3; ++i)
187 {
188 int j = (i + 1) % 3;
189 int k = (i + 2) % 3;
190
191 if (m_hasOmega[i])
192 {
193 m_hasVel[j] = true;
194 m_hasVel[k] = true;
195 }
196 }
197 // initialize aeroforce filter
198 if (m_hasFreeMotion)
199 {
200 InitialiseFilter(m_session, pFields, pForce);
201 }
202}
int m_NumVariable
Number of variables.
Definition: Forcing.h:121
void CheckForRestartTime(const Array< OneD, MultiRegions::ExpListSharedPtr > &pFields, NekDouble &time)
void InitBodySolver(const TiXmlElement *pForce, const int dim, const int rank, const NekDouble time)
void LoadParameters(const TiXmlElement *pForce, const NekDouble time)
void InitialiseFilter(const LibUtilities::SessionReaderSharedPtr &pSession, const Array< OneD, MultiRegions::ExpListSharedPtr > &pFields, const TiXmlElement *pForce)
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, CheckForRestartTime(), InitBodySolver(), InitialiseFilter(), LoadParameters(), m_coords, m_disp, Nektar::SolverUtils::Forcing::m_equ, m_expdim, m_extForceXYZ, m_hasFreeMotion, m_hasOmega, m_hasPlane0, m_hasRotation, m_hasVel, m_isH1d, m_isH2d, Nektar::SolverUtils::Forcing::m_NumVariable, m_omegaXYZ, m_omegaxyz, m_pivotPoint, m_ProjMatZ, m_rank, Nektar::SolverUtils::Forcing::m_session, m_spacedim, m_startTime, m_travelWave, m_velXYZ, m_velxyz, and Vmath::Sadd().

◆ v_PreApply()

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

Reimplemented from Nektar::SolverUtils::Forcing.

Definition at line 892 of file ForcingMovingReferenceFrame.cpp.

896{
897 Update(fields, time);
898 int npoints = fields[0]->GetNpoints();
899 if (m_isH2d && fields[0]->GetWaveSpace())
900 {
901 for (int i = 0; i < m_spacedim; ++i)
902 {
903 if (m_hasVel[i])
904 {
905 Array<OneD, NekDouble> tmpphys(npoints,
906 -m_velxyz[i] - m_travelWave[i]);
907 Array<OneD, NekDouble> tmpcoef(npoints);
908 fields[0]->HomogeneousFwdTrans(npoints, tmpphys, tmpcoef);
909 Vmath::Vadd(npoints, tmpcoef, 1, inarray[i], 1, outarray[i], 1);
910 }
911 else if (&inarray != &outarray)
912 {
913 Vmath::Vcopy(npoints, inarray[i], 1, outarray[i], 1);
914 }
915 }
916 }
917 else
918 {
919 int npoints0 = npoints;
920 if (m_isH1d && fields[0]->GetWaveSpace())
921 {
922 npoints0 = m_hasPlane0 ? fields[0]->GetPlane(0)->GetNpoints() : 0;
923 }
924 for (int i = 0; i < m_spacedim; ++i)
925 {
926 if (m_hasVel[i])
927 {
928 Vmath::Sadd(npoints0, -m_velxyz[i] - m_travelWave[i],
929 inarray[i], 1, outarray[i], 1);
930 if (&inarray != &outarray && npoints != npoints0)
931 {
932 Array<OneD, NekDouble> tmp = outarray[i] + npoints0;
933 Vmath::Vcopy(npoints - npoints0, inarray[i] + npoints0, 1,
934 tmp, 1);
935 }
936 }
937 else if (&inarray != &outarray)
938 {
939 Vmath::Vcopy(npoints, inarray[i], 1, outarray[i], 1);
940 }
941 }
942 if (m_hasRotation)
943 {
944 addRotation(npoints0, outarray, -1., m_coords, outarray);
945 }
946 }
947}
void Update(const Array< OneD, MultiRegions::ExpListSharedPtr > &pFields, const NekDouble &time)
Updates the forcing array with the current required forcing.
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

References addRotation(), m_coords, m_hasPlane0, m_hasRotation, m_hasVel, m_isH1d, m_isH2d, m_spacedim, m_travelWave, m_velxyz, Vmath::Sadd(), Update(), Vmath::Vadd(), and Vmath::Vcopy().

Friends And Related Function Documentation

◆ MemoryManager< ForcingMovingReferenceFrame >

Definition at line 97 of file ForcingMovingReferenceFrame.h.

Member Data Documentation

◆ classNameBody

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

Name of the class.

Definition at line 121 of file ForcingMovingReferenceFrame.h.

◆ m_aeroforceFilter

FilterAeroForcesSharedPtr Nektar::SolverUtils::ForcingMovingReferenceFrame::m_aeroforceFilter
private

Definition at line 200 of file ForcingMovingReferenceFrame.h.

Referenced by InitialiseFilter(), and Update().

◆ m_bodySolver

Newmark_BetaSolver Nektar::SolverUtils::ForcingMovingReferenceFrame::m_bodySolver
private

Definition at line 197 of file ForcingMovingReferenceFrame.h.

Referenced by InitBodySolver(), and SolveBodyMotion().

◆ m_bodyVel

Array<OneD, Array<OneD, NekDouble> > Nektar::SolverUtils::ForcingMovingReferenceFrame::m_bodyVel
private

Definition at line 198 of file ForcingMovingReferenceFrame.h.

Referenced by InitBodySolver(), Update(), and UpdateBoundaryConditions().

◆ m_coords

Array<OneD, Array<OneD, NekDouble> > Nektar::SolverUtils::ForcingMovingReferenceFrame::m_coords
private

Definition at line 174 of file ForcingMovingReferenceFrame.h.

Referenced by v_InitObject(), and v_PreApply().

◆ m_DirDoFs

std::set<int> Nektar::SolverUtils::ForcingMovingReferenceFrame::m_DirDoFs
private

Definition at line 199 of file ForcingMovingReferenceFrame.h.

Referenced by InitBodySolver(), Update(), and UpdateBoundaryConditions().

◆ m_disp

Array<OneD, NekDouble> Nektar::SolverUtils::ForcingMovingReferenceFrame::m_disp
private

◆ m_expdim

NekInt Nektar::SolverUtils::ForcingMovingReferenceFrame::m_expdim
private

Definition at line 194 of file ForcingMovingReferenceFrame.h.

Referenced by LoadParameters(), and v_InitObject().

◆ m_extForceFunction

std::map<int, LibUtilities::EquationSharedPtr> Nektar::SolverUtils::ForcingMovingReferenceFrame::m_extForceFunction
private

Definition at line 151 of file ForcingMovingReferenceFrame.h.

Referenced by LoadParameters(), Update(), and UpdateBoundaryConditions().

◆ m_extForceXYZ

Array<OneD, NekDouble> Nektar::SolverUtils::ForcingMovingReferenceFrame::m_extForceXYZ
private

◆ m_frame

FrameTransform Nektar::SolverUtils::ForcingMovingReferenceFrame::m_frame
private

◆ m_frameVelFunction

std::map<int, LibUtilities::EquationSharedPtr> Nektar::SolverUtils::ForcingMovingReferenceFrame::m_frameVelFunction
private

◆ m_hasFreeMotion

bool Nektar::SolverUtils::ForcingMovingReferenceFrame::m_hasFreeMotion
private

Definition at line 192 of file ForcingMovingReferenceFrame.h.

Referenced by InitBodySolver(), Update(), and v_InitObject().

◆ m_hasOmega

Array<OneD, bool> Nektar::SolverUtils::ForcingMovingReferenceFrame::m_hasOmega
private

◆ m_hasPlane0

bool Nektar::SolverUtils::ForcingMovingReferenceFrame::m_hasPlane0
private

Definition at line 190 of file ForcingMovingReferenceFrame.h.

Referenced by v_InitObject(), and v_PreApply().

◆ m_hasRotation

bool Nektar::SolverUtils::ForcingMovingReferenceFrame::m_hasRotation
private

◆ m_hasVel

Array<OneD, bool> Nektar::SolverUtils::ForcingMovingReferenceFrame::m_hasVel
private

◆ m_index

unsigned int Nektar::SolverUtils::ForcingMovingReferenceFrame::m_index
private

Definition at line 195 of file ForcingMovingReferenceFrame.h.

Referenced by InitBodySolver(), and Update().

◆ m_isH1d

bool Nektar::SolverUtils::ForcingMovingReferenceFrame::m_isH1d
private

Definition at line 189 of file ForcingMovingReferenceFrame.h.

Referenced by v_InitObject(), and v_PreApply().

◆ m_isH2d

bool Nektar::SolverUtils::ForcingMovingReferenceFrame::m_isH2d
private

Definition at line 191 of file ForcingMovingReferenceFrame.h.

Referenced by v_InitObject(), and v_PreApply().

◆ m_omegaXYZ

Array<OneD, NekDouble> Nektar::SolverUtils::ForcingMovingReferenceFrame::m_omegaXYZ
private

Definition at line 169 of file ForcingMovingReferenceFrame.h.

Referenced by Update(), UpdateBoundaryConditions(), and v_InitObject().

◆ m_omegaxyz

Array<OneD, NekDouble> Nektar::SolverUtils::ForcingMovingReferenceFrame::m_omegaxyz
private

Definition at line 172 of file ForcingMovingReferenceFrame.h.

Referenced by addRotation(), Update(), and v_InitObject().

◆ m_outputFrequency

unsigned int Nektar::SolverUtils::ForcingMovingReferenceFrame::m_outputFrequency
private

Definition at line 196 of file ForcingMovingReferenceFrame.h.

Referenced by InitBodySolver(), and Update().

◆ m_outputStream

std::ofstream Nektar::SolverUtils::ForcingMovingReferenceFrame::m_outputStream
private

◆ m_pivotPoint

Array<OneD, NekDouble> Nektar::SolverUtils::ForcingMovingReferenceFrame::m_pivotPoint
private

Definition at line 145 of file ForcingMovingReferenceFrame.h.

Referenced by LoadParameters(), and v_InitObject().

◆ m_ProjMatZ

bn::ublas::matrix<NekDouble> Nektar::SolverUtils::ForcingMovingReferenceFrame::m_ProjMatZ
private

◆ m_rank

int Nektar::SolverUtils::ForcingMovingReferenceFrame::m_rank
private

◆ m_spacedim

NekInt Nektar::SolverUtils::ForcingMovingReferenceFrame::m_spacedim
private

◆ m_startTime

NekDouble Nektar::SolverUtils::ForcingMovingReferenceFrame::m_startTime
private

Definition at line 185 of file ForcingMovingReferenceFrame.h.

Referenced by Update(), and v_InitObject().

◆ m_timestep

NekDouble Nektar::SolverUtils::ForcingMovingReferenceFrame::m_timestep
private

◆ m_travelWave

Array<OneD, NekDouble> Nektar::SolverUtils::ForcingMovingReferenceFrame::m_travelWave
private

◆ m_velXYZ

Array<OneD, NekDouble> Nektar::SolverUtils::ForcingMovingReferenceFrame::m_velXYZ
private

Definition at line 163 of file ForcingMovingReferenceFrame.h.

Referenced by Update(), UpdateBoundaryConditions(), and v_InitObject().

◆ m_velxyz

Array<OneD, NekDouble> Nektar::SolverUtils::ForcingMovingReferenceFrame::m_velxyz
private

Definition at line 166 of file ForcingMovingReferenceFrame.h.

Referenced by Update(), v_InitObject(), and v_PreApply().