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 void v_Process (po::variables_map &vm) override
 
virtual std::string v_GetModuleName () override
 
virtual std::string v_GetModuleDescription () override
 
virtual ModulePriority v_GetModulePriority () override
 
- Protected Member Functions inherited from Nektar::FieldUtils::Module
 Module ()
 
virtual void v_Process (po::variables_map &vm)
 
virtual std::string v_GetModuleName ()
 
virtual std::string v_GetModuleDescription ()
 
virtual ModulePriority v_GetModulePriority ()
 

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
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:54
std::shared_ptr< StdExpansion > StdExpansionSharedPtr
double NekDouble
void Neg(int n, T *x, const int incx)
Negate x = -x.
Definition: Vmath.cpp:513
T Dot(int n, const T *w, const T *x)
dot (vector times vector): z = w*x
Definition: Vmath.cpp:1095
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:354
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:245
void Vcopy(int n, const T *x, const int incx, T *y, const int incy)
Definition: Vmath.cpp:1191
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:53

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
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
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 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...
void GetVelAndConvertToCartSys(Array< OneD, Array< OneD, NekDouble > > &vel)
Get velocity and convert to Cartesian system, if it is still in transformed system....
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:207

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.