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
 Compute the moving frame velocity at given time. More...
 
- 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 ~Forcing ()=default
 
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 UpdatePrescribed (const NekDouble &time, std::map< int, NekDouble > &Dirs)
 
void UpdateFrameVelocity (const Array< OneD, MultiRegions::ExpListSharedPtr > &pFields, const NekDouble &time)
 Updates the forcing array with the current required forcing. More...
 
void UpdateFluidInterface (Array< OneD, Array< OneD, NekDouble > > &bodyVel, const int step)
 
void SetInitialConditions ()
 
void SetInitialConditions (std::map< int, NekDouble > &Dirs)
 
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)
 
void SolveBodyMotion (Array< OneD, Array< OneD, NekDouble > > &bodyVel, const Array< OneD, NekDouble > &forcebody, std::map< int, NekDouble > &Dirs)
 
void LoadParameters (const TiXmlElement *pForce)
 
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::ofstream m_outputStream
 
bool m_isRoot
 
Array< OneD, bool > m_hasVel
 
Array< OneD, bool > m_hasOmega
 
bool m_hasRotation
 
Array< OneD, NekDoublem_velxyz
 
Array< OneD, NekDoublem_omegaxyz
 
Array< OneD, Array< OneD, NekDouble > > m_coords
 
NekDouble m_currentTime
 
NekDouble m_timestep
 
bool m_isH1d
 
bool m_hasPlane0
 
bool m_isH2d
 
int32_t m_spacedim
 
int32_t m_expdim
 
unsigned int m_index
 
unsigned int m_outputFrequency
 
struct {
   Array< OneD, Array< OneD, NekDouble > >   vel
 
   bool   hasFreeMotion
 
   std::set< int >   dirDoFs
 
   bool   isCircular
 
   FilterAeroForcesSharedPtr   aeroforceFilter
 
   std::map< int, LibUtilities::EquationSharedPtr >   extForceFunction
 
   Array< OneD, NekDouble >   extForceXYZ
 
   Array< OneD, NekDouble >   M
 
   Array< OneD, NekDouble >   C
 
   Array< OneD, NekDouble >   K
 
m_body
 
Newmark_BetaSolver m_bodySolver
 

Friends

class MemoryManager< ForcingMovingReferenceFrame >
 

Additional Inherited Members

- Public Member Functions inherited from Nektar::SolverUtils::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 105 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 65 of file ForcingMovingReferenceFrame.cpp.

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

◆ ~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 771 of file ForcingMovingReferenceFrame.cpp.

776{
777 ASSERTL0(&inarray1 != &outarray, "inarray1 and outarray "
778 "should not be the same.");
779
780 // TODO: In case of having support for all three components of Omega,
781 // they should be transformed into the rotating frame first!
782
783 // In case that the inarray0 and outarry are different, to avoid using
784 // un-initialized array, copy the array first
785 if (&inarray0 != &outarray)
786 {
787 ASSERTL0(inarray0.size() == outarray.size(),
788 "inarray0 and outarray must have same dimentions");
789 for (int i = 0; i < inarray0.size(); ++i)
790 {
791 Vmath::Vcopy(nPnts, inarray0[i], 1, outarray[i], 1);
792 }
793 }
794
795 if (m_spacedim >= 2 && m_hasOmega[2])
796 {
797 NekDouble cp = m_omegaxyz[2] * angVelScale;
798 NekDouble cm = -1. * cp;
799
800 Vmath::Svtvp(nPnts, cm, inarray1[1], 1, outarray[0], 1, outarray[0], 1);
801 Vmath::Svtvp(nPnts, cp, inarray1[0], 1, outarray[1], 1, outarray[1], 1);
802 }
803
804 if (m_spacedim == 3 && m_hasOmega[0])
805 {
806 NekDouble cp = m_omegaxyz[0] * angVelScale;
807 NekDouble cm = -1. * cp;
808
809 Vmath::Svtvp(nPnts, cp, inarray1[1], 1, outarray[2], 1, outarray[2], 1);
810 Vmath::Svtvp(nPnts, cm, inarray1[2], 1, outarray[1], 1, outarray[1], 1);
811 }
812
813 if (m_spacedim == 3 && m_hasOmega[1])
814 {
815 NekDouble cp = m_omegaxyz[1] * angVelScale;
816 NekDouble cm = -1. * cp;
817
818 Vmath::Svtvp(nPnts, cp, inarray1[2], 1, outarray[0], 1, outarray[0], 1);
819 Vmath::Svtvp(nPnts, cm, inarray1[0], 1, outarray[2], 1, outarray[2], 1);
820 }
821}
#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().

◆ 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 112 of file ForcingMovingReferenceFrame.h.

117 {
120 pSession, pEquation);
121 p->InitObject(pFields, pNumForcingFields, pForce);
122 return p;
123 }
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 170 of file ForcingMovingReferenceFrame.cpp.

172{
173 NekDouble value = 0.;
174 try
175 {
176 LibUtilities::Equation expession(m_session->GetInterpreter(),
177 expression);
178 value = expession.Evaluate();
179 }
180 catch (const std::runtime_error &)
181 {
182 NEKERROR(ErrorUtil::efatal, "Error evaluating expression" + expression);
183 }
184 return value;
185}
#define NEKERROR(type, msg)
Assert Level 0 – Fundamental assert which is used whether in FULLDEBUG, DEBUG or OPT compilation mode...
Definition: ErrorUtil.hpp:202
LibUtilities::SessionReaderSharedPtr m_session
Session reader.
Definition: Forcing.h:123

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)
private

Definition at line 381 of file ForcingMovingReferenceFrame.cpp.

382{
383 int NumDof = m_spacedim + 1;
384 const TiXmlElement *mssgTag;
385 std::string mssgStr;
386 // allocate memory and initialise
387 m_body.vel = Array<OneD, Array<OneD, NekDouble>>(3);
388 for (size_t i = 0; i < 3; ++i)
389 {
390 m_body.vel[i] = Array<OneD, NekDouble>(NumDof, 0.);
391 }
394 // read free motion DoFs
395 m_body.dirDoFs.clear();
396 for (int i = 0; i < NumDof; ++i)
397 {
398 m_body.dirDoFs.insert(i);
399 }
400 mssgTag = pForce->FirstChildElement("MOTIONPRESCRIBED");
401 if (mssgTag)
402 {
403 std::vector<std::string> values;
404 mssgStr = mssgTag->GetText();
405 ParseUtils::GenerateVector(mssgStr, values);
406 ASSERTL0(values.size() == NumDof,
407 "MOTIONPRESCRIBED vector should be of size " +
408 std::to_string(NumDof));
409 for (int i = 0; i < NumDof; ++i)
410 {
411 if (EvaluateExpression(values[i]) == 0)
412 {
413 m_body.dirDoFs.erase(i);
414 if (i < m_spacedim)
415 {
416 m_hasVel[i] = true;
417 }
418 else if (i == m_spacedim)
419 {
420 m_hasOmega[2] = true;
421 m_hasRotation = true;
422 }
423 }
424 }
425 }
426 m_body.hasFreeMotion = m_body.dirDoFs.size() < NumDof;
427 // read mass matrix
428 m_body.M = Array<OneD, NekDouble>(NumDof * NumDof, 0.);
429 mssgTag = pForce->FirstChildElement("MASS");
430 ASSERTL0(m_body.dirDoFs.size() == NumDof || mssgTag,
431 "Mass matrix is required.");
432 if (mssgTag)
433 {
434 std::vector<std::string> values;
435 mssgStr = mssgTag->GetText();
436 ParseUtils::GenerateVector(mssgStr, values);
437 ASSERTL0(values.size() == NumDof * NumDof,
438 "Mass matrix should be of size " + std::to_string(NumDof) +
439 "X" + std::to_string(NumDof));
440 int count = 0;
441 for (int i = 0; i < NumDof; ++i)
442 {
443 for (int j = 0; j < NumDof; ++j)
444 {
445 m_body.M[count] = EvaluateExpression(values[count]);
446 ++count;
447 }
448 }
449 }
450 // read damping matrix
451 m_body.C = Array<OneD, NekDouble>(NumDof * NumDof, 0.);
452 mssgTag = pForce->FirstChildElement("DAMPING");
453 if (mssgTag)
454 {
455 std::vector<std::string> values;
456 mssgStr = mssgTag->GetText();
457 ParseUtils::GenerateVector(mssgStr, values);
458 ASSERTL0(values.size() == NumDof * NumDof,
459 "Damping matrix should be of size " + std::to_string(NumDof) +
460 "X" + std::to_string(NumDof));
461 int count = 0;
462 for (int i = 0; i < NumDof; ++i)
463 {
464 for (int j = 0; j < NumDof; ++j)
465 {
466 m_body.C[count] = EvaluateExpression(values[count]);
467 ++count;
468 }
469 }
470 }
471 // read rigidity matrix
472 m_body.K = Array<OneD, NekDouble>(NumDof * NumDof, 0.);
473 mssgTag = pForce->FirstChildElement("RIGIDITY");
474 if (mssgTag)
475 {
476 std::vector<std::string> values;
477 mssgStr = mssgTag->GetText();
478 ParseUtils::GenerateVector(mssgStr, values);
479 ASSERTL0(values.size() == NumDof * NumDof,
480 "Rigidity matrix should be of size " + std::to_string(NumDof) +
481 "X" + std::to_string(NumDof));
482 int count = 0;
483 for (int i = 0; i < NumDof; ++i)
484 {
485 for (int j = 0; j < NumDof; ++j)
486 {
487 m_body.K[count] = EvaluateExpression(values[count]);
488 ++count;
489 }
490 }
491 }
492 // read Newmark Beta paramters
493 m_timestep = m_session->GetParameter("TimeStep");
494 NekDouble beta = 0.25;
495 NekDouble gamma = 0.51;
496 if (m_session->DefinesParameter("NewmarkBeta"))
497 {
498 beta = m_session->GetParameter("NewmarkBeta");
499 }
500 if (m_session->DefinesParameter("NewmarkGamma"))
501 {
502 gamma = m_session->GetParameter("NewmarkGamma");
503 }
505 m_body.K, m_body.dirDoFs);
506}
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
void UpdateFluidInterface(Array< OneD, Array< OneD, NekDouble > > &bodyVel, const int step)
struct Nektar::SolverUtils::ForcingMovingReferenceFrame::@2 m_body
void SetNewmarkBeta(NekDouble beta, NekDouble gamma, NekDouble dt, Array< OneD, NekDouble > M, Array< OneD, NekDouble > C, Array< OneD, NekDouble > K, std::set< int > DirDoFs)
@ beta
Gauss Radau pinned at x=-1,.
Definition: PointsType.h:59

References ASSERTL0, Nektar::LibUtilities::beta, EvaluateExpression(), Nektar::ParseUtils::GenerateVector(), m_body, m_bodySolver, m_hasOmega, m_hasRotation, m_hasVel, Nektar::SolverUtils::Forcing::m_session, m_spacedim, m_timestep, SetInitialConditions(), Nektar::SolverUtils::Newmark_BetaSolver::SetNewmarkBeta(), and UpdateFluidInterface().

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 983 of file ForcingMovingReferenceFrame.cpp.

987{
988 std::map<std::string, std::string> vParams;
989 vParams["OutputFile"] = ".dummyMRFForceFile";
990 const TiXmlElement *param = pForce->FirstChildElement("BOUNDARY");
991 ASSERTL0(param, "Body surface should be assigned");
992
993 vParams["Boundary"] = param->GetText();
994 const TiXmlElement *pivotElmt = pForce->FirstChildElement("PIVOTPOINT");
995 if (pivotElmt)
996 {
997 std::string pstr = pivotElmt->GetText();
998 std::replace(pstr.begin(), pstr.end(), ',', ' ');
999 vParams["MomentPoint"] = pstr;
1000 }
1002 pSession, m_equ.lock(), vParams);
1003
1004 m_body.aeroforceFilter->Initialise(pFields, 0.0);
1005}
const std::weak_ptr< EquationSystem > m_equ
Weak pointer to equation system using this forcing.
Definition: Forcing.h:125

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

Referenced by v_InitObject().

◆ LoadParameters()

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

Definition at line 187 of file ForcingMovingReferenceFrame.cpp.

188{
189 const TiXmlElement *funcNameElmt;
190 // body is a circular cylinder
191 const TiXmlElement *mssgTagSpecial =
192 pForce->FirstChildElement("CIRCULARCYLINDER");
193 if (mssgTagSpecial)
194 {
195 m_body.isCircular = true;
196 }
197 else
198 {
199 m_body.isCircular = false;
200 }
201 // load frame velocity
202 funcNameElmt = pForce->FirstChildElement("FRAMEVELOCITY");
203 if (funcNameElmt)
204 {
205 std::string FuncName = funcNameElmt->GetText();
206 ASSERTL0(m_session->DefinesFunction(FuncName),
207 "Function '" + FuncName + "' is not defined in the session.");
208 // linear velocity
209 for (int i = 0; i < m_spacedim; ++i)
210 {
211 std::string var = m_session->GetVariable(i);
212 if (m_session->DefinesFunction(FuncName, var))
213 {
214 m_frameVelFunction[i] = m_session->GetFunction(FuncName, var);
215 m_hasVel[i] = true;
216 }
217 }
218 // linear displacement and acceleration
219 std::vector<std::string> linearDispVar = {"X", "Y", "Z"};
220 std::vector<std::string> linearAcceVar = {"A_x", "A_y", "A_z"};
221 for (int i = 0; i < m_spacedim; ++i)
222 {
223 if (m_session->DefinesFunction(FuncName, linearDispVar[i]))
224 {
225 m_frameVelFunction[i + 6] =
226 m_session->GetFunction(FuncName, linearDispVar[i]);
227 }
228 if (m_session->DefinesFunction(FuncName, linearAcceVar[i]))
229 {
230 m_frameVelFunction[i + 12] =
231 m_session->GetFunction(FuncName, linearAcceVar[i]);
232 }
233 }
234 // angular velocities
235 m_hasRotation = false;
236 std::vector<std::string> angularVar = {"Omega_x", "Omega_y", "Omega_z"};
237 for (int i = 0; i < 3; ++i)
238 {
239 std::string var = angularVar[i];
240 if (m_session->DefinesFunction(FuncName, var))
241 {
242 m_frameVelFunction[i + 3] =
243 m_session->GetFunction(FuncName, var);
244 m_hasOmega[i] = true;
245 m_hasRotation = true;
246 }
247 }
248 // angular displacement and acceleration
249 std::vector<std::string> angularDispVar = {"Theta_x", "Theta_y",
250 "Theta_z"};
251 std::vector<std::string> angularAccepVar = {"DOmega_x", "DOmega_y",
252 "DOmega_z"};
253 for (int i = 0; i < 3; ++i)
254 {
255 if (m_session->DefinesFunction(FuncName, angularDispVar[i]))
256 {
257 m_frameVelFunction[i + 3 + 6] =
258 m_session->GetFunction(FuncName, angularDispVar[i]);
259 }
260 if (m_session->DefinesFunction(FuncName, angularAccepVar[i]))
261 {
262 m_frameVelFunction[i + 3 + 12] =
263 m_session->GetFunction(FuncName, angularAccepVar[i]);
264 }
265 }
266 // TODO: add the support for general rotation
267 for (int i = 0; i < 2; ++i)
268 {
269 ASSERTL0(!m_hasOmega[i], "Currently only Omega_z is supported");
270 }
271 }
272
273 // load external force
274 funcNameElmt = pForce->FirstChildElement("EXTERNALFORCE");
275 if (funcNameElmt)
276 {
277 std::string FuncName = funcNameElmt->GetText();
278 if (m_session->DefinesFunction(FuncName))
279 {
280 std::vector<std::string> forceVar = {"Fx", "Fy", "Fz"};
281 for (int i = 0; i < m_spacedim; ++i)
282 {
283 std::string var = forceVar[i];
284 if (m_session->DefinesFunction(FuncName, var))
285 {
286 m_body.extForceFunction[i] =
287 m_session->GetFunction(FuncName, var);
288 }
289 }
290 std::vector<std::string> momentVar = {"Mx", "My", "Mz"};
291 for (int i = 0; i < 3; ++i)
292 {
293 std::string var = momentVar[i];
294 if (m_session->DefinesFunction(FuncName, var))
295 {
296 m_body.extForceFunction[i + 3] =
297 m_session->GetFunction(FuncName, var);
298 }
299 }
300 }
301 }
302
303 // load pitching pivot
304 const TiXmlElement *pivotElmt = pForce->FirstChildElement("PIVOTPOINT");
305 if (pivotElmt)
306 {
307 std::vector<std::string> values;
308 std::string mssgStr = pivotElmt->GetText();
309 ParseUtils::GenerateVector(mssgStr, values);
310 for (int j = 0; j < m_spacedim; ++j)
311 {
312 m_pivotPoint[j] = EvaluateExpression(values[j]);
313 }
314 }
315
316 // load travelling wave speed
317 const TiXmlElement *TWSElmt =
318 pForce->FirstChildElement("TRAVELINGWAVESPEED");
319 if (TWSElmt)
320 {
321 std::vector<std::string> values;
322 std::string mssgStr = TWSElmt->GetText();
323 ParseUtils::GenerateVector(mssgStr, values);
324 for (int j = 0; j < m_spacedim; ++j)
325 {
326 NekDouble tmp = EvaluateExpression(values[j]);
327 if (fabs(tmp) > NekConstants::kNekMachineEpsilon)
328 {
329 m_travelWave[j] = tmp;
330 m_hasVel[j] = true;
331 }
332 }
333 }
334
335 // OutputFile
336 const TiXmlElement *mssgTag = pForce->FirstChildElement("OutputFile");
337 std::string filename;
338 if (mssgTag)
339 {
340 filename = mssgTag->GetText();
341 }
342 else
343 {
344 filename = m_session->GetSessionName();
345 }
346 if (!(filename.length() >= 4 &&
347 filename.substr(filename.length() - 4) == ".mrf"))
348 {
349 filename += ".mrf";
350 }
351 if (m_isRoot)
352 {
353 m_outputStream.open(filename.c_str());
354 if (m_spacedim == 2)
355 {
357 << "Variables = t, x, ux, ax, y, uy, ay, theta, omega, domega"
358 << std::endl;
359 }
360 else if (m_spacedim == 3)
361 {
362 m_outputStream << "Variables = t, x, ux, ax, y, uy, ay, z, uz, az, "
363 "theta, omega, domega"
364 << std::endl;
365 }
366 }
367
368 // output frequency
370 mssgTag = pForce->FirstChildElement("OutputFrequency");
371 if (mssgTag)
372 {
373 std::vector<std::string> values;
374 std::string mssgStr = mssgTag->GetText();
375 m_outputFrequency = round(EvaluateExpression(mssgStr));
376 }
378 "OutputFrequency should be greater than zero.");
379}
std::map< int, LibUtilities::EquationSharedPtr > m_frameVelFunction
static const NekDouble kNekMachineEpsilon

References ASSERTL0, EvaluateExpression(), Nektar::ParseUtils::GenerateVector(), Nektar::NekConstants::kNekMachineEpsilon, m_body, m_frameVelFunction, m_hasOmega, m_hasRotation, m_hasVel, m_isRoot, m_outputFrequency, m_outputStream, m_pivotPoint, Nektar::SolverUtils::Forcing::m_session, m_spacedim, and m_travelWave.

Referenced by v_InitObject().

◆ SetInitialConditions() [1/2]

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

Definition at line 883 of file ForcingMovingReferenceFrame.cpp.

884{
885 NekDouble time = 0.;
886 std::map<std::string, std::string> fieldMetaDataMap;
887 std::vector<std::string> strFrameData = {
888 "X", "Y", "Z", "Theta_x", "Theta_y", "Theta_z",
889 "U", "V", "W", "Omega_x", "Omega_y", "Omega_z",
890 "A_x", "A_y", "A_z", "DOmega_x", "DOmega_y", "DOmega_z"};
891 std::map<std::string, NekDouble> fileData;
892 if (m_session->DefinesFunction("InitialConditions"))
893 {
894 for (int i = 0; i < m_session->GetVariables().size(); ++i)
895 {
896 if (m_session->GetFunctionType("InitialConditions",
897 m_session->GetVariable(i)) ==
899 {
900 std::string filename = m_session->GetFunctionFilename(
901 "InitialConditions", m_session->GetVariable(i));
902 fs::path pfilename(filename);
903 // redefine path for parallel file which is in directory
904 if (fs::is_directory(pfilename))
905 {
906 fs::path metafile("Info.xml");
907 fs::path fullpath = pfilename / metafile;
908 filename = LibUtilities::PortablePath(fullpath);
909 }
912 fld->ImportFieldMetaData(filename, fieldMetaDataMap);
913
914 // check to see if time is defined
915 if (fieldMetaDataMap != LibUtilities::NullFieldMetaDataMap)
916 {
917 if (fieldMetaDataMap.find("Time") != fieldMetaDataMap.end())
918 {
919 time = std::stod(fieldMetaDataMap["Time"]);
920 }
921 fileData.clear();
922 for (auto &var : strFrameData)
923 {
924 if (fieldMetaDataMap.find(var) !=
925 fieldMetaDataMap.end())
926 {
927 fileData[var] = std::stod(fieldMetaDataMap[var]);
928 }
929 }
930 if (fileData.size() == strFrameData.size())
931 {
932 break;
933 }
934 }
935 }
936 }
937 }
938 if (m_session->DefinesCmdLineArgument("set-start-time"))
939 {
940 time = std::stod(
941 m_session->GetCmdLineArgument<std::string>("set-start-time"));
942 }
943 if (fileData.size() == strFrameData.size())
944 {
945 int NumDofm1 = m_body.vel[0].size() - 1;
946 for (int i = 0; i < m_spacedim; ++i)
947 {
948 m_body.vel[0][i] = fileData[strFrameData[i]];
949 m_body.vel[1][i] = fileData[strFrameData[i + 6]];
950 m_body.vel[2][i] = fileData[strFrameData[i + 12]];
951 }
952 m_body.vel[0][NumDofm1] = fileData[strFrameData[5]];
953 m_body.vel[1][NumDofm1] = fileData[strFrameData[11]];
954 m_body.vel[2][NumDofm1] = fileData[strFrameData[17]];
955 }
956 std::map<int, NekDouble> Dirs;
957 UpdatePrescribed(time, Dirs);
959}
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:223
void UpdatePrescribed(const NekDouble &time, std::map< int, NekDouble > &Dirs)
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:66
static FieldMetaDataMap NullFieldMetaDataMap
Definition: FieldIO.h:51

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

Referenced by InitBodySolver(), SetInitialConditions(), and UpdateFrameVelocity().

◆ SetInitialConditions() [2/2]

void Nektar::SolverUtils::ForcingMovingReferenceFrame::SetInitialConditions ( std::map< int, NekDouble > &  Dirs)
private

Definition at line 961 of file ForcingMovingReferenceFrame.cpp.

963{
964 for (auto it : Dirs)
965 {
966 int NumDof = m_body.vel[0].size();
967 int NumDof2 = NumDof << 1;
968 if (it.first < m_body.vel[0].size())
969 {
970 m_body.vel[1][it.first] = it.second;
971 }
972 else if (it.first < NumDof2)
973 {
974 m_body.vel[0][it.first - NumDof] = it.second;
975 }
976 else
977 {
978 m_body.vel[2][it.first - NumDof2] = it.second;
979 }
980 }
981}

References m_body.

◆ 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 658 of file ForcingMovingReferenceFrame.cpp.

661{
662 if (!m_body.hasFreeMotion)
663 {
664 m_bodySolver.SolvePrescribed(bodyVel, Dirs);
665 }
666 else if (!m_hasRotation || Dirs.find(m_spacedim) != Dirs.end())
667 {
668 m_bodySolver.SolvePrescribed(bodyVel, Dirs);
669 Array<OneD, NekDouble> force(6, 0.), tmp;
670 if (m_hasRotation && Dirs.find(m_spacedim) != Dirs.end())
671 {
672 Array<OneD, NekDouble> angle(3, 0.);
673 angle[2] = bodyVel[0][m_spacedim];
674 m_frame.SetAngle(angle);
675 m_frame.BodyToInerital(3, forcebody, force);
676 m_frame.BodyToInerital(3, forcebody + 3, tmp = force + 3);
677 }
678 else
679 {
680 Vmath::Vcopy(6, forcebody, 1, force, 1);
681 }
682 for (int i = 0; i < m_spacedim; ++i)
683 {
684 force[i] += m_body.extForceXYZ[i];
685 }
686 force[m_spacedim] = force[5] + m_body.extForceXYZ[5];
687 m_bodySolver.SolveFree(bodyVel, force);
688 }
689 else
690 {
691 Array<OneD, Array<OneD, NekDouble>> tmpbodyVel(bodyVel.size());
692 for (size_t i = 0; i < bodyVel.size(); ++i)
693 {
694 tmpbodyVel[i] = Array<OneD, NekDouble>(bodyVel[i].size());
695 }
696 Array<OneD, NekDouble> angle(3, 0.);
697 angle[2] = bodyVel[0][m_spacedim];
698 for (int iter = 0; iter < 2; ++iter)
699 {
700 // copy initial condition
701 for (size_t i = 0; i < bodyVel.size(); ++i)
702 {
703 Vmath::Vcopy(bodyVel[i].size(), bodyVel[i], 1, tmpbodyVel[i],
704 1);
705 }
706 Array<OneD, NekDouble> force(6, 0.), tmp;
707 m_frame.SetAngle(angle);
708 m_frame.BodyToInerital(3, forcebody, force);
709 m_frame.BodyToInerital(3, forcebody + 3, tmp = force + 3);
710 for (int i = 0; i < m_spacedim; ++i)
711 {
712 force[i] += m_body.extForceXYZ[i];
713 }
714 force[m_spacedim] = force[5] + m_body.extForceXYZ[5];
715 m_bodySolver.Solve(tmpbodyVel, force, Dirs);
716 angle[2] = tmpbodyVel[0][m_spacedim];
717 }
718 // copy final results
719 for (size_t i = 0; i < bodyVel.size(); ++i)
720 {
721 Vmath::Vcopy(bodyVel[i].size(), tmpbodyVel[i], 1, bodyVel[i], 1);
722 }
723 }
724}
void SetAngle(const Array< OneD, NekDouble > theta)
void BodyToInerital(const int dim, const Array< OneD, NekDouble > &body, Array< OneD, NekDouble > &inertial)
void SolveFree(Array< OneD, Array< OneD, NekDouble > > u, Array< OneD, NekDouble > force)
void SolvePrescribed(Array< OneD, Array< OneD, NekDouble > > u, std::map< int, NekDouble > motionPrescribed)
void Solve(Array< OneD, Array< OneD, NekDouble > > u, Array< OneD, NekDouble > force, std::map< int, NekDouble > motionPrescribed)

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

Referenced by UpdateFrameVelocity().

◆ UpdateBoundaryConditions()

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

Set velocity boundary condition at the next time step.

Definition at line 751 of file ForcingMovingReferenceFrame.cpp.

752{
753 time += m_timestep;
754 // compute the velocities whose functions are provided in inertial frame
755 std::map<int, NekDouble> Dirs;
756 UpdatePrescribed(time, Dirs);
757 Array<OneD, Array<OneD, NekDouble>> bodyVel(m_body.vel.size());
758 for (size_t i = 0; i < m_body.vel.size(); ++i)
759 {
760 bodyVel[i] = Array<OneD, NekDouble>(m_body.vel[i].size());
761 Vmath::Vcopy(m_body.vel[i].size(), m_body.vel[i], 1, bodyVel[i], 1);
762 }
763 m_bodySolver.SolvePrescribed(bodyVel, Dirs);
764 // set displacements at the next time step
765 UpdateFluidInterface(bodyVel, 1);
766}

References m_body, m_bodySolver, m_timestep, Nektar::SolverUtils::Newmark_BetaSolver::SolvePrescribed(), UpdateFluidInterface(), UpdatePrescribed(), and Vmath::Vcopy().

Referenced by v_Apply().

◆ UpdateFluidInterface()

void Nektar::SolverUtils::ForcingMovingReferenceFrame::UpdateFluidInterface ( Array< OneD, Array< OneD, NekDouble > > &  bodyVel,
const int  step 
)
private

Definition at line 621 of file ForcingMovingReferenceFrame.cpp.

623{
624 // set displacements at the current or next time step
625 Array<OneD, NekDouble> disp(6, 0.);
626 Array<OneD, NekDouble> vel(12, 0.0);
627 for (int i = 0; i < m_spacedim; ++i)
628 {
629 disp[i] = bodyVel[0][i];
630 }
631 if (!m_body.isCircular)
632 {
633 disp[5] = bodyVel[0][m_spacedim];
634 }
635 // to set the boundary condition of the next time step
636 // update the frame velocities and accelerations
637 for (int i = 0; i < m_spacedim; ++i)
638 {
639 vel[i] = bodyVel[1][i];
640 vel[i + 6] = bodyVel[2][i];
641 }
642 vel[5] = bodyVel[1][m_spacedim];
643 vel[11] = bodyVel[2][m_spacedim];
644 Array<OneD, NekDouble> tmp;
645 if (step && m_hasRotation)
646 {
647 m_frame.SetAngle(disp + 3);
649 m_frame.IneritalToBody(3, vel + 6, tmp = vel + 6);
650 }
651 auto equ = m_equ.lock();
652 ASSERTL0(equ, "Weak pointer to the equation system is expired");
653 auto FluidEq = std::dynamic_pointer_cast<FluidInterface>(equ);
654 FluidEq->SetMovingFrameVelocities(vel, step);
655 FluidEq->SetMovingFrameDisp(disp, step);
656}
void IneritalToBody(const int dim, const Array< OneD, NekDouble > &inertial, Array< OneD, NekDouble > &body)

References ASSERTL0, Nektar::SolverUtils::FrameTransform::IneritalToBody(), m_body, Nektar::SolverUtils::Forcing::m_equ, m_frame, m_hasRotation, m_spacedim, Nektar::SolverUtils::FrameTransform::SetAngle(), and vel.

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

◆ UpdateFrameVelocity()

void Nektar::SolverUtils::ForcingMovingReferenceFrame::UpdateFrameVelocity ( 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 556 of file ForcingMovingReferenceFrame.cpp.

559{
560 if (m_currentTime >= time)
561 {
562 return;
563 }
564 m_currentTime = time;
565 std::map<int, NekDouble> Dirs;
566 UpdatePrescribed(time, Dirs);
567 if (m_index == 0)
568 {
570 }
571 else
572 {
573 // compute the velocites whoes functions are provided in inertial frame
574 Array<OneD, NekDouble> forcebody(6, 0.); // fluid force
575 if (m_body.hasFreeMotion)
576 {
577 for (auto it : m_body.extForceFunction)
578 {
579 m_body.extForceXYZ[it.first] =
580 it.second->Evaluate(0., 0., 0., time);
581 }
582 m_body.aeroforceFilter->GetForces(pFields, NullNekDouble1DArray,
583 time);
584 auto equ = m_equ.lock();
585 ASSERTL0(equ, "Weak pointer to the equation system is expired");
586 auto FluidEq = std::dynamic_pointer_cast<FluidInterface>(equ);
587 FluidEq->GetAeroForce(forcebody);
588 }
589 SolveBodyMotion(m_body.vel, forcebody, Dirs);
590 }
591 if (m_isRoot && m_index % m_outputFrequency == 0)
592 {
593 m_outputStream << boost::format("%25.19e") % time << " ";
594 for (size_t i = 0; i < m_body.vel[0].size(); ++i)
595 {
596 m_outputStream << boost::format("%25.19e") % m_body.vel[0][i] << " "
597 << boost::format("%25.19e") % m_body.vel[1][i] << " "
598 << boost::format("%25.19e") % m_body.vel[2][i]
599 << " ";
600 }
601 m_outputStream << std::endl;
602 }
603 // extract values and transform to body frame
604 for (int i = 0; i < m_spacedim; ++i)
605 {
606 m_velxyz[i] = m_body.vel[1][i];
607 }
608 if (m_hasRotation)
609 {
610 m_omegaxyz[2] = m_body.vel[1][m_spacedim];
611 Array<OneD, NekDouble> angle(3, 0.);
612 angle[2] = m_body.vel[0][m_spacedim];
613 m_frame.SetAngle(angle);
615 }
616 // set displacements at the current time step
618 ++m_index;
619}
void SolveBodyMotion(Array< OneD, Array< OneD, NekDouble > > &bodyVel, const Array< OneD, NekDouble > &forcebody, std::map< int, NekDouble > &Dirs)
static Array< OneD, NekDouble > NullNekDouble1DArray

References ASSERTL0, CellMLToNektar.pycml::format, Nektar::SolverUtils::FrameTransform::IneritalToBody(), m_body, m_currentTime, Nektar::SolverUtils::Forcing::m_equ, m_frame, m_hasRotation, m_index, m_isRoot, m_omegaxyz, m_outputFrequency, m_outputStream, m_spacedim, m_velxyz, Nektar::NullNekDouble1DArray, Nektar::SolverUtils::FrameTransform::SetAngle(), SetInitialConditions(), SolveBodyMotion(), UpdateFluidInterface(), and UpdatePrescribed().

Referenced by v_PreApply().

◆ UpdatePrescribed()

void Nektar::SolverUtils::ForcingMovingReferenceFrame::UpdatePrescribed ( const NekDouble time,
std::map< int, NekDouble > &  Dirs 
)
private

Definition at line 508 of file ForcingMovingReferenceFrame.cpp.

510{
511 int NumDof = m_spacedim + 1;
512 for (auto it : m_frameVelFunction)
513 {
514 if (it.first < 3)
515 {
516 Dirs[it.first] = it.second->Evaluate(0., 0., 0., time);
517 }
518 else if (it.first == 5)
519 {
520 Dirs[m_spacedim] = it.second->Evaluate(0., 0., 0., time);
521 }
522 else if (it.first < 9)
523 {
524 Dirs[NumDof + it.first - 6] = it.second->Evaluate(0., 0., 0., time);
525 }
526 else if (it.first == 11)
527 {
528 Dirs[NumDof + m_spacedim] = it.second->Evaluate(0., 0., 0., time);
529 }
530 else if (it.first < 15)
531 {
532 Dirs[(NumDof << 1) + it.first - 12] =
533 it.second->Evaluate(0., 0., 0., time);
534 }
535 else if (it.first == 17)
536 {
537 Dirs[(NumDof << 1) + m_spacedim] =
538 it.second->Evaluate(0., 0., 0., time);
539 }
540 }
541 for (auto i : m_body.dirDoFs)
542 {
543 if (Dirs.find(i) == Dirs.end())
544 {
545 Dirs[i] = 0.;
546 Dirs[i + NumDof] = 0.;
547 Dirs[i + (NumDof << 1)] = 0.;
548 }
549 }
550}

References m_body, m_frameVelFunction, and m_spacedim.

Referenced by SetInitialConditions(), UpdateBoundaryConditions(), and UpdateFrameVelocity().

◆ 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 733 of file ForcingMovingReferenceFrame.cpp.

737{
738 // If there is no rotation, body force is zero,
739 // nothing needs to be done here.
740 if (m_hasRotation)
741 {
742 int npoints = fields[0]->GetNpoints();
743 addRotation(npoints, outarray, -1., inarray, outarray);
744 }
746}
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 86 of file ForcingMovingReferenceFrame.cpp.

90{
91 m_session->MatchSolverInfo("Homogeneous", "1D", m_isH1d, false);
92 m_session->MatchSolverInfo("Homogeneous", "2D", m_isH2d, false);
93 bool singleMode, halfMode;
94 m_session->MatchSolverInfo("ModeType", "SingleMode", singleMode, false);
95 m_session->MatchSolverInfo("ModeType", "HalfMode", halfMode, false);
96 if (singleMode || halfMode)
97 {
98 m_isH1d = false;
99 }
100 m_expdim = m_isH2d ? 1 : pFields[0]->GetGraph()->GetMeshDimension();
101 m_spacedim = m_expdim + (m_isH1d ? 1 : 0) + (m_isH2d ? 2 : 0);
102 m_isRoot = pFields[0]->GetComm()->TreatAsRankZero();
103 m_hasPlane0 = true;
104 if (m_isH1d)
105 {
106 m_hasPlane0 = pFields[0]->GetZIDs()[0] == 0;
107 }
108 // initialize variables
109 m_velxyz = Array<OneD, NekDouble>(3, 0.0);
110 m_omegaxyz = Array<OneD, NekDouble>(3, 0.0);
111 m_body.extForceXYZ = Array<OneD, NekDouble>(6, 0.0);
112 m_hasVel = Array<OneD, bool>(3, false);
113 m_hasOmega = Array<OneD, bool>(3, false);
114 m_travelWave = Array<OneD, NekDouble>(3, 0.);
115 m_pivotPoint = Array<OneD, NekDouble>(3, 0.0);
116 m_index = 0;
117 m_currentTime = -1.;
118 LoadParameters(pForce);
119 InitBodySolver(pForce);
120 if (m_body.isCircular || m_expdim == 1)
121 {
122 for (int i = 0; i < 3; ++i)
123 {
124 m_hasOmega[i] = false;
125 }
126 m_hasRotation = false;
127 }
128 // account for the effect of rotation
129 // Omega_X results in having v and w even if not defined by user
130 // Omega_Y results in having u and w even if not defined by user
131 // Omega_Z results in having u and v even if not defined by user
132 for (int i = 0; i < 3; ++i)
133 {
134 int j = (i + 1) % 3;
135 int k = (i + 2) % 3;
136 if (m_hasOmega[i])
137 {
138 m_hasVel[j] = true;
139 m_hasVel[k] = true;
140 }
141 }
142 if (m_hasRotation)
143 {
144 int npoints = pFields[0]->GetNpoints();
145 m_coords = Array<OneD, Array<OneD, NekDouble>>(3);
146 for (int j = 0; j < m_spacedim; ++j)
147 {
148 m_coords[j] = Array<OneD, NekDouble>(npoints);
149 }
150 pFields[0]->GetCoords(m_coords[0], m_coords[1], m_coords[2]);
151 // move the origin to the pivot point
152 for (int i = 0; i < m_spacedim; ++i)
153 {
154 Vmath::Sadd(npoints, -m_pivotPoint[i], m_coords[i], 1, m_coords[i],
155 1);
156 }
157 }
158 // initialise pivot point for fluid interface
159 auto equ = m_equ.lock();
160 ASSERTL0(equ, "Weak pointer to the equation system is expired");
161 auto FluidEq = std::dynamic_pointer_cast<FluidInterface>(equ);
162 FluidEq->SetMovingFramePivot(m_pivotPoint);
163 // initialize aeroforce filter
164 if (m_body.hasFreeMotion)
165 {
166 InitialiseFilter(m_session, pFields, pForce);
167 }
168}
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, InitBodySolver(), InitialiseFilter(), LoadParameters(), m_body, m_coords, m_currentTime, Nektar::SolverUtils::Forcing::m_equ, m_expdim, m_hasOmega, m_hasPlane0, m_hasRotation, m_hasVel, m_index, m_isH1d, m_isH2d, m_isRoot, m_omegaxyz, m_pivotPoint, Nektar::SolverUtils::Forcing::m_session, m_spacedim, m_travelWave, 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

Compute the moving frame velocity at given time.

Reimplemented from Nektar::SolverUtils::Forcing.

Definition at line 826 of file ForcingMovingReferenceFrame.cpp.

830{
831 UpdateFrameVelocity(fields, time);
832 int npoints = fields[0]->GetNpoints();
833 if (m_isH2d && fields[0]->GetWaveSpace())
834 {
835 for (int i = 0; i < m_spacedim; ++i)
836 {
837 if (m_hasVel[i])
838 {
839 Array<OneD, NekDouble> tmpphys(npoints,
840 -m_velxyz[i] - m_travelWave[i]);
841 Array<OneD, NekDouble> tmpcoef(npoints);
842 fields[0]->HomogeneousFwdTrans(npoints, tmpphys, tmpcoef);
843 Vmath::Vadd(npoints, tmpcoef, 1, inarray[i], 1, outarray[i], 1);
844 }
845 else if (&inarray != &outarray)
846 {
847 Vmath::Vcopy(npoints, inarray[i], 1, outarray[i], 1);
848 }
849 }
850 }
851 else
852 {
853 int npoints0 = npoints;
854 if (m_isH1d && fields[0]->GetWaveSpace())
855 {
856 npoints0 = m_hasPlane0 ? fields[0]->GetPlane(0)->GetNpoints() : 0;
857 }
858 for (int i = 0; i < m_spacedim; ++i)
859 {
860 if (m_hasVel[i])
861 {
862 Vmath::Sadd(npoints0, -m_velxyz[i] - m_travelWave[i],
863 inarray[i], 1, outarray[i], 1);
864 if (&inarray != &outarray && npoints != npoints0)
865 {
866 Array<OneD, NekDouble> tmp = outarray[i] + npoints0;
867 Vmath::Vcopy(npoints - npoints0, inarray[i] + npoints0, 1,
868 tmp, 1);
869 }
870 }
871 else if (&inarray != &outarray)
872 {
873 Vmath::Vcopy(npoints, inarray[i], 1, outarray[i], 1);
874 }
875 }
876 if (m_hasRotation)
877 {
878 addRotation(npoints0, outarray, -1., m_coords, outarray);
879 }
880 }
881}
void UpdateFrameVelocity(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(), UpdateFrameVelocity(), Vmath::Vadd(), and Vmath::Vcopy().

Friends And Related Function Documentation

◆ MemoryManager< ForcingMovingReferenceFrame >

Definition at line 102 of file ForcingMovingReferenceFrame.h.

Member Data Documentation

◆ aeroforceFilter

FilterAeroForcesSharedPtr Nektar::SolverUtils::ForcingMovingReferenceFrame::aeroforceFilter

Definition at line 193 of file ForcingMovingReferenceFrame.h.

◆ C

Array<OneD, NekDouble> Nektar::SolverUtils::ForcingMovingReferenceFrame::C

Definition at line 198 of file ForcingMovingReferenceFrame.h.

◆ 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.
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:41

Name of the class.

Definition at line 126 of file ForcingMovingReferenceFrame.h.

◆ dirDoFs

std::set<int> Nektar::SolverUtils::ForcingMovingReferenceFrame::dirDoFs

Definition at line 190 of file ForcingMovingReferenceFrame.h.

◆ extForceFunction

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

Definition at line 195 of file ForcingMovingReferenceFrame.h.

◆ extForceXYZ

Array<OneD, NekDouble> Nektar::SolverUtils::ForcingMovingReferenceFrame::extForceXYZ

Definition at line 196 of file ForcingMovingReferenceFrame.h.

◆ hasFreeMotion

bool Nektar::SolverUtils::ForcingMovingReferenceFrame::hasFreeMotion

Definition at line 189 of file ForcingMovingReferenceFrame.h.

◆ isCircular

bool Nektar::SolverUtils::ForcingMovingReferenceFrame::isCircular

Definition at line 191 of file ForcingMovingReferenceFrame.h.

◆ K

Array<OneD, NekDouble> Nektar::SolverUtils::ForcingMovingReferenceFrame::K

Definition at line 199 of file ForcingMovingReferenceFrame.h.

◆ M

Array<OneD, NekDouble> Nektar::SolverUtils::ForcingMovingReferenceFrame::M

Definition at line 197 of file ForcingMovingReferenceFrame.h.

◆ 

struct { ... } Nektar::SolverUtils::ForcingMovingReferenceFrame::m_body

◆ m_bodySolver

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

◆ m_coords

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

Definition at line 173 of file ForcingMovingReferenceFrame.h.

Referenced by v_InitObject(), and v_PreApply().

◆ m_currentTime

NekDouble Nektar::SolverUtils::ForcingMovingReferenceFrame::m_currentTime
private

Definition at line 175 of file ForcingMovingReferenceFrame.h.

Referenced by UpdateFrameVelocity(), and v_InitObject().

◆ m_expdim

int32_t Nektar::SolverUtils::ForcingMovingReferenceFrame::m_expdim
private

Definition at line 182 of file ForcingMovingReferenceFrame.h.

Referenced by v_InitObject().

◆ m_frame

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

◆ m_frameVelFunction

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

Definition at line 155 of file ForcingMovingReferenceFrame.h.

Referenced by LoadParameters(), and UpdatePrescribed().

◆ m_hasOmega

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

◆ m_hasPlane0

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

Definition at line 179 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 183 of file ForcingMovingReferenceFrame.h.

Referenced by UpdateFrameVelocity(), and v_InitObject().

◆ m_isH1d

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

Definition at line 178 of file ForcingMovingReferenceFrame.h.

Referenced by v_InitObject(), and v_PreApply().

◆ m_isH2d

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

Definition at line 180 of file ForcingMovingReferenceFrame.h.

Referenced by v_InitObject(), and v_PreApply().

◆ m_isRoot

bool Nektar::SolverUtils::ForcingMovingReferenceFrame::m_isRoot
private

◆ m_omegaxyz

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

Definition at line 171 of file ForcingMovingReferenceFrame.h.

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

◆ m_outputFrequency

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

Definition at line 184 of file ForcingMovingReferenceFrame.h.

Referenced by LoadParameters(), and UpdateFrameVelocity().

◆ m_outputStream

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

◆ m_pivotPoint

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

Definition at line 150 of file ForcingMovingReferenceFrame.h.

Referenced by LoadParameters(), and v_InitObject().

◆ m_spacedim

int32_t Nektar::SolverUtils::ForcingMovingReferenceFrame::m_spacedim
private

◆ m_timestep

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

Definition at line 176 of file ForcingMovingReferenceFrame.h.

Referenced by InitBodySolver(), and UpdateBoundaryConditions().

◆ m_travelWave

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

Definition at line 151 of file ForcingMovingReferenceFrame.h.

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

◆ m_velxyz

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

Definition at line 168 of file ForcingMovingReferenceFrame.h.

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

◆ vel

Array<OneD, Array<OneD, NekDouble> > Nektar::SolverUtils::ForcingMovingReferenceFrame::vel

Definition at line 188 of file ForcingMovingReferenceFrame.h.

Referenced by UpdateFluidInterface().