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

This processing module calculates the wall shear stress and adds it as an extra-field to the output file, and writes it to a surface output file. More...

#include <ProcessBodyFittedVelocity.h>

Inheritance diagram for Nektar::FieldUtils::ProcessBodyFittedVelocity:
[legend]

Public Member Functions

 ProcessBodyFittedVelocity (FieldSharedPtr f)
 
virtual ~ProcessBodyFittedVelocity ()
 
void GenPntwiseBodyFittedCoordSys (const int targetBndId, const Array< OneD, NekDouble > assistVec, Array< OneD, NekDouble > &distance, Array< OneD, Array< OneD, Array< OneD, NekDouble >>> &bfcsDir, const bool isCheckAngle, const NekDouble distTol=1.0e-12, const NekDouble iterTol=1.0e-12, const NekDouble dirTol=1.0e-4, const NekDouble geoTol=1.0e-12)
 At each quadrature point inside the domian, compute the body-fitted coordinate system with respect to the input boundary id. More...
 
- Public Member Functions inherited from Nektar::FieldUtils::ProcessBoundaryExtract
 ProcessBoundaryExtract (FieldSharedPtr f)
 
virtual ~ProcessBoundaryExtract ()
 
- Public Member Functions inherited from Nektar::FieldUtils::ProcessModule
 ProcessModule ()
 
 ProcessModule (FieldSharedPtr p_f)
 
- Public Member Functions inherited from Nektar::FieldUtils::Module
FIELD_UTILS_EXPORT Module (FieldSharedPtr p_f)
 
virtual ~Module ()=default
 
void Process (po::variables_map &vm)
 
std::string GetModuleName ()
 
std::string GetModuleDescription ()
 
const ConfigOptionGetConfigOption (const std::string &key) const
 
ModulePriority GetModulePriority ()
 
FIELD_UTILS_EXPORT void RegisterConfig (std::string key, std::string value="")
 Register a configuration option with a module. More...
 
FIELD_UTILS_EXPORT void PrintConfig ()
 Print out all configuration options for a module. More...
 
FIELD_UTILS_EXPORT void SetDefaults ()
 Sets default configuration options for those which have not been set. More...
 
FIELD_UTILS_EXPORT void AddFile (std::string fileType, std::string fileName)
 
FIELD_UTILS_EXPORT void EvaluateTriFieldAtEquiSpacedPts (LocalRegions::ExpansionSharedPtr &exp, const Array< OneD, const NekDouble > &infield, Array< OneD, NekDouble > &outfield)
 

Static Public Member Functions

static std::shared_ptr< Modulecreate (FieldSharedPtr f)
 Creates an instance of this class. More...
 
- Static Public Member Functions inherited from Nektar::FieldUtils::ProcessBoundaryExtract
static std::shared_ptr< Modulecreate (FieldSharedPtr f)
 Creates an instance of this class. More...
 

Static Public Attributes

static ModuleKey className
 
- Static Public Attributes inherited from Nektar::FieldUtils::ProcessBoundaryExtract
static ModuleKey className
 

Protected Member Functions

virtual void v_Process (po::variables_map &vm) override
 Write mesh to output file. More...
 
virtual std::string v_GetModuleName () override
 
virtual std::string v_GetModuleDescription () override
 
- Protected Member Functions inherited from Nektar::FieldUtils::ProcessBoundaryExtract
virtual ModulePriority v_GetModulePriority () override
 
- Protected Member Functions inherited from Nektar::FieldUtils::Module
 Module ()
 

Private Member Functions

NekDouble PntToBndElmtPntDistance (const Array< OneD, Array< OneD, NekDouble >> &pts, const int pId, const Array< OneD, Array< OneD, NekDouble >> &bndPts)
 Compute the local coordinate for the nearest point on the given 2D boundary element to the input point. More...
 
bool LocCoordForNearestPntOnBndElmt_2D (const Array< OneD, const NekDouble > &inGloCoord, SpatialDomains::GeometrySharedPtr bndGeom, const Array< OneD, Array< OneD, NekDouble >> &pts, Array< OneD, NekDouble > &locCoord, Array< OneD, NekDouble > &gloCoord, NekDouble &dist, const NekDouble iterTol=1.0e-12, const int iterMax=51)
 Compute the local coordinate for the nearest point on the given 2D boundary element to the input point. More...
 
bool LocCoordForNearestPntOnBndElmt (const Array< OneD, const NekDouble > &inGloCoord, SpatialDomains::GeometrySharedPtr bndGeom, Array< OneD, NekDouble > &locCoord, Array< OneD, NekDouble > &gloCoord, NekDouble &dist, const NekDouble iterTol=1.0e-12, const int iterMax=51)
 Compute the local coordinate for the nearest point on the given boundary element to the input point. The locCoord is the position to set up the body-fitted coordinate. This function works as a driver. More...
 
void ScaledCrosssProduct (const Array< OneD, NekDouble > &vec1, const Array< OneD, NekDouble > &vec2, Array< OneD, NekDouble > &vec3)
 Compute the normalized cross product for two 2D vectors. vec3 = vec1 x vec2. More...
 
void GetVelAndConvertToCartSys (Array< OneD, Array< OneD, NekDouble >> &vel)
 Get velocity and convert to Cartesian system, if it is still in transformed system. It is copied and modified from from ProcessGrad.cpp. More...
 

Additional Inherited Members

- Public Attributes inherited from Nektar::FieldUtils::Module
FieldSharedPtr m_f
 Field object. More...
 
- Protected Attributes inherited from Nektar::FieldUtils::Module
std::map< std::string, ConfigOptionm_config
 List of configuration values. More...
 
std::set< std::string > m_allowedFiles
 List of allowed file formats. More...
 

Detailed Description

This processing module calculates the wall shear stress and adds it as an extra-field to the output file, and writes it to a surface output file.

Definition at line 50 of file ProcessBodyFittedVelocity.h.

Constructor & Destructor Documentation

◆ ProcessBodyFittedVelocity()

Nektar::FieldUtils::ProcessBodyFittedVelocity::ProcessBodyFittedVelocity ( FieldSharedPtr  f)

Definition at line 64 of file ProcessBodyFittedVelocity.cpp.

66 {
67  f->m_writeBndFld =
68  false; // turned on in the father class ProcessBoundaryExtract
69 
70  // bnd is read from father class ProcessBoundaryExtract
71  m_config["assistDir"] =
72  ConfigOption(false, "0.0,0.0,1.0",
73  "The normal direction of the assistant plane, where \
74  the first body-fitted coordinate direction is located. \
75  The assistance plane is defined in point normal form. \
76  Default = [0,0,1]");
77  m_config["checkAngle"] =
78  ConfigOption(true, "0", "The flag for checking the distance vector \
79  perpendicular to the nearest element or not. It \
80  does not need to be turned on if geometry is \
81  smooth and there is no special consideration of \
82  the body-fitted coordinate system. It would be \
83  helpful to set up a desired coordinate system \
84  based on the surface with with sharp corners, \
85  such as at the presence of a step or gap. \
86  Default = false.");
87  m_config["distTol"] = ConfigOption(
88  false, "1.0e-12", "The distance tolerence to properly find out the \
89  nearest boundary element. It works together with \
90  the CHECKANGLE option to set up the body-fitted \
91  coordinate system near the corner. \
92  Default = 1.0e-12.");
93  m_config["bfcOut"] = ConfigOption(
94  true, "1", "The flag control whether the body-fitted coordinate \
95  system will be output. Default = true.");
96 }
std::map< std::string, ConfigOption > m_config
List of configuration values.
Definition: Module.h:263

References Nektar::FieldUtils::Module::m_config.

◆ ~ProcessBodyFittedVelocity()

Nektar::FieldUtils::ProcessBodyFittedVelocity::~ProcessBodyFittedVelocity ( )
virtual

Definition at line 98 of file ProcessBodyFittedVelocity.cpp.

99 {
100 }

Member Function Documentation

◆ create()

static std::shared_ptr<Module> Nektar::FieldUtils::ProcessBodyFittedVelocity::create ( FieldSharedPtr  f)
inlinestatic

Creates an instance of this class.

Definition at line 54 of file ProcessBodyFittedVelocity.h.

55  {
57  }
static std::shared_ptr< DataType > AllocateSharedPtr(const Args &...args)
Allocate a shared pointer from the memory pool.

References Nektar::MemoryManager< DataType >::AllocateSharedPtr().

◆ GenPntwiseBodyFittedCoordSys()

void Nektar::FieldUtils::ProcessBodyFittedVelocity::GenPntwiseBodyFittedCoordSys ( const int  targetBndId,
const Array< OneD, NekDouble assistVec,
Array< OneD, NekDouble > &  distance,
Array< OneD, Array< OneD, Array< OneD, NekDouble >>> &  bfcsDir,
const bool  isCheckAngle,
const NekDouble  distTol = 1.0e-12,
const NekDouble  iterTol = 1.0e-12,
const NekDouble  dirTol = 1.0e-4,
const NekDouble  geoTol = 1.0e-12 
)

At each quadrature point inside the domian, compute the body-fitted coordinate system with respect to the input boundary id.

Parameters
targetBndIdTarget boundary id.
assistVecUnit assistant vector, the cross product of inward- pointing wall normalId and wihch gives of the main tangential direction of the body-fitted system.
bfcsDirPointwise body-fitted coordinate system.
isPerpendicularConditionFlag for using perpendicular check or not
distTolDistance tolerence. Used to find the boundary elements for local coordinate iteration.
iterTolIteration tolerence. Used to check iteration convergence.
dirTolDirection tolerencce. Used to check if the inner product of two unit vectors is cloes enough to 1.0.
geoTolGeometry tolerence. Used as the relative tolerence for local coord and distance absolute tolerence.

Definition at line 506 of file ProcessBodyFittedVelocity.cpp.

512 {
513 
514  const int nFields = m_f->m_variables.size();
515  const int nCoordDim = m_f->m_exp[0]->GetCoordim(0);
516  const int nSpaceDim = nCoordDim + m_f->m_numHomogeneousDir;
517  const int nBndLcoordDim = nCoordDim - 1;
518 
519  // Get expansion list for boundary
520  Array<OneD, MultiRegions::ExpListSharedPtr> BndExp(nFields);
521  for (int i = 0; i < nFields; ++i)
522  {
523  BndExp[i] = m_f->m_exp[i]->UpdateBndCondExpansion(targetBndId);
524  }
525 
526  const int nElmts = m_f->m_exp[0]->GetNumElmts(); // num of inner element
527  const int nBndElmts = BndExp[0]->GetNumElmts(); // num of bnd element
528 
529  // Use the outward-pointing normal at quardrature pts on bnd elmt as dir ref
530  Array<OneD, Array<OneD, NekDouble>> normalQ;
531  m_f->m_exp[0]->GetBoundaryNormals(targetBndId, normalQ);
532 
533  // Vars in the loop
536  Array<OneD, Array<OneD, NekDouble>> bndCoeffs(nCoordDim);
537  Array<OneD, Array<OneD, NekDouble>> bndPts(nCoordDim);
538 
539  int nPts, nBndPts;
540  NekDouble dist_tmp, dist_bak;
541  bool isConverge;
542  vector<int> bndElmtIds;
543  int bndElmtId, bndElmtId_bak;
544  int phys_offset, bnd_phys_offset;
545 
546  Array<OneD, NekDouble> inGloCoord(3, 0.0); // inner pnt
547  Array<OneD, NekDouble> locCoord(nBndLcoordDim), locCoord_tmp(nBndLcoordDim);
548  Array<OneD, NekDouble> gloCoord(3, 0.0), gloCoord_tmp(3, 0.0);
549  Array<OneD, NekDouble> normal(3), normalRef(3);
550  Array<OneD, NekDouble> tangential1(3),
551  tangential2(3); // 1 - main, 2 - minor
552  Array<OneD, NekDouble> normalChk(3);
553  ProcessWallNormalData wnd(m_f); // wallNormalData object to use its routine
554 
555  // backup for angle check
556  Array<OneD, NekDouble> locCoord_bak(nBndLcoordDim), gloCoord_bak(3, 0.0);
557 
558  //-------------------------------------------------------------------------
559  // Loop all the quadrature points of the field, and find out the closest
560  // point on the bnd for each of them. The bnd element contains this bnd
561  // point is recorded.
562 
563  // Loop inner element
564  for (int eId = 0; eId < nElmts; ++eId) // element id, nElmts
565  {
566  // Get inner points
567  nPts = m_f->m_exp[0]->GetExp(eId)->GetTotPoints();
568  Array<OneD, Array<OneD, NekDouble>> pts(nCoordDim);
569  for (int i = 0; i < nCoordDim; ++i)
570  {
571  pts[i] = Array<OneD, NekDouble>(nPts, 0.0);
572  }
573 
574  if (nCoordDim == 2)
575  {
576  m_f->m_exp[0]->GetExp(eId)->GetCoords(pts[0], pts[1]);
577  }
578  else if (nCoordDim == 3)
579  {
580  m_f->m_exp[0]->GetExp(eId)->GetCoords(pts[0], pts[1], pts[2]);
581  }
582 
583  // Get the offset for the current elmt
584  phys_offset = m_f->m_exp[0]->GetPhys_Offset(eId);
585 
586  // Loop points in the inner element
587  for (int pId = 0; pId < nPts; ++pId)
588  {
589 
590  // Compute the distance from the pnt (bnd elmt) to the inner pnt
591  // Step 1 - Estimate search
592  // - Find the closest quadrature pnt among all the bnd elmt;
593  // - The bnd elmt which contains this pnt is saved for Step 2.
594  // * If the quadtature pnt is on the edge or corner of the bnd
595  // elmt, there will be more than one bnd elmt which contains
596  // this point.
597 
598  bndElmtIds.clear(); // clear the bnd elmt id vec for a new inner pnt
599 
600  // Loop bnd elmt to find the elmt to build body-fitted coord sys
601  for (int beId = 0; beId < nBndElmts; ++beId)
602  {
603  // Get geomery and points
604  bndGeom = BndExp[0]->GetExp(beId)->GetGeom();
605  bndXmap = bndGeom->GetXmap();
606  nBndPts = bndXmap->GetTotPoints();
607 
608  for (int i = 0; i < nCoordDim; ++i)
609  {
610  bndPts[i] = Array<OneD, NekDouble>(nBndPts);
611  bndCoeffs[i] = bndGeom->GetCoeffs(i); // 0/1/2 for x/y/z
612  bndXmap->BwdTrans(bndCoeffs[i], bndPts[i]);
613  }
614 
615  // Compute the distance (estimate)
616  dist_tmp = PntToBndElmtPntDistance(pts, pId, bndPts);
617 
618  if ((dist_tmp < (distance[phys_offset + pId] - geoTol)) &&
619  (dist_tmp < (distance[phys_offset + pId] - distTol)))
620  {
621  // Find a closer quadrature point from a different bnd elmt
622  // Update distance and bnd elmt id vector
623  distance[phys_offset + pId] = dist_tmp;
624  bndElmtIds.clear();
625  bndElmtIds.push_back(beId);
626  }
627  else if ((dist_tmp < (distance[phys_offset + pId] + geoTol)) ||
628  (dist_tmp < (distance[phys_offset + pId] + distTol)))
629  {
630  // The same quadrature point from a different bnd elmt is
631  // found for the other time.
632  // Keep the distance and add the bnd elmt id to the vector
633  bndElmtIds.push_back(beId);
634  }
635 
636  } // end of bnd elmt loop
637 
638  // Step 2 - Accurate search
639  // - Find the accurate distance and locCoord for the nearest pnt
640  // (to the inner point) on the bnd elmt
641  // - This process will be repeated on all the bnd elmts in the bnd
642  // elmt id vector.
643 
644  // Generate the coordinate for the inner point
645  for (int i = 0; i < nCoordDim; ++i)
646  {
647  inGloCoord[i] = pts[i][pId];
648  }
649 
650  // reset the dist to make sure the condition for if will be
651  // satisfied
652  distance[phys_offset + pId] = 9999;
653  bndElmtId = -1;
654  dist_bak = 9999;
655  bndElmtId_bak = -1;
656 
657  // Compute the accurate distance and locCoord
658  for (int i = 0; i < bndElmtIds.size(); ++i)
659  {
660  // Iterate on each of the possible bnd elmt to get the locCoord
661  // and the smallest dist
662  bndGeom = BndExp[0]->GetExp(bndElmtIds[i])->GetGeom();
663 
664  isConverge = LocCoordForNearestPntOnBndElmt(
665  inGloCoord, bndGeom, locCoord_tmp, gloCoord_tmp, dist_tmp,
666  iterTol, 51);
667 
668  if (!isConverge)
669  {
670  WARNINGL1(false, "Bisection iteration is not converged!!!");
671  }
672 
673  // Perpendicular check (angle check)
674  // When activated (distance > geoTol)
675  // if the pnt-to-pnt vector is not parallel with the wall
676  // normal, this bnd will be skipped. It is helpful to avoid
677  // confusion when there are cornors
678  if (isCheckAngle && (dist_tmp > geoTol)) // skip pts on the bnd
679  {
680  // Generate the scaled vector
681  Vmath::Vcopy(nCoordDim, gloCoord_tmp, 1, normalChk, 1);
682  Vmath::Neg(nCoordDim, normalChk, 1);
683  Vmath::Vadd(nCoordDim, inGloCoord, 1, normalChk, 1,
684  normalChk, 1);
685  Vmath::Smul(nCoordDim,
686  1.0 / sqrt(Vmath::Dot(nCoordDim, normalChk, 1,
687  normalChk, 1)),
688  normalChk, 1, normalChk, 1);
689 
690  // Get normal based on the locCoord_tmp
691  wnd.GetNormals(bndGeom, locCoord_tmp, normal);
692 
693  // Reverse the direction to make it point into the field
694  bnd_phys_offset = BndExp[0]->GetPhys_Offset(bndElmtIds[i]);
695  for (int j = 0; j < nCoordDim; ++j)
696  {
697  normalRef[j] = normalQ[j][bnd_phys_offset];
698  }
699 
700  if (Vmath::Dot(nCoordDim, normal, normalRef) > 0.0)
701  {
702  Vmath::Neg(nCoordDim, normal, 1);
703  }
704 
705  // Check if the current bnd elmt convers this inner pnt
706  if (Vmath::Dot(nCoordDim, normalChk, 1, normal, 1) <
707  (1 - dirTol))
708  {
709  // If not covered, save the nearest result as backup
710  // Then skip
711  if (dist_tmp < dist_bak)
712  {
713  bndElmtId_bak = bndElmtIds[i];
714  dist_bak = dist_tmp;
715 
716  for (int j = 0; j < nBndLcoordDim; ++j)
717  {
718  locCoord_bak[j] = locCoord_tmp[j];
719  }
720 
721  for (int j = 0; j < 3; ++j)
722  {
723  gloCoord_bak[j] = gloCoord_tmp[j];
724  }
725  }
726 
727  continue; // Skip current bnd elmt
728  }
729  }
730 
731  // No violation occurs, update the current result
732  // This section must be executed at least once if there the
733  // angle check is turned off. It means the following
734  // (bndElmtId == -1) can only be caused by angle check.
735  if (dist_tmp < distance[phys_offset + pId])
736  {
737  bndElmtId = bndElmtIds[i];
738  distance[phys_offset + pId] = dist_tmp;
739 
740  for (int j = 0; j < nBndLcoordDim; ++j)
741  {
742  locCoord[j] = locCoord_tmp[j];
743  }
744 
745  for (int j = 0; j < 3; ++j)
746  {
747  gloCoord[j] = gloCoord_tmp[j];
748  }
749  }
750  }
751 
752  // Check if the bnd elmt is found. If not, use nearest one.
753  if (bndElmtId == -1)
754  {
755  if (bndElmtIds.size() == 0)
756  {
757  ASSERTL0(false, "No boundary element is found to be the \
758  possible nearest element. Please check.");
759  }
760 
761  distance[phys_offset + pId] = dist_bak;
762  bndElmtId = bndElmtId_bak;
763 
764  for (int i = 0; i < nBndLcoordDim; ++i)
765  {
766  locCoord[i] = locCoord_bak[i];
767  }
768 
769  for (int i = 0; i < 3; ++i)
770  {
771  gloCoord[i] = gloCoord_bak[i];
772  }
773 
774  WARNINGL1(false,
775  "The boundary element is not found under given \
776  tolerence. Please check and reset the \
777  tolerence, or just turn off the angle check. \
778  If you would like to continue, the nearest \
779  boundary element is used.");
780  }
781 
782  // Get the wall normal using the function in wallNormalData class
783  bndGeom = BndExp[0]->GetExp(bndElmtId)->GetGeom();
784  wnd.GetNormals(bndGeom, locCoord, normal);
785 
786  // Get ref normal for outward-point dir
787  bnd_phys_offset = BndExp[0]->GetPhys_Offset(bndElmtId);
788  for (int i = 0; i < nCoordDim; ++i)
789  {
790  normalRef[i] = normalQ[i][bnd_phys_offset];
791  }
792 
793  // Correct the normal direction to make sure it points inward
794  if (Vmath::Dot(nCoordDim, normal, normalRef) > 0.0)
795  {
796  Vmath::Neg(nCoordDim, normal, 1);
797  }
798 
799  // The main tagential direction is defined to be overlapped with the
800  // intersection line of the tangantial plane and the assistant
801  // plane, whose normal is the input assistDir. Both plane is defined
802  // using the point normal form, where the point is the nearest point
803  // on the boundary (gloCoord), and the vectors are the normal
804  // (pointing out) and the assistant direction (assistDir).
805  // Therefore, the main tangantial direction can be obtained by the
806  // cross product of the two vectors, since the two vectors has the
807  // same starting point and the tangantial direction is perpendicular
808  // to both of them.
809  ScaledCrosssProduct(normal, assistVec, tangential1);
810 
811  // Save the direction vectors
812  for (int i = 0; i < nSpaceDim; ++i)
813  {
814  bfcsDir[0][i][phys_offset + pId] = tangential1[i];
815  bfcsDir[1][i][phys_offset + pId] = normal[i];
816  }
817 
818  if (nSpaceDim == 3)
819  {
820  ScaledCrosssProduct(tangential1, normal, tangential2);
821  for (int i = 0; i < 3; ++i)
822  {
823  bfcsDir[2][i][phys_offset + pId] = tangential2[i];
824  }
825  }
826 
827  } // end of inner pts loop
828 
829  } // end of inner elmt loop
830 }
#define WARNINGL1(condition, msg)
Definition: ErrorUtil.hpp:250
#define ASSERTL0(condition, msg)
Definition: ErrorUtil.hpp:215
FieldSharedPtr m_f
Field object.
Definition: Module.h:234
void ScaledCrosssProduct(const Array< OneD, NekDouble > &vec1, const Array< OneD, NekDouble > &vec2, Array< OneD, NekDouble > &vec3)
Compute the normalized cross product for two 2D vectors. vec3 = vec1 x vec2.
NekDouble PntToBndElmtPntDistance(const Array< OneD, Array< OneD, NekDouble >> &pts, const int pId, const Array< OneD, Array< OneD, NekDouble >> &bndPts)
Compute the local coordinate for the nearest point on the given 2D boundary element to the input poin...
bool LocCoordForNearestPntOnBndElmt(const Array< OneD, const NekDouble > &inGloCoord, SpatialDomains::GeometrySharedPtr bndGeom, Array< OneD, NekDouble > &locCoord, Array< OneD, NekDouble > &gloCoord, NekDouble &dist, const NekDouble iterTol=1.0e-12, const int iterMax=51)
Compute the local coordinate for the nearest point on the given boundary element to the input point....
std::shared_ptr< Geometry > GeometrySharedPtr
Definition: Geometry.h:53
std::shared_ptr< StdExpansion > StdExpansionSharedPtr
double NekDouble
void Neg(int n, T *x, const int incx)
Negate x = -x.
Definition: Vmath.cpp:518
T Dot(int n, const T *w, const T *x)
dot (vector times vector): z = w*x
Definition: Vmath.cpp:1100
void Vadd(int n, const T *x, const int incx, const T *y, const int incy, T *z, const int incz)
Add vector z = x+y.
Definition: Vmath.cpp:359
void Smul(int n, const T alpha, const T *x, const int incx, T *y, const int incy)
Scalar multiply y = alpha*x.
Definition: Vmath.cpp:248
void Vcopy(int n, const T *x, const int incx, T *y, const int incy)
Definition: Vmath.cpp:1255
scalarT< T > sqrt(scalarT< T > in)
Definition: scalar.hpp:294

References ASSERTL0, Vmath::Dot(), Nektar::FieldUtils::ProcessWallNormalData::GetNormals(), LocCoordForNearestPntOnBndElmt(), Nektar::FieldUtils::Module::m_f, Vmath::Neg(), PntToBndElmtPntDistance(), ScaledCrosssProduct(), Vmath::Smul(), tinysimd::sqrt(), Vmath::Vadd(), Vmath::Vcopy(), and WARNINGL1.

Referenced by v_Process().

◆ GetVelAndConvertToCartSys()

void Nektar::FieldUtils::ProcessBodyFittedVelocity::GetVelAndConvertToCartSys ( Array< OneD, Array< OneD, NekDouble >> &  vel)
private

Get velocity and convert to Cartesian system, if it is still in transformed system. It is copied and modified from from ProcessGrad.cpp.

Definition at line 837 of file ProcessBodyFittedVelocity.cpp.

839 {
840  int spacedim = m_f->m_exp[0]->GetCoordim(0) + m_f->m_numHomogeneousDir;
841  int nfields = m_f->m_variables.size();
842  int npoints = m_f->m_exp[0]->GetNpoints();
843  int var_offset = 0;
844 
845  // Check type of the fields and set variable offset
846  vector<string> vars = m_f->m_exp[0]->GetSession()->GetVariables();
847  if (boost::iequals(vars[0], "rho") && boost::iequals(vars[1], "rhou"))
848  {
849  var_offset = spacedim + 2;
850  }
851 
852  // Get mapping
854 
855  // Get velocity and convert to Cartesian system,
856  // if it is still in transformed system
857  if (m_f->m_fieldMetaDataMap.count("MappingCartesianVel"))
858  {
859  if (m_f->m_fieldMetaDataMap["MappingCartesianVel"] == "False")
860  {
861  // Initialize arrays and copy velocity
862  for (int i = 0; i < spacedim; ++i)
863  {
864  vel[i] = Array<OneD, NekDouble>(npoints);
865  if (m_f->m_exp[0]->GetWaveSpace())
866  {
867  m_f->m_exp[0]->HomogeneousBwdTrans(
868  npoints, m_f->m_exp[var_offset + i]->GetPhys(), vel[i]);
869  }
870  else
871  {
872  Vmath::Vcopy(npoints, m_f->m_exp[var_offset + i]->GetPhys(),
873  1, vel[i], 1);
874  }
875  }
876  // Convert velocity to cartesian system
877  mapping->ContravarToCartesian(vel, vel);
878  // Convert back to wavespace if necessary
879  if (m_f->m_exp[0]->GetWaveSpace())
880  {
881  for (int i = 0; i < spacedim; ++i)
882  {
883  m_f->m_exp[0]->HomogeneousFwdTrans(npoints, vel[i], vel[i]);
884  }
885  }
886  }
887  else
888  {
889  for (int i = 0; i < spacedim; ++i)
890  {
891  vel[i] = Array<OneD, NekDouble>(npoints);
892  Vmath::Vcopy(npoints, m_f->m_exp[var_offset + i]->GetPhys(), 1,
893  vel[i], 1);
894  }
895  }
896  }
897  else
898  {
899  for (int i = 0; i < spacedim && i < nfields; ++i)
900  {
901  vel[i] = Array<OneD, NekDouble>(npoints);
902  Vmath::Vcopy(npoints, m_f->m_exp[var_offset + i]->GetPhys(), 1,
903  vel[i], 1);
904  }
905  }
906 }
static GlobalMapping::MappingSharedPtr GetMapping(FieldSharedPtr f)
GLOBAL_MAPPING_EXPORT typedef std::shared_ptr< Mapping > MappingSharedPtr
A shared pointer to a Mapping object.
Definition: Mapping.h:50

References Nektar::FieldUtils::ProcessMapping::GetMapping(), Nektar::FieldUtils::Module::m_f, Nektar::GlobalMapping::MappingSharedPtr, and Vmath::Vcopy().

Referenced by v_Process().

◆ LocCoordForNearestPntOnBndElmt()

bool Nektar::FieldUtils::ProcessBodyFittedVelocity::LocCoordForNearestPntOnBndElmt ( const Array< OneD, const NekDouble > &  inGloCoord,
SpatialDomains::GeometrySharedPtr  bndGeom,
Array< OneD, NekDouble > &  locCoord,
Array< OneD, NekDouble > &  gloCoord,
NekDouble dist,
const NekDouble  iterTol = 1.0e-12,
const int  iterMax = 51 
)
private

Compute the local coordinate for the nearest point on the given boundary element to the input point. The locCoord is the position to set up the body-fitted coordinate. This function works as a driver.

Parameters
inGloCoordGlobal coordinate for the input point.
bndGeomGeometry of the boundary element to search from.
locCoordLocal coordinate of the result.
gloCoordGlobal coordinate of the result.
distDistance from the input point to the boundary element.
iterTolIteration tolerence.
iterMaxMax iteration steps.

Definition at line 430 of file ProcessBodyFittedVelocity.cpp.

435 {
436  bool isConverge = false;
437  const int nCoordDim = m_f->m_exp[0]->GetCoordim(0); // =2 for 2.5D cases
438 
439  StdRegions::StdExpansionSharedPtr bndXmap = bndGeom->GetXmap();
440  int nBndPts = bndXmap->GetTotPoints();
441 
442  Array<OneD, Array<OneD, const NekDouble>> bndCoeffs(nCoordDim);
443  Array<OneD, Array<OneD, NekDouble>> bndPts(nCoordDim);
444  for (int i = 0; i < nCoordDim; ++i)
445  {
446  bndPts[i] = Array<OneD, NekDouble>(nBndPts);
447  bndCoeffs[i] = bndGeom->GetCoeffs(i);
448  bndXmap->BwdTrans(bndCoeffs[i], bndPts[i]);
449  }
450 
451  // Compute the locCoord for the pnt on the bnd elmt
452  if (nCoordDim == 2)
453  {
454  // Bisection search
456  inGloCoord, bndGeom, bndPts, locCoord, gloCoord, dist, iterTol,
457  iterMax);
458  }
459  else
460  {
461  // Bi-bisection search
462  ASSERTL0(false, "Not available at the moment.");
463  }
464 
465  return isConverge;
466 }
bool LocCoordForNearestPntOnBndElmt_2D(const Array< OneD, const NekDouble > &inGloCoord, SpatialDomains::GeometrySharedPtr bndGeom, const Array< OneD, Array< OneD, NekDouble >> &pts, Array< OneD, NekDouble > &locCoord, Array< OneD, NekDouble > &gloCoord, NekDouble &dist, const NekDouble iterTol=1.0e-12, const int iterMax=51)
Compute the local coordinate for the nearest point on the given 2D boundary element to the input poin...

References ASSERTL0, LocCoordForNearestPntOnBndElmt_2D(), and Nektar::FieldUtils::Module::m_f.

Referenced by GenPntwiseBodyFittedCoordSys().

◆ LocCoordForNearestPntOnBndElmt_2D()

bool Nektar::FieldUtils::ProcessBodyFittedVelocity::LocCoordForNearestPntOnBndElmt_2D ( const Array< OneD, const NekDouble > &  inGloCoord,
SpatialDomains::GeometrySharedPtr  bndGeom,
const Array< OneD, Array< OneD, NekDouble >> &  pts,
Array< OneD, NekDouble > &  locCoord,
Array< OneD, NekDouble > &  gloCoord,
NekDouble dist,
const NekDouble  iterTol = 1.0e-12,
const int  iterMax = 51 
)
private

Compute the local coordinate for the nearest point on the given 2D boundary element to the input point.

Parameters
inGloCoordGlobal coordinate for the input point.
bndGeomGeometry of the boundary element to search from.
ptsGlobal coordinate of the quadrature points in the boundary element.
locCoordLocal coordinate of the result.
gloCoordGlobal coordinate of the result.
distDistance from the input point to the boundary element.
iterTolIteration tolerence.
iterMaxMax iteration steps.

Definition at line 356 of file ProcessBodyFittedVelocity.cpp.

362 {
363 
364  // Initial settings
365  Array<OneD, NekDouble> etaLR(2); // range [-1,1]
366  etaLR[0] = -1.0; // left
367  etaLR[1] = 1.0; // right
368  NekDouble tmpLx, tmpLy, tmpRx, tmpRy; // tmp values for L/R
369  NekDouble distL2, distR2; // distance square
370 
371  StdRegions::StdExpansionSharedPtr bndXmap = bndGeom->GetXmap();
372  locCoord[0] = -2.0;
373  int cnt = 0;
374  bool isConverge = false;
375  while (cnt < iterMax)
376  {
377  tmpLx = bndXmap->PhysEvaluate(etaLR, pts[0]);
378  tmpLy = bndXmap->PhysEvaluate(etaLR, pts[1]);
379  tmpRx = bndXmap->PhysEvaluate(etaLR + 1, pts[0]);
380  tmpRy = bndXmap->PhysEvaluate(etaLR + 1, pts[1]);
381 
382  distL2 = (tmpLx - inGloCoord[0]) * (tmpLx - inGloCoord[0]) +
383  (tmpLy - inGloCoord[1]) * (tmpLy - inGloCoord[1]);
384  distR2 = (tmpRx - inGloCoord[0]) * (tmpRx - inGloCoord[0]) +
385  (tmpRy - inGloCoord[1]) * (tmpRy - inGloCoord[1]);
386 
387  if (distL2 >= distR2)
388  {
389  etaLR[0] = 0.5 * (etaLR[0] + etaLR[1]);
390  }
391  else
392  {
393  etaLR[1] = 0.5 * (etaLR[0] + etaLR[1]);
394  }
395 
396  if ((etaLR[1] - etaLR[0]) < iterTol)
397  {
398  locCoord[0] = 0.5 * (etaLR[0] + etaLR[1]);
399  gloCoord[0] = 0.5 * (tmpLx + tmpRx);
400  gloCoord[1] = 0.5 * (tmpLy + tmpRy);
401  dist = sqrt(0.5 * (distL2 + distR2));
402  isConverge = true;
403  break;
404  }
405 
406  ++cnt;
407  }
408 
409  // Warning if failed
410  if (cnt >= iterMax)
411  {
412  WARNINGL1(false, "Bisection iteration is not converged");
413  }
414 
415  return isConverge;
416 }

References tinysimd::sqrt(), and WARNINGL1.

Referenced by LocCoordForNearestPntOnBndElmt().

◆ PntToBndElmtPntDistance()

NekDouble Nektar::FieldUtils::ProcessBodyFittedVelocity::PntToBndElmtPntDistance ( const Array< OneD, Array< OneD, NekDouble >> &  pts,
const int  pId,
const Array< OneD, Array< OneD, NekDouble >> &  bndPts 
)
private

Compute the local coordinate for the nearest point on the given 2D boundary element to the input point.

Compute the point-to-point distance to find the estimated cloest element.

Parameters
inGloCoordGlobal coordinate for the input point.
bndGeomGeometry of the boundary element to search from.
ptsGlobal coordinate of the quadrature points in the boundary element.
locCoordLocal coordinate of the result.
gloCoordGlobal coordinate of the result.
distDistance from the input point to the boundary element.
iterTolIteration tolerence.
iterMaxMax iteration steps.
ptsGlobal coordinate of the quadrature points in the inner element.
pIdId of the inner point of interest in the current loop.
bndPtsGlobal coordinate of the quadrature points in the boundary element.

Definition at line 315 of file ProcessBodyFittedVelocity.cpp.

318 {
319  const int nCoordDim = pts.size();
320 
321  NekDouble dist = 9999, dist_tmp;
322 
323  for (int i = 0; i < bndPts[0].size(); ++i)
324  {
325  // Compute distance
326  dist_tmp = 0.0;
327  for (int j = 0; j < nCoordDim; ++j)
328  {
329  dist_tmp +=
330  (bndPts[j][i] - pts[j][pId]) * (bndPts[j][i] - pts[j][pId]);
331  }
332  dist_tmp = sqrt(dist_tmp);
333 
334  if (dist_tmp < dist)
335  {
336  dist = dist_tmp;
337  }
338  }
339 
340  return dist;
341 }

References tinysimd::sqrt().

Referenced by GenPntwiseBodyFittedCoordSys().

◆ ScaledCrosssProduct()

void Nektar::FieldUtils::ProcessBodyFittedVelocity::ScaledCrosssProduct ( const Array< OneD, NekDouble > &  vec1,
const Array< OneD, NekDouble > &  vec2,
Array< OneD, NekDouble > &  vec3 
)
private

Compute the normalized cross product for two 2D vectors. vec3 = vec1 x vec2.

Definition at line 472 of file ProcessBodyFittedVelocity.cpp.

475 {
476  vec3[0] = vec1[1] * vec2[2] - vec1[2] * vec2[1];
477  vec3[1] = vec1[2] * vec2[0] - vec1[0] * vec2[2];
478  vec3[2] = vec1[0] * vec2[1] - vec1[1] * vec2[0];
479 
480  NekDouble coef;
481  coef =
482  1.0 / sqrt(vec3[0] * vec3[0] + vec3[1] * vec3[1] + vec3[2] * vec3[2]);
483 
484  vec3[0] = vec3[0] * coef;
485  vec3[1] = vec3[1] * coef;
486  vec3[2] = vec3[2] * coef;
487 }

References tinysimd::sqrt().

Referenced by GenPntwiseBodyFittedCoordSys().

◆ v_GetModuleDescription()

virtual std::string Nektar::FieldUtils::ProcessBodyFittedVelocity::v_GetModuleDescription ( )
inlineoverrideprotectedvirtual

Reimplemented from Nektar::FieldUtils::ProcessBoundaryExtract.

Definition at line 72 of file ProcessBodyFittedVelocity.h.

73  {
74  return "Get velocity in the body-fitted coordinate system.";
75  }

◆ v_GetModuleName()

virtual std::string Nektar::FieldUtils::ProcessBodyFittedVelocity::v_GetModuleName ( )
inlineoverrideprotectedvirtual

Reimplemented from Nektar::FieldUtils::ProcessBoundaryExtract.

Definition at line 67 of file ProcessBodyFittedVelocity.h.

68  {
69  return "ProcessBodyFittedVelocity";
70  }

◆ v_Process()

void Nektar::FieldUtils::ProcessBodyFittedVelocity::v_Process ( po::variables_map &  vm)
overrideprotectedvirtual

Write mesh to output file.

Reimplemented from Nektar::FieldUtils::ProcessBoundaryExtract.

Definition at line 117 of file ProcessBodyFittedVelocity.cpp.

118 {
120 
121  // Get dim to store data
122  const int nFields = m_f->m_variables.size();
123  const int nCoordDim = m_f->m_exp[0]->GetCoordim(0);
124  const int nSpaceDim = nCoordDim + m_f->m_numHomogeneousDir;
125  const int nAddFields = nSpaceDim + 1; // distanceToWall, u_bfc, v_bfc, w_bfc
126 
127  // Tolerence setting
128  // To include more elmts for further check
129  const NekDouble distTol = m_config["distTol"].as<NekDouble>();
130  const NekDouble geoTol = 1.0e-12; // To check if two pnts are too close
131  const NekDouble dirTol = 1.0e-4; // To check if two unit vecs are parallel
132  const NekDouble iterTol = 1.0e-12; // To check if locCoord iter convergence
133 
134  const bool isCheckAngle = m_config["checkAngle"].as<bool>();
135  const bool isOutputBfc = m_config["bfcOut"].as<bool>();
136 
137  // Get the assist vector
138  vector<NekDouble> assistDir;
139  ASSERTL0(ParseUtils::GenerateVector(m_config["assistDir"].as<string>(),
140  assistDir),
141  "Failed to interpret assistance direction");
142 
143  Array<OneD, NekDouble> assistVec(3); // Save the assist vector
144  for (int i = 0; i < 3; ++i)
145  {
146  assistVec[i] = (assistDir.size() > i) ? assistDir[i] : 0.0;
147  }
148  if (nCoordDim == 2)
149  {
150  assistVec[0] = 0.0;
151  assistVec[1] = 0.0;
152  }
153 
154  NekDouble norm = sqrt(Vmath::Dot(3, assistVec, 1, assistVec, 1));
155  if (norm < geoTol)
156  {
157  ASSERTL0(false, "Error. The amplitude of assist vector is smaller than \
158  the geometry tolerence 1.0e-12.");
159  }
160  Vmath::Smul(3, 1.0 / norm, assistVec, 1, assistVec, 1);
161 
162  // Get the bnd id
163  // We only use the first one [0], check ProcessBoundaryExtract for more info
164  SpatialDomains::BoundaryConditions bcs(m_f->m_session,
165  m_f->m_exp[0]->GetGraph());
167  bcs.GetBoundaryRegions();
168  map<int, int> BndRegionMap;
169  int cnt = 0;
170  for (auto &breg_it : bregions)
171  {
172  BndRegionMap[breg_it.first] = cnt++;
173  }
174  int bnd = BndRegionMap[m_f->m_bndRegionsToWrite[0]];
175 
176  // Generate the distance array and three arrays for directional vectors
177  // bfcsDir[i][j][k]
178  // i - dir vec: 0-main tangential, 1-normal, (2-minor tangential)
179  // j - component: 0-x, 1-y, (2-z)
180  // k - point id
181  int npoints = m_f->m_exp[0]->GetNpoints();
182  Array<OneD, NekDouble> distance(npoints, 9999);
183  Array<OneD, Array<OneD, Array<OneD, NekDouble>>> bfcsDir(nSpaceDim);
184  for (int i = 0; i < nSpaceDim; ++i)
185  {
186  bfcsDir[i] = Array<OneD, Array<OneD, NekDouble>>(nSpaceDim);
187 
188  for (int j = 0; j < nSpaceDim; ++j)
189  {
190  bfcsDir[i][j] = Array<OneD, NekDouble>(npoints);
191  }
192  }
193 
194  // Key function. At each quadrature point inside the domian, compute the
195  // body-fitted coordinate system with respect to the input bnd id
196  GenPntwiseBodyFittedCoordSys(bnd, assistVec, distance, bfcsDir,
197  isCheckAngle, distTol, iterTol, dirTol,
198  geoTol);
199 
200  // Compute the velocity
201  Array<OneD, Array<OneD, NekDouble>> vel_car(nSpaceDim); // Cartesian
202  Array<OneD, Array<OneD, NekDouble>> vel_bfc(nSpaceDim); // body-fiitted
203  Array<OneD, NekDouble> vel_tmp(npoints);
204 
205  for (int i = 0; i < nSpaceDim; ++i)
206  {
207  vel_bfc[i] = Array<OneD, NekDouble>(npoints, 0.0);
208  }
209 
210  // Get the velocity in Cartesian coordinate system
211  GetVelAndConvertToCartSys(vel_car);
212 
213  // Project the velocity into the body-fitted coordinate system
214  for (int i = 0; i < nSpaceDim; ++i) // loop for bfc velocity
215  {
216  for (int j = 0; j < nSpaceDim; ++j)
217  {
218  Vmath::Vmul(npoints, vel_car[j], 1, bfcsDir[i][j], 1, vel_tmp, 1);
219  Vmath::Vadd(npoints, vel_tmp, 1, vel_bfc[i], 1, vel_bfc[i], 1);
220  }
221  }
222 
223  // Add var names
224  m_f->m_variables.push_back("distanceToWall");
225  m_f->m_variables.push_back("u_bfc");
226  m_f->m_variables.push_back("v_bfc");
227  if (nSpaceDim == 3)
228  {
229  m_f->m_variables.push_back("w_bfc");
230  }
231  else if (nSpaceDim == 1)
232  {
233  ASSERTL0(false, "Velocity in 1D case is already in the body fitted \
234  coordinate. The dimension should be 2 or 3.");
235  }
236 
237  // Add the new fields (distance + u,v,w_bfc)
238  // copy distance
239  m_f->m_exp.resize(nFields + nAddFields);
240 
241  m_f->m_exp[nFields] = m_f->AppendExpList(m_f->m_numHomogeneousDir);
242  Vmath::Vcopy(npoints, distance, 1, m_f->m_exp[nFields]->UpdatePhys(), 1);
243  m_f->m_exp[nFields]->FwdTransLocalElmt(distance,
244  m_f->m_exp[nFields]->UpdateCoeffs());
245 
246  // copy vel_bfc
247  for (int i = 1; i < nAddFields; ++i)
248  {
249  m_f->m_exp[nFields + i] = m_f->AppendExpList(m_f->m_numHomogeneousDir);
250  Vmath::Vcopy(npoints, vel_bfc[i - 1], 1,
251  m_f->m_exp[nFields + i]->UpdatePhys(), 1);
252  m_f->m_exp[nFields + i]->FwdTransLocalElmt(
253  vel_bfc[i - 1], m_f->m_exp[nFields + i]->UpdateCoeffs());
254  }
255 
256  // Output the the body-fitted coordinate into the file
257  // The filter will read the coordiante through file
258  // bfcsDir[i][j][k]
259  // i - dir vec: 0-main tangential, 1-normal, (2-minor tangential)
260  // j - component: 0-x, 1-y, (2-z)
261  // k - point id
262  if (isOutputBfc)
263  {
264  m_f->m_variables.push_back("bfc_dir0_x");
265  m_f->m_variables.push_back("bfc_dir0_y");
266  if (nSpaceDim == 3)
267  {
268  m_f->m_variables.push_back("bfc_dir0_z");
269  }
270  m_f->m_variables.push_back("bfc_dir1_x");
271  m_f->m_variables.push_back("bfc_dir1_y");
272  if (nSpaceDim == 3)
273  {
274  m_f->m_variables.push_back("bfc_dir1_z");
275 
276  m_f->m_variables.push_back("bfc_dir2_x");
277  m_f->m_variables.push_back("bfc_dir2_y");
278  m_f->m_variables.push_back("bfc_dir2_z");
279  }
280 
281  int nAddFields_coord = (nSpaceDim == 3) ? 9 : 4;
282  m_f->m_exp.resize(nFields + nAddFields + nAddFields_coord);
283 
284  cnt = 0;
285  for (int i = 0; i < nSpaceDim; ++i)
286  {
287  for (int j = 0; j < nSpaceDim; ++j)
288  {
289 
290  m_f->m_exp[nFields + nAddFields + cnt] =
291  m_f->AppendExpList(m_f->m_numHomogeneousDir);
292 
293  Vmath::Vcopy(
294  npoints, bfcsDir[i][j], 1,
295  m_f->m_exp[nFields + nAddFields + cnt]->UpdatePhys(), 1);
296  m_f->m_exp[nFields + nAddFields + cnt]->FwdTransLocalElmt(
297  bfcsDir[i][j],
298  m_f->m_exp[nFields + nAddFields + cnt]->UpdateCoeffs());
299 
300  ++cnt;
301  }
302  }
303  }
304 }
void GetVelAndConvertToCartSys(Array< OneD, Array< OneD, NekDouble >> &vel)
Get velocity and convert to Cartesian system, if it is still in transformed system....
void GenPntwiseBodyFittedCoordSys(const int targetBndId, const Array< OneD, NekDouble > assistVec, Array< OneD, NekDouble > &distance, Array< OneD, Array< OneD, Array< OneD, NekDouble >>> &bfcsDir, const bool isCheckAngle, const NekDouble distTol=1.0e-12, const NekDouble iterTol=1.0e-12, const NekDouble dirTol=1.0e-4, const NekDouble geoTol=1.0e-12)
At each quadrature point inside the domian, compute the body-fitted coordinate system with respect to...
virtual void v_Process(po::variables_map &vm) override
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:131
std::map< int, BoundaryRegionShPtr > BoundaryRegionCollection
Definition: Conditions.h:210
void Vmul(int n, const T *x, const int incx, const T *y, const int incy, T *z, const int incz)
Multiply vector z = x*y.
Definition: Vmath.cpp:209

References ASSERTL0, Vmath::Dot(), Nektar::ParseUtils::GenerateVector(), GenPntwiseBodyFittedCoordSys(), Nektar::SpatialDomains::BoundaryConditions::GetBoundaryRegions(), GetVelAndConvertToCartSys(), Nektar::FieldUtils::Module::m_config, Nektar::FieldUtils::Module::m_f, Vmath::Smul(), tinysimd::sqrt(), Nektar::FieldUtils::ProcessBoundaryExtract::v_Process(), Vmath::Vadd(), Vmath::Vcopy(), and Vmath::Vmul().

Member Data Documentation

◆ className

ModuleKey Nektar::FieldUtils::ProcessBodyFittedVelocity::className
static
Initial value:
=
ModuleKey(eProcessModule, "bodyFittedVelocity"),
"Convert the velocity components from the Cartesian coordinate into "
"the body-fitted coordinate.")
static std::shared_ptr< Module > create(FieldSharedPtr f)
Creates an instance of this class.
tKey RegisterCreatorFunction(tKey idKey, CreatorFunction classCreator, std::string pDesc="")
Register a class with the factory.
Definition: NekFactory.hpp:198
std::pair< ModuleType, std::string > ModuleKey
Definition: Module.h:317
ModuleFactory & GetModuleFactory()
Definition: Module.cpp:49

Definition at line 58 of file ProcessBodyFittedVelocity.h.