Nektar++
Public Member Functions | Static Public Member Functions | Static Public Attributes | Protected Member Functions | Private Member Functions | Private Attributes | List of all members
Nektar::FieldUtils::ProcessWallNormalData 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 <ProcessWallNormalData.h>

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

Public Member Functions

 ProcessWallNormalData (FieldSharedPtr f)
 
 ~ProcessWallNormalData () override
 
void GetNormals (SpatialDomains::GeometrySharedPtr bndGeom, const Array< OneD, const NekDouble > &locCoord, Array< OneD, NekDouble > &normals)
 Get the normals for a given locCoord. More...
 
- Public Member Functions inherited from Nektar::FieldUtils::ProcessBoundaryExtract
 ProcessBoundaryExtract (FieldSharedPtr f)
 
 ~ProcessBoundaryExtract () override
 
- 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 ()
 
std::vector< ModuleKeyGetModulePrerequisites ()
 
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

void v_Process (po::variables_map &vm) override
 Write mesh to output file. More...
 
std::string v_GetModuleName () override
 
std::string v_GetModuleDescription () override
 
- Protected Member Functions inherited from Nektar::FieldUtils::ProcessBoundaryExtract
void v_Process (po::variables_map &vm) override
 
std::string v_GetModuleName () override
 
std::string v_GetModuleDescription () override
 
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 ()
 
virtual std::vector< ModuleKeyv_GetModulePrerequisites ()
 

Private Member Functions

void ProjectPoint (const Array< OneD, const NekDouble > &gloCoord, const Array< OneD, const NekDouble > &projDir, const NekDouble distToOrig, Array< OneD, NekDouble > &projGloCoord)
 Project a single point along the given direction to a plane. More...
 
void ProjectVertices (const Array< OneD, const Array< OneD, NekDouble > > &pts, const Array< OneD, const NekDouble > &projDir, const NekDouble distToOrig, Array< OneD, Array< OneD, NekDouble > > &projPts)
 Project a single point along the given direction to a plane. More...
 
bool isInProjectedArea2D (const Array< OneD, const NekDouble > &projGloCoord, const Array< OneD, const Array< OneD, NekDouble > > &projPts, const NekDouble paralTol=1.0e-12)
 Determine if the projected point is inside the projected element. More...
 
bool isInProjectedArea3D (const Array< OneD, const NekDouble > &projGloCoord, const Array< OneD, const Array< OneD, NekDouble > > &projPts, const Array< OneD, const NekDouble > &projDir, const NekDouble paralTol=1.0e-12, const NekDouble angleTol=1.0e-6)
 
bool BisectionForLocCoordOnBndElmt (SpatialDomains::GeometrySharedPtr bndGeom, const Array< OneD, const NekDouble > &gloCoord, const Array< OneD, const Array< OneD, NekDouble > > &pts, const Array< OneD, const int > &dirUse, Array< OneD, NekDouble > &locCoord, const NekDouble iterTol=1.0e-8, const int iterMax=51)
 Use iteration to get the locCoord. This routine should be used after we have checked the projected point is inside the projected element. More...
 
bool NewtonIterForLocCoordOnBndElmt (SpatialDomains::GeometrySharedPtr bndGeom, const Array< OneD, const NekDouble > &gloCoord, const Array< OneD, const Array< OneD, NekDouble > > &pts, const Array< OneD, const int > &dirUse, Array< OneD, NekDouble > &locCoord, NekDouble &dist, const NekDouble iterTol=1.0e-8, const int iterMax=51)
 
bool BndElmtContainsPoint (SpatialDomains::GeometrySharedPtr bndGeom, const Array< OneD, const NekDouble > &gloCoord, const Array< OneD, const NekDouble > &projDir, Array< OneD, NekDouble > &locCoord, NekDouble &projDist, const NekDouble maxDist=1.0, const NekDouble iterTol=1.0e-8)
 Check if a point can be projected onto an oundary element in a given direction. If yes, give the local coordinates of the projected point. we have checked the projected point is inside the projected element. More...
 

Private Attributes

int m_spacedim
 

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 47 of file ProcessWallNormalData.h.

Constructor & Destructor Documentation

◆ ProcessWallNormalData()

Nektar::FieldUtils::ProcessWallNormalData::ProcessWallNormalData ( FieldSharedPtr  f)

Definition at line 57 of file ProcessWallNormalData.cpp.

59{
60 f->m_writeBndFld = false; // turned on in upstream ProcessBoundaryExtract
61
62 m_config["xorig"] =
63 ConfigOption(false, "0.5,0.0,0.0",
64 "The point to be projected onto the wall to get the \
65 sampling origin. default=[0.5,0,0]");
66 m_config["projDir"] =
67 ConfigOption(false, "0.0,1.0,0.0",
68 "The direction to project the point onto the wall to \
69 get the sampling origin. default=[0,1,0]");
70 m_config["maxDist"] = ConfigOption(
71 false, "1.0", "Distance to limit projection distance to find the \
72 desired sampling origin. defalut=1.0");
73 m_config["distH"] = ConfigOption(
74 false, "0.01", "Sampling distance along the wall normal at the \
75 sampling origin. default=0.1");
76 m_config["nptsH"] = ConfigOption(
77 false, "5", "Number of sampling points along the wall normal. \
78 default=5");
79 m_config["d"] = ConfigOption(
80 false, "0.1", "The parameter that controls the sampling points' \
81 distribution. d should be in the range (0,inf). d \
82 in (0,0.95] gives controled points; d in (0.95,inf) \
83 gives evenly spaced points");
84
85 // To allow some functions called somewhere else outside Process(),
86 // m_spacedim should be defined while it cannot be defined here in the
87 // constructor because f->m_exp[0]->GetCoordim(0) and
88 // f->m_graph->GetMeshDimension() has not been defeind yet
89 // *It is defeind in m_f->SetUpExp(vm), where vm is necessary.
90}
std::map< std::string, ConfigOption > m_config
List of configuration values.
Definition: Module.h:272

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

◆ ~ProcessWallNormalData()

Nektar::FieldUtils::ProcessWallNormalData::~ProcessWallNormalData ( )
override

Definition at line 92 of file ProcessWallNormalData.cpp.

93{
94}

Member Function Documentation

◆ BisectionForLocCoordOnBndElmt()

bool Nektar::FieldUtils::ProcessWallNormalData::BisectionForLocCoordOnBndElmt ( SpatialDomains::GeometrySharedPtr  bndGeom,
const Array< OneD, const NekDouble > &  gloCoord,
const Array< OneD, const Array< OneD, NekDouble > > &  pts,
const Array< OneD, const int > &  dirUse,
Array< OneD, NekDouble > &  locCoord,
const NekDouble  iterTol = 1.0e-8,
const int  iterMax = 51 
)
private

Use iteration to get the locCoord. This routine should be used after we have checked the projected point is inside the projected element.

Parameters
bndGeomGeometry to get the xmap.
gloCoordGlobal coordinate of the point. size=3.
ptsGlobal coordinate of the vertices of the elmt. size=2/3.
dieUseThe main direction(s) used to compute local coordinate
locCoordIteration results for local coordinate(s)
distReturned distance in physical space if the collapsed locCoord is out of range [-1,1].
iterTolTolerence for iteration.
iterMaxMaximum iteration steps
Returns
Converged (true) or not (false)

Definition at line 591 of file ProcessWallNormalData.cpp.

597{
598 // Initial settings
599 Array<OneD, NekDouble> etaLR(2); // range [-1,1]
600 etaLR[0] = -1.0; // left
601 etaLR[1] = 1.0; // right
602 NekDouble tmpL, tmpR; // tmp values for L/R
603
604 StdRegions::StdExpansionSharedPtr bndXmap = bndGeom->GetXmap();
605 locCoord[0] = -2.0;
606 int cnt = 0;
607 bool isConverge = false;
608 while (cnt < iterMax)
609 {
610 tmpL = bndXmap->PhysEvaluate(etaLR, pts[dirUse[0]]);
611 tmpR = bndXmap->PhysEvaluate(etaLR + 1, pts[dirUse[0]]);
612
613 if (fabs(gloCoord[dirUse[0]] - tmpL) >=
614 fabs(gloCoord[dirUse[0]] - tmpR))
615 {
616 etaLR[0] = 0.5 * (etaLR[0] + etaLR[1]);
617 }
618 else
619 {
620 etaLR[1] = 0.5 * (etaLR[0] + etaLR[1]);
621 }
622
623 if ((etaLR[1] - etaLR[0]) < iterTol)
624 {
625 locCoord[0] = 0.5 * (etaLR[0] + etaLR[1]);
626 isConverge = true;
627 break;
628 }
629
630 ++cnt;
631 }
632
633 // Warning if failed
634 if (cnt >= iterMax)
635 {
636 WARNINGL1(false, "Bisection iteration is not converged");
637 }
638
639 return isConverge;
640}
#define WARNINGL1(condition, msg)
Definition: ErrorUtil.hpp:243
std::shared_ptr< StdExpansion > StdExpansionSharedPtr
double NekDouble

References WARNINGL1.

Referenced by BndElmtContainsPoint().

◆ BndElmtContainsPoint()

bool Nektar::FieldUtils::ProcessWallNormalData::BndElmtContainsPoint ( SpatialDomains::GeometrySharedPtr  bndGeom,
const Array< OneD, const NekDouble > &  gloCoord,
const Array< OneD, const NekDouble > &  projDir,
Array< OneD, NekDouble > &  locCoord,
NekDouble projDist,
const NekDouble  maxDist = 1.0,
const NekDouble  iterTol = 1.0e-8 
)
private

Check if a point can be projected onto an oundary element in a given direction. If yes, give the local coordinates of the projected point. we have checked the projected point is inside the projected element.

Parameters
bndGeomPointer to the geometry of the boundary element.
gloCoordGlobal coordinate of the point. size=3.
projDirProjection direction, which is used as the reference direction in the 3D routine. size=3, norm=1.
locCoordIteration results for local coordinates (if inside).
projDistProjection distance betweem the point to the wall point.
maxDistDisntance to check if the wall point is desired.
iterTolTolerence for iteration.
Returns
Inside (true) or not (false)

Definition at line 796 of file ProcessWallNormalData.cpp.

802{
803 // Get variables
804 StdRegions::StdExpansionSharedPtr bndXmap = bndGeom->GetXmap();
805 const int npts = bndXmap->GetTotPoints();
806 const int nCoordDim = m_f->m_exp[0]->GetCoordim(0); // =2 for 2.5D cases
807
808 Array<OneD, Array<OneD, const NekDouble>> bndCoeffs(nCoordDim);
809 Array<OneD, Array<OneD, NekDouble>> pts(nCoordDim);
810 Array<OneD, Array<OneD, NekDouble>> projPts(nCoordDim);
811 Array<OneD, NekDouble> projGloCoord(3, 0.0);
812
813 for (int i = 0; i < nCoordDim; ++i)
814 {
815 pts[i] = Array<OneD, NekDouble>(npts);
816 projPts[i] = Array<OneD, NekDouble>(npts);
817 bndCoeffs[i] = bndGeom->GetCoeffs(i); // 0/1/2 for x/y/z
818 bndXmap->BwdTrans(bndCoeffs[i], pts[i]);
819 }
820
821 // Project the point and vertices of the element in the input direction
822 ProjectPoint(gloCoord, projDir, 0.0, projGloCoord);
823 ProjectVertices(pts, projDir, 0.0, projPts);
824
825 // Set the main direction(s) and the minor direction
826 // The gloCoord for minor direction will not be used for locCoord iteration
827 // dirUse[0] is the main dir for 2D/2.5D cases, dirUse[1]/[2] is the minor
828 // one dirUse[0] and dirUse[1] are the main dir for 3D cases, dirUse[2] is
829 // hte minor one
830 int dirMaxId = 0; // id to get the dir with largest projDir component
831 for (int i = 1; i < nCoordDim; ++i)
832 {
833 if (fabs(projDir[i]) > fabs(projDir[dirMaxId]))
834 {
835 dirMaxId = i;
836 }
837 }
838
839 Array<OneD, int> dirUse(3, 0);
840 if (nCoordDim == 2)
841 {
842 // 2D or 2.5D cases
843 if (dirMaxId == 0)
844 {
845 dirUse[0] = 1;
846 dirUse[1] = 0;
847 dirUse[2] = 2;
848 }
849 else
850 {
851 dirUse[0] = 0;
852 dirUse[1] = 1;
853 dirUse[2] = 2;
854 }
855 }
856 else
857 {
858 // 3D cases
859 if (dirMaxId == 0)
860 {
861 dirUse[0] = 1;
862 dirUse[1] = 2;
863 dirUse[2] = 0;
864 }
865 else if (dirMaxId == 1)
866 {
867 dirUse[0] = 2;
868 dirUse[1] = 0;
869 dirUse[2] = 1;
870 }
871 else
872 {
873 dirUse[0] = 0;
874 dirUse[1] = 1;
875 dirUse[2] = 2;
876 }
877 }
878
879 // Check if the projected point is in the projected elmt
880 // If yes, then compute the locCoord and check if desired point is found
881 if (nCoordDim == 2)
882 {
883 if (isInProjectedArea2D(projGloCoord, projPts, 1.0e-12))
884 {
885 bool isConverge, isDesired;
886
888 bndGeom, projGloCoord, projPts, dirUse, locCoord, iterTol);
889
890 Array<OneD, NekDouble> tmp(2, 0.0);
891 tmp[0] = bndXmap->PhysEvaluate(locCoord, pts[0]) - gloCoord[0];
892 tmp[1] = bndXmap->PhysEvaluate(locCoord, pts[1]) - gloCoord[1];
893 projDist = Vmath::Dot(2, tmp, 1, projDir, 1); // can be negative
894
895 isDesired = (projDist > 0.0) && (projDist < maxDist);
896
897 return isConverge && isDesired;
898 }
899 else
900 {
901 return false;
902 }
903 }
904 else
905 {
906 if (isInProjectedArea3D(projGloCoord, projPts, projDir, 1.0e-12,
907 1.0e-6))
908 {
909 NekDouble dist;
910 bool isConverge, isDesired;
911
912 isConverge =
913 NewtonIterForLocCoordOnBndElmt(bndGeom, projGloCoord, projPts,
914 dirUse, locCoord, dist, iterTol);
915
916 if (dist > iterTol)
917 {
918 std::ostringstream ss;
919 ss << "Collapsed locCoord out of range.\n"
920 << "Newton iteration gives the distance: " << dist;
921 WARNINGL1(false, ss.str());
922 }
923
924 Array<OneD, NekDouble> tmp(3, 0.0);
925 tmp[0] = bndXmap->PhysEvaluate(locCoord, pts[0]) - gloCoord[0];
926 tmp[1] = bndXmap->PhysEvaluate(locCoord, pts[1]) - gloCoord[1];
927 tmp[2] = bndXmap->PhysEvaluate(locCoord, pts[2]) - gloCoord[2];
928 projDist = Vmath::Dot(3, tmp, 1, projDir, 1); // can be negative
929
930 isDesired = (projDist > 0.0) && (projDist < maxDist);
931
932 return isConverge && isDesired;
933 }
934 else
935 {
936 return false;
937 }
938 }
939}
FieldSharedPtr m_f
Field object.
Definition: Module.h:239
void ProjectPoint(const Array< OneD, const NekDouble > &gloCoord, const Array< OneD, const NekDouble > &projDir, const NekDouble distToOrig, Array< OneD, NekDouble > &projGloCoord)
Project a single point along the given direction to a plane.
bool NewtonIterForLocCoordOnBndElmt(SpatialDomains::GeometrySharedPtr bndGeom, const Array< OneD, const NekDouble > &gloCoord, const Array< OneD, const Array< OneD, NekDouble > > &pts, const Array< OneD, const int > &dirUse, Array< OneD, NekDouble > &locCoord, NekDouble &dist, const NekDouble iterTol=1.0e-8, const int iterMax=51)
bool isInProjectedArea2D(const Array< OneD, const NekDouble > &projGloCoord, const Array< OneD, const Array< OneD, NekDouble > > &projPts, const NekDouble paralTol=1.0e-12)
Determine if the projected point is inside the projected element.
bool isInProjectedArea3D(const Array< OneD, const NekDouble > &projGloCoord, const Array< OneD, const Array< OneD, NekDouble > > &projPts, const Array< OneD, const NekDouble > &projDir, const NekDouble paralTol=1.0e-12, const NekDouble angleTol=1.0e-6)
bool BisectionForLocCoordOnBndElmt(SpatialDomains::GeometrySharedPtr bndGeom, const Array< OneD, const NekDouble > &gloCoord, const Array< OneD, const Array< OneD, NekDouble > > &pts, const Array< OneD, const int > &dirUse, Array< OneD, NekDouble > &locCoord, const NekDouble iterTol=1.0e-8, const int iterMax=51)
Use iteration to get the locCoord. This routine should be used after we have checked the projected po...
void ProjectVertices(const Array< OneD, const Array< OneD, NekDouble > > &pts, const Array< OneD, const NekDouble > &projDir, const NekDouble distToOrig, Array< OneD, Array< OneD, NekDouble > > &projPts)
Project a single point along the given direction to a plane.
T Dot(int n, const T *w, const T *x)
dot product
Definition: Vmath.hpp:761

References BisectionForLocCoordOnBndElmt(), Vmath::Dot(), isInProjectedArea2D(), isInProjectedArea3D(), Nektar::FieldUtils::Module::m_f, NewtonIterForLocCoordOnBndElmt(), ProjectPoint(), ProjectVertices(), and WARNINGL1.

Referenced by v_Process().

◆ create()

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

Creates an instance of this class.

Definition at line 51 of file ProcessWallNormalData.h.

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

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

◆ GetNormals()

void Nektar::FieldUtils::ProcessWallNormalData::GetNormals ( SpatialDomains::GeometrySharedPtr  bndGeom,
const Array< OneD, const NekDouble > &  locCoord,
Array< OneD, NekDouble > &  normals 
)

Get the normals for a given locCoord.

Parameters
bndGeomPointer to the geometry of the boundary element.
locCoordIteration results for local coordinates (if inside).
normalsWall normal as the result

Definition at line 947 of file ProcessWallNormalData.cpp.

951{
952 const int nCoordDim = m_f->m_exp[0]->GetCoordim(0); // =2 for 2.5D cases
953 StdRegions::StdExpansionSharedPtr bndXmap = bndGeom->GetXmap();
954 Array<OneD, Array<OneD, NekDouble>> pts(m_spacedim);
955 Array<OneD, Array<OneD, const NekDouble>> bndCoeffs(m_spacedim);
956 int npts = bndXmap->GetTotPoints();
957
958 // Get pts in the element
959 for (int i = 0; i < nCoordDim; ++i)
960 {
961 pts[i] = Array<OneD, NekDouble>(npts);
962 bndCoeffs[i] = bndGeom->GetCoeffs(i); // 0/1/2 for x/y/z
963 bndXmap->BwdTrans(bndCoeffs[i], pts[i]);
964 }
965
966 // Get the outward-pointing normals according to the given locCoord
967 if (nCoordDim == 2)
968 {
969 Array<OneD, NekDouble> DxD1(pts[0].size());
970 Array<OneD, NekDouble> DyD1(pts[0].size());
971
972 bndXmap->PhysDeriv(pts[0], DxD1);
973 bndXmap->PhysDeriv(pts[1], DyD1);
974
975 NekDouble dxd1, dyd1, norm;
976 dxd1 = bndXmap->PhysEvaluate(locCoord, DxD1);
977 dyd1 = bndXmap->PhysEvaluate(locCoord, DyD1);
978 norm = sqrt(dxd1 * dxd1 + dyd1 * dyd1);
979
980 normals[0] = dyd1 / norm;
981 normals[1] = -dxd1 / norm;
982 normals[2] = 0.0;
983 }
984 else
985 {
986 Array<OneD, NekDouble> DxD1(pts[0].size());
987 Array<OneD, NekDouble> DxD2(pts[0].size());
988 Array<OneD, NekDouble> DyD1(pts[0].size());
989 Array<OneD, NekDouble> DyD2(pts[0].size());
990 Array<OneD, NekDouble> DzD1(pts[0].size());
991 Array<OneD, NekDouble> DzD2(pts[0].size());
992
993 bndXmap->PhysDeriv(pts[0], DxD1, DxD2);
994 bndXmap->PhysDeriv(pts[1], DyD1, DyD2);
995 bndXmap->PhysDeriv(pts[2], DzD1, DzD2);
996
997 NekDouble dxd1, dyd1, dzd1, dxd2, dyd2, dzd2;
998 dxd1 = bndXmap->PhysEvaluate(locCoord, DxD1);
999 dxd2 = bndXmap->PhysEvaluate(locCoord, DxD2);
1000 dyd1 = bndXmap->PhysEvaluate(locCoord, DyD1);
1001 dyd2 = bndXmap->PhysEvaluate(locCoord, DyD2);
1002 dzd1 = bndXmap->PhysEvaluate(locCoord, DzD1);
1003 dzd2 = bndXmap->PhysEvaluate(locCoord, DzD2);
1004
1005 NekDouble n1, n2, n3, norm;
1006 n1 = dyd1 * dzd2 - dyd2 * dzd1;
1007 n2 = dzd1 * dxd2 - dzd2 * dxd1;
1008 n3 = dxd1 * dyd2 - dxd2 * dyd1;
1009 norm = sqrt(n1 * n1 + n2 * n2 + n3 * n3);
1010
1011 normals[0] = n1 / norm;
1012 normals[1] = n2 / norm;
1013 normals[2] = n3 / norm;
1014 }
1015}
scalarT< T > sqrt(scalarT< T > in)
Definition: scalar.hpp:294

References Nektar::FieldUtils::Module::m_f, m_spacedim, and tinysimd::sqrt().

Referenced by Nektar::FieldUtils::ProcessBodyFittedVelocity::GenPntwiseBodyFittedCoordSys(), and v_Process().

◆ isInProjectedArea2D()

bool Nektar::FieldUtils::ProcessWallNormalData::isInProjectedArea2D ( const Array< OneD, const NekDouble > &  projGloCoord,
const Array< OneD, const Array< OneD, NekDouble > > &  projPts,
const NekDouble  paralTol = 1.0e-12 
)
private

Determine if the projected point is inside the projected element.

Parameters
projGloCoordThe global coordinate of the projected single point.
projPtsThe global coordinate of the projected vertices,size=2/3
projDirProjection direction, which is used as the reference direction. size=3, norm=1.
paralTolTolerence to check if two vectors are parallel.
angleTolTolerence to check if the total angle is 2*pi.
Returns
Inside (true) or not (false)
Parameters
projGloCoordThe global coordinate of the projected single point.
projPtsThe global coordinate of the projected vertices,size=2/3
projDirProjection direction, which is used as the reference direction in the 3D routine. size=3, norm=1.
paralTolTolerence to check if two vectors are parallel.
angleTolTolerence to check if the total angle is 2*pi.
Returns
Inside (true) or not (false)

Definition at line 444 of file ProcessWallNormalData.cpp.

448{
449 const NekDouble npts = projPts[0].size();
450
451 Array<OneD, NekDouble> vec1(2, 0.0), vec2(2, 0.0);
452
453 vec1[0] = projPts[0][0] - projGloCoord[0];
454 vec1[1] = projPts[1][0] - projGloCoord[1];
455 vec2[0] = projPts[0][npts - 1] - projGloCoord[0];
456 vec2[1] = projPts[1][npts - 1] - projGloCoord[1];
457
458 Vmath::Smul(2, 1.0 / sqrt(Vmath::Dot(2, vec1, 1, vec1, 1)), vec1, 1, vec1,
459 1);
460 Vmath::Smul(2, 1.0 / sqrt(Vmath::Dot(2, vec2, 1, vec2, 1)), vec2, 1, vec2,
461 1);
462
463 if ((fabs(vec1[0] + vec2[0]) + fabs(vec1[1] + vec2[1])) < paralTol)
464 {
465 // On the line segement, true
466 return true;
467 }
468 else
469 {
470 return false;
471 }
472}
void Smul(int n, const T alpha, const T *x, const int incx, T *y, const int incy)
Scalar multiply y = alpha*x.
Definition: Vmath.hpp:100

References Vmath::Dot(), Vmath::Smul(), and tinysimd::sqrt().

Referenced by BndElmtContainsPoint().

◆ isInProjectedArea3D()

bool Nektar::FieldUtils::ProcessWallNormalData::isInProjectedArea3D ( const Array< OneD, const NekDouble > &  projGloCoord,
const Array< OneD, const Array< OneD, NekDouble > > &  projPts,
const Array< OneD, const NekDouble > &  projDir,
const NekDouble  paralTol = 1.0e-12,
const NekDouble  angleTol = 1.0e-6 
)
private

Definition at line 474 of file ProcessWallNormalData.cpp.

479{
480
481 // Generate a polygen (quad), re-order the points on the edge
482 const NekDouble npts = projPts[0].size();
483 const int nptsEdge =
484 sqrt(npts); // num of points on edge for geo representation
485 const int nptsPolygon = 4 * nptsEdge - 4;
486 Array<OneD, Array<OneD, NekDouble>> ptsPolygon(3);
487 for (int i = 0; i < 3; ++i)
488 {
489 ptsPolygon[i] = Array<OneD, NekDouble>(nptsPolygon);
490
491 for (int j = 0; j < nptsEdge; ++j)
492 {
493 ptsPolygon[i][j] = projPts[i][j];
494 }
495 for (int j = 0; j < nptsEdge - 2; ++j)
496 {
497 ptsPolygon[i][nptsEdge + j] = projPts[i][(j + 2) * nptsEdge - 1];
498 }
499 for (int j = 0; j < nptsEdge; ++j)
500 {
501 ptsPolygon[i][2 * nptsEdge - 2 + j] = projPts[i][npts - 1 - j];
502 }
503 for (int j = 0; j < nptsEdge - 2; ++j)
504 {
505 ptsPolygon[i][3 * nptsEdge - 2 + j] =
506 projPts[i][nptsEdge * (nptsEdge - j - 2)];
507 }
508 }
509
510 // Determine relation using angle method (sum=2*pi)
511 NekDouble angleCos, angleAbs, angleSign, angleSum = 0.0;
512 Array<OneD, NekDouble> vec1(3, 0.0), vec2(3, 0.0), vec3(3, 0.0);
513 int id1, id2;
514
515 for (int i = 0; i < nptsPolygon; ++i)
516 {
517 id1 = i;
518 id2 = (id1 == (nptsPolygon - 1)) ? 0 : (id1 + 1);
519
520 for (int j = 0; j < 3; ++j)
521 {
522 vec1[j] = ptsPolygon[j][id1] - projGloCoord[j];
523 vec2[j] = ptsPolygon[j][id2] - projGloCoord[j];
524 }
525
526 Vmath::Smul(3, 1.0 / sqrt(Vmath::Dot(3, vec1, 1, vec1, 1)), vec1, 1,
527 vec1, 1);
528 Vmath::Smul(3, 1.0 / sqrt(Vmath::Dot(3, vec2, 1, vec2, 1)), vec2, 1,
529 vec2, 1);
530
531 if ((fabs(vec1[0] + vec2[0]) + fabs(vec1[1] + vec2[1]) +
532 fabs(vec1[2] + vec2[2])) < paralTol)
533 {
534 // On the line segement, true
535 // This branch is used to aviod angle=pi but angleSign=-1 (not 1)
536 return true;
537 }
538 else
539 {
540 // Off the line segement, compute angle
541 // vec3 = vec1 x vec2, not scaled
542 vec3[0] = vec1[1] * vec2[2] - vec1[2] * vec2[1];
543 vec3[1] = vec1[2] * vec2[0] - vec1[0] * vec2[2];
544 vec3[2] = vec1[0] * vec2[1] - vec1[1] * vec2[0];
545
546 // Use the projDir as reference direction (positive)
547 angleSign = Vmath::Dot(3, vec3, 1, projDir, 1) > 0.0 ? 1.0 : -1.0;
548 angleCos = Vmath::Dot(3, vec1, 1, vec2, 1);
549
550 // Avoid error in using acos()
551 if (angleCos > 1.0)
552 {
553 angleCos = 1.0;
554 }
555 else if (angleCos < -1.0)
556 {
557 angleCos = -1.0;
558 }
559
560 angleAbs = acos(angleCos);
561 angleSum += angleSign * angleAbs;
562 }
563 }
564
565 // Check
566 angleSum = fabs(angleSum);
567 if (fabs(angleSum - 2.0 * M_PI) < angleTol)
568 {
569 return true;
570 }
571 else
572 {
573 return false;
574 }
575}

References Vmath::Dot(), Vmath::Smul(), and tinysimd::sqrt().

Referenced by BndElmtContainsPoint().

◆ NewtonIterForLocCoordOnBndElmt()

bool Nektar::FieldUtils::ProcessWallNormalData::NewtonIterForLocCoordOnBndElmt ( SpatialDomains::GeometrySharedPtr  bndGeom,
const Array< OneD, const NekDouble > &  gloCoord,
const Array< OneD, const Array< OneD, NekDouble > > &  pts,
const Array< OneD, const int > &  dirUse,
Array< OneD, NekDouble > &  locCoord,
NekDouble dist,
const NekDouble  iterTol = 1.0e-8,
const int  iterMax = 51 
)
private

Definition at line 642 of file ProcessWallNormalData.cpp.

648{
649
650 const NekDouble LcoordDiv = 15.0;
651
652 StdRegions::StdExpansionSharedPtr bndXmap = bndGeom->GetXmap();
653
654 Array<OneD, const NekDouble> Jac =
655 bndGeom->GetMetricInfo()->GetJac(bndXmap->GetPointsKeys());
656 NekDouble scaledTol =
657 Vmath::Vsum(Jac.size(), Jac, 1) / ((NekDouble)Jac.size());
658 scaledTol *= iterTol;
659
660 // Set the gloCoord used to compute locCoord
661 const int dir1 = dirUse[0];
662 const int dir2 = dirUse[1];
663
664 Array<OneD, NekDouble> Dx1D1(pts[dir1].size());
665 Array<OneD, NekDouble> Dx1D2(pts[dir1].size());
666 Array<OneD, NekDouble> Dx2D1(pts[dir1].size());
667 Array<OneD, NekDouble> Dx2D2(pts[dir1].size());
668
669 // Ideally this will be stored in m_geomfactors
670 bndXmap->PhysDeriv(pts[dir1], Dx1D1, Dx1D2);
671 bndXmap->PhysDeriv(pts[dir2], Dx2D1, Dx2D2);
672
673 // Initial the locCoord, in [-1,1]
674 locCoord[0] = 0.0;
675 locCoord[1] = 0.0;
676
677 NekDouble x1map, x2map, F1, F2;
678 NekDouble derx1_1, derx1_2, derx2_1, derx2_2, jac;
679 NekDouble resid;
680 int cnt = 0;
681 bool isConverge = false;
682
683 F1 = F2 = 2000; // Starting value of Function
684 resid = sqrt(F1 * F1 + F2 * F2);
685 while (cnt++ < iterMax)
686 {
687 x1map = bndXmap->PhysEvaluate(locCoord, pts[dir1]);
688 x2map = bndXmap->PhysEvaluate(locCoord, pts[dir2]);
689
690 F1 = gloCoord[dir1] - x1map;
691 F2 = gloCoord[dir2] - x2map;
692
693 if (F1 * F1 + F2 * F2 < scaledTol)
694 {
695 resid = sqrt(F1 * F1 + F2 * F2);
696 isConverge = true;
697 break;
698 }
699
700 // Interpolate derivative metric at locCoord
701 derx1_1 = bndXmap->PhysEvaluate(locCoord, Dx1D1);
702 derx1_2 = bndXmap->PhysEvaluate(locCoord, Dx1D2);
703 derx2_1 = bndXmap->PhysEvaluate(locCoord, Dx2D1);
704 derx2_2 = bndXmap->PhysEvaluate(locCoord, Dx2D2);
705
706 jac = derx2_2 * derx1_1 - derx2_1 * derx1_2;
707
708 // Use analytical inverse of derivitives which are
709 // also similar to those of metric factors.
710 locCoord[0] = locCoord[0] + (derx2_2 * (gloCoord[dir1] - x1map) -
711 derx1_2 * (gloCoord[dir2] - x2map)) /
712 jac;
713
714 locCoord[1] = locCoord[1] + (-derx2_1 * (gloCoord[dir1] - x1map) +
715 derx1_1 * (gloCoord[dir2] - x2map)) /
716 jac;
717
718 // locCoord have diverged so stop iteration
719 if (!(std::isfinite(locCoord[0]) && std::isfinite(locCoord[1])))
720 {
721 dist = 1e16;
722 std::ostringstream ss;
723 ss << "nan or inf found in NewtonIterForLocCoordOnProjBndElmt in "
724 "element "
725 << bndGeom->GetGlobalID();
726 WARNINGL1(false, ss.str());
727 return false;
728 }
729 if (fabs(locCoord[0]) > LcoordDiv || fabs(locCoord[1]) > LcoordDiv)
730 {
731 break;
732 }
733 }
734
735 // Check distance for collapsed coordinate
736 Array<OneD, NekDouble> eta(2);
737 bndXmap->LocCoordToLocCollapsed(locCoord, eta);
738
739 if (bndGeom->ClampLocCoords(eta, 0.0))
740 {
741 // calculate the global point corresponding to locCoord
742 x1map = bndXmap->PhysEvaluate(eta, pts[dir1]);
743 x2map = bndXmap->PhysEvaluate(eta, pts[dir2]);
744
745 F1 = gloCoord[dir1] - x1map;
746 F2 = gloCoord[dir2] - x2map;
747
748 dist = sqrt(F1 * F1 + F2 * F2);
749 }
750 else
751 {
752 dist = 0.0;
753 }
754
755 // Warning if failed
756 if (cnt >= iterMax)
757 {
758 Array<OneD, NekDouble> collCoords(2);
759 bndXmap->LocCoordToLocCollapsed(locCoord, collCoords);
760
761 // if coordinate is inside element dump error!
762 if ((collCoords[0] >= -1.0 && collCoords[0] <= 1.0) &&
763 (collCoords[1] >= -1.0 && collCoords[1] <= 1.0))
764 {
765 std::ostringstream ss;
766
767 ss << "Reached MaxIterations (" << iterMax
768 << ") in Newton iteration ";
769 ss << "Init value (" << setprecision(4) << 0 << "," << 0 << ","
770 << ") ";
771 ss << "Fin value (" << locCoord[0] << "," << locCoord[1] << ","
772 << ") ";
773 ss << "Resid = " << resid << " Tolerance = " << sqrt(scaledTol);
774
775 WARNINGL1(cnt < iterMax, ss.str());
776 }
777 }
778
779 return isConverge;
780}
T Vsum(int n, const T *x, const int incx)
Subtract return sum(x)
Definition: Vmath.hpp:608

References tinysimd::sqrt(), Vmath::Vsum(), and WARNINGL1.

Referenced by BndElmtContainsPoint().

◆ ProjectPoint()

void Nektar::FieldUtils::ProcessWallNormalData::ProjectPoint ( const Array< OneD, const NekDouble > &  gloCoord,
const Array< OneD, const NekDouble > &  projDir,
const NekDouble  distToOrig,
Array< OneD, NekDouble > &  projGloCoord 
)
private

Project a single point along the given direction to a plane.

Parameters
gloCoordGlobal coordinate of the point. size=3.
projDirProjection direction, which is also the normal vector of the target plane. size=3, norm=1.
distToOrigThe distance from the origin (0,0,0) to the target plane.
projGloCoordThe global coordinate of the projecion result.
gloCoordGlobal coordinate of the point. size=3.
projDirProjection direction, which is also the normal vector of the target plane. size=3, norm=1.
distToOrigThe distance from the origin (0,0,0) to the target plane
projGloCoordThe global coordinate of the projecion result.

Definition at line 380 of file ProcessWallNormalData.cpp.

384{
385 NekDouble tmp1;
386 Array<OneD, NekDouble> tmp2(3);
387
388 tmp1 = Vmath::Dot(3, gloCoord, 1, projDir, 1); // |xn| = x dot n
389 Vmath::Smul(3, distToOrig - tmp1, projDir, 1, tmp2,
390 1); // d_xn = (dist-|xn|) n
391 Vmath::Vadd(3, gloCoord, 1, tmp2, 1, projGloCoord, 1); // x' = x + d_xn
392}
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 Vmath::Dot(), Vmath::Smul(), and Vmath::Vadd().

Referenced by BndElmtContainsPoint().

◆ ProjectVertices()

void Nektar::FieldUtils::ProcessWallNormalData::ProjectVertices ( const Array< OneD, const Array< OneD, NekDouble > > &  pts,
const Array< OneD, const NekDouble > &  projDir,
const NekDouble  distToOrig,
Array< OneD, Array< OneD, NekDouble > > &  projPts 
)
private

Project a single point along the given direction to a plane.

Project the vertices of the elmt along the given direction to a plane.

Parameters
ptsGlobal coordinate of the vertices of the elmt. size=2/3.
projDirProjection direction, which is also the normal vector of the target plane. size=3, norm=1.
distToOrigThe distance from the origin (0,0,0) to the target plane.
projPtsThe global coordinate of the projecion result.

Definition at line 402 of file ProcessWallNormalData.cpp.

406{
407 const int nCoordDim = pts.size(); // 2 for 2.5D cases
408 const int npts = pts[0].size();
409
410 NekDouble tmp1;
411 Array<OneD, NekDouble> singlePnt(nCoordDim), tmp2(nCoordDim);
412
413 for (int i = 0; i < npts; ++i)
414 {
415 // Get a point
416 for (int j = 0; j < nCoordDim; ++j)
417 {
418 singlePnt[j] = pts[j][i];
419 }
420
421 // Projection
422 tmp1 = Vmath::Dot(nCoordDim, singlePnt, 1, projDir, 1);
423 Vmath::Smul(nCoordDim, distToOrig - tmp1, projDir, 1, tmp2, 1);
424 Vmath::Vadd(nCoordDim, singlePnt, 1, tmp2, 1, singlePnt, 1);
425
426 // Save to projPts
427 for (int j = 0; j < nCoordDim; ++j)
428 {
429 projPts[j][i] = singlePnt[j];
430 }
431 }
432}

References Vmath::Dot(), Vmath::Smul(), and Vmath::Vadd().

Referenced by BndElmtContainsPoint().

◆ v_GetModuleDescription()

std::string Nektar::FieldUtils::ProcessWallNormalData::v_GetModuleDescription ( )
inlineoverrideprotectedvirtual

Reimplemented from Nektar::FieldUtils::ProcessBoundaryExtract.

Definition at line 79 of file ProcessWallNormalData.h.

80 {
81 return "Get the wall-normal data at a given origin.";
82 }

◆ v_GetModuleName()

std::string Nektar::FieldUtils::ProcessWallNormalData::v_GetModuleName ( )
inlineoverrideprotectedvirtual

Reimplemented from Nektar::FieldUtils::ProcessBoundaryExtract.

Definition at line 74 of file ProcessWallNormalData.h.

75 {
76 return "ProcessWallNormalData";
77 }

◆ v_Process()

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

Write mesh to output file.

Reimplemented from Nektar::FieldUtils::ProcessBoundaryExtract.

Definition at line 117 of file ProcessWallNormalData.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 nBndLcoordDim = nCoordDim - 1;
125 m_spacedim = m_f->m_exp[0]->GetCoordim(0) + m_f->m_numHomogeneousDir;
126 const int totVars = m_spacedim + nfields;
127
128 // Initialize the sampling parameters
129 std::vector<NekDouble> xorig, searchDir;
130 ASSERTL0(ParseUtils::GenerateVector(m_config["xorig"].as<string>(), xorig),
131 "Failed to interpret origin coordinates string");
132 ASSERTL0(
133 ParseUtils::GenerateVector(m_config["projDir"].as<string>(), searchDir),
134 "Failed to interpret search direction string");
135 const NekDouble maxDist = m_config["maxDist"].as<NekDouble>();
136 const NekDouble distH = m_config["distH"].as<NekDouble>();
137 const int nptsH = m_config["nptsH"].as<int>();
138 const NekDouble delta = m_config["d"].as<NekDouble>();
139
140 Array<OneD, NekDouble> orig(3), projDir(3); // gloCoord of the origin
141 for (int i = 0; i < 3; ++i)
142 {
143 orig[i] = (xorig.size() >= (i + 1)) ? xorig[i] : 0.0;
144 projDir[i] = (searchDir.size() >= (i + 1)) ? searchDir[i] : 0.0;
145 }
146 if (nCoordDim == 2)
147 {
148 projDir[2] = 0.0;
149 }
150 Vmath::Smul(3, 1.0 / sqrt(Vmath::Dot(3, projDir, 1, projDir, 1)), projDir,
151 1, projDir, 1);
152
153 // Update z according to the closest plane in 2.5D cases
154 if (m_f->m_numHomogeneousDir == 1)
155 {
156 int nPlanes = m_f->m_exp[0]->GetHomogeneousBasis()->GetZ().size();
157 NekDouble lHom = m_f->m_exp[0]->GetHomoLen();
158 if (orig[2] < 0.0 || orig[2] > lHom)
159 {
160 orig[2] = 0.0;
161 }
162 else
163 {
164 NekDouble dZ = lHom / nPlanes;
165 NekDouble zTmp, zCur = 0.0, distTmp, distCur = 999.0;
166 for (int i = 0; i <= nPlanes; ++i)
167 {
168 zTmp = dZ * i;
169 distTmp = fabs(orig[2] - zTmp);
170 if (distTmp < distCur)
171 {
172 distCur = distTmp;
173 zCur = zTmp;
174 if (i == nPlanes)
175 {
176 zCur = 0.0;
177 }
178 }
179 }
180 orig[2] = zCur;
181 }
182 }
183
184 // Get the bnd id
185 SpatialDomains::BoundaryConditions bcs(m_f->m_session,
186 m_f->m_exp[0]->GetGraph());
188 bcs.GetBoundaryRegions();
189 map<int, int> BndRegionMap;
190 int cnt = 0;
191 for (auto &breg_it : bregions)
192 {
193 BndRegionMap[breg_it.first] = cnt++;
194 }
195 int bnd = BndRegionMap[m_f->m_bndRegionsToWrite[0]];
196
197 // Get expansion list for boundary
198 Array<OneD, MultiRegions::ExpListSharedPtr> BndExp(nfields);
199 for (int i = 0; i < nfields; ++i)
200 {
201 BndExp[i] = m_f->m_exp[i]->UpdateBndCondExpansion(bnd);
202 }
203
204 //-------------------------------------------------------------------------
205 // Find the element that contains the origin, and give the precise origin
207 Array<OneD, NekDouble> locCoord(nBndLcoordDim, -999.0);
208 NekDouble projDist;
209 int elmtid;
210 bool isInside = false;
211
212 // Search and get precise locCoord
213 const int nElmts = BndExp[0]->GetNumElmts();
214 for (elmtid = 0; elmtid < nElmts; ++elmtid) // nElmts
215 {
216 bndGeom = BndExp[0]->GetExp(elmtid)->GetGeom();
217 isInside = BndElmtContainsPoint(bndGeom, orig, projDir, locCoord,
218 projDist, maxDist);
219 if (isInside)
220 {
221 break;
222 }
223 }
224 ASSERTL0(isInside, "Failed to find the sampling origin on the boundary.");
225
226 // Then Update the precise sampling position
227 StdRegions::StdExpansionSharedPtr bndXmap = bndGeom->GetXmap();
228 const int npts = bndXmap->GetTotPoints();
229 Array<OneD, Array<OneD, NekDouble>> pts(nCoordDim);
230 Array<OneD, Array<OneD, const NekDouble>> bndCoeffs(nCoordDim);
231
232 for (int i = 0; i < nCoordDim; ++i)
233 {
234 pts[i] = Array<OneD, NekDouble>(npts);
235 bndCoeffs[i] = bndGeom->GetCoeffs(i); // 0/1/2 for x/y/z
236 bndXmap->BwdTrans(bndCoeffs[i], pts[i]);
237 orig[i] = bndXmap->PhysEvaluate(locCoord, pts[i]); // Update wall point
238 }
239
240 // Get outward-pointing normal vectors for all quadrature points on bnd
241 // Use these normals as diretion references
242 Array<OneD, Array<OneD, NekDouble>> normalsQ;
243 m_f->m_exp[0]->GetBoundaryNormals(bnd, normalsQ);
244
245 // Get the normals in the element
246 // Set point key to get point id
247 Array<OneD, LibUtilities::PointsKey> from_key(nBndLcoordDim);
248 int from_nPtsPerElmt = 1;
249 for (int i = 0; i < nBndLcoordDim; ++i)
250 {
251 from_key[i] = BndExp[0]->GetExp(elmtid)->GetBasis(i)->GetPointsKey();
252 from_nPtsPerElmt *= from_key[i].GetNumPoints();
253 }
254
255 // Get ref normal
256 Array<OneD, NekDouble> normalsRef(3, 0.0);
257 int refId = elmtid * from_nPtsPerElmt + 0; // the 1st normal in the bnd elmt
258 for (int i = 0; i < m_spacedim; ++i)
259 {
260 normalsRef[i] = normalsQ[i][refId];
261 }
262
263 // Get the precise normals and correct the direction to be inward
264 Array<OneD, NekDouble> normals(3, 0.0);
265 GetNormals(bndGeom, locCoord, normals);
266
267 if (Vmath::Dot(3, normals, normalsRef) > 0.0)
268 {
269 Vmath::Neg(3, normals, 1);
270 }
271
272 // Output the info if -v is set
273 if (m_f->m_verbose)
274 {
275 cout << "------ wallNormalData module ------\n";
276 cout << "Input point:\n";
277 cout << " - [Px,Py,Pz] = [" << xorig[0] << ", " << xorig[1];
278 if (xorig.size() >= 3)
279 {
280 cout << ", " << xorig[2] << "]\n";
281 }
282 else
283 {
284 cout << ", " << 0.0 << "]\n";
285 }
286 cout << "Projection direction:\n";
287 cout << " - [vx,vy,vz] = [" << projDir[0] << ", " << projDir[1] << ", "
288 << projDir[2] << "]\n";
289 cout << "Sampling origin on the wall:\n";
290 cout << " - [Ox,Oy,Oz] = [" << orig[0] << ", " << orig[1] << ", "
291 << orig[2] << "]\n";
292 cout << "Normals at the origin:\n";
293 cout << " - [nx,ny,nz] = [" << normals[0] << ", " << normals[1] << ", "
294 << normals[2] << "]\n";
295 cout
296 << "Ref normals (at quadrature points in the projected element):\n";
297 for (int i = 0; i < from_nPtsPerElmt; ++i)
298 {
299 cout << " - " << i << ": [nx,ny,nz] = ["
300 << -normalsQ[0][elmtid * from_nPtsPerElmt + i] << ", "
301 << -normalsQ[1][elmtid * from_nPtsPerElmt + i];
302 if (m_spacedim == 3)
303 {
304 cout << ", " << -normalsQ[2][elmtid * from_nPtsPerElmt + i]
305 << "]\n";
306 }
307 else
308 {
309 cout << "]\n";
310 }
311 }
312 cout << endl;
313 }
314
315 //-------------------------------------------------------------------------
316 // Set the depth of sampling array
317 Array<OneD, NekDouble> h(nptsH, 0.0);
318 if (delta > 0 && delta <= 0.95)
319 {
320 // Use expression in Agrawal's paper:
321 // h = 1-tanh((1-ksi)*atanh(sqrt(1-delta)))/sqrt(1-delta), ksi in [0,1]
322 NekDouble tmp1;
323 const NekDouble tmp2 = 1.0 / (static_cast<NekDouble>(nptsH) - 1.0);
324 const NekDouble tmp3 = sqrt(1.0 - delta);
325 const NekDouble tmp4 = atanh(tmp3);
326 const NekDouble tmp5 = 1.0 / tmp3;
327 for (int i = 1; i < nptsH; ++i)
328 {
329 tmp1 = 1.0 - i * tmp2; // tmp1 = 1-ksi
330 h[i] = 1 - tanh(tmp1 * tmp4) * tmp5;
331 h[i] *= distH; // physical distance in normal direction
332 }
333 }
334 else if (delta > 0.95)
335 {
336 // Evenly spaced array
337 const NekDouble tmp1 = 1.0 / (static_cast<NekDouble>(nptsH) - 1.0);
338 for (int i = 1; i < nptsH; ++i)
339 {
340 h[i] = i * tmp1;
341 h[i] *= distH; // physical distance in normal direction
342 }
343 }
344 else
345 {
346 ASSERTL0(false, "Input error. Delta needs to be greater than 0.0.");
347 }
348
349 // Set pts coordinates and interpoate the data
350 Array<OneD, Array<OneD, NekDouble>> ptsH(totVars);
351 for (int i = 0; i < totVars; ++i)
352 {
353 ptsH[i] = Array<OneD, NekDouble>(nptsH, 0.0);
354 }
355
356 for (int i = 0; i < m_spacedim; ++i)
357 {
358 for (int j = 0; j < nptsH; ++j)
359 {
360 ptsH[i][j] = orig[i] + h[j] * normals[i]; // x0+dist*nx
361 }
362 }
363
365 m_spacedim, m_f->m_variables, ptsH, LibUtilities::NullPtsInfoMap);
366
367 Interpolator<std::vector<MultiRegions::ExpListSharedPtr>> interp;
368 interp.Interpolate(m_f->m_exp, m_f->m_fieldPts,
370}
#define ASSERTL0(condition, msg)
Definition: ErrorUtil.hpp:208
void v_Process(po::variables_map &vm) override
bool BndElmtContainsPoint(SpatialDomains::GeometrySharedPtr bndGeom, const Array< OneD, const NekDouble > &gloCoord, const Array< OneD, const NekDouble > &projDir, Array< OneD, NekDouble > &locCoord, NekDouble &projDist, const NekDouble maxDist=1.0, const NekDouble iterTol=1.0e-8)
Check if a point can be projected onto an oundary element in a given direction. If yes,...
void GetNormals(SpatialDomains::GeometrySharedPtr bndGeom, const Array< OneD, const NekDouble > &locCoord, Array< OneD, NekDouble > &normals)
Get the normals for a given locCoord.
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
static std::map< PtsInfo, int > NullPtsInfoMap
Definition: PtsField.h:66
static const NekDouble kNekUnsetDouble
std::map< int, BoundaryRegionShPtr > BoundaryRegionCollection
Definition: Conditions.h:210
std::shared_ptr< Geometry > GeometrySharedPtr
Definition: Geometry.h:51
void Neg(int n, T *x, const int incx)
Negate x = -x.
Definition: Vmath.hpp:292

References Nektar::MemoryManager< DataType >::AllocateSharedPtr(), ASSERTL0, BndElmtContainsPoint(), Vmath::Dot(), Nektar::ParseUtils::GenerateVector(), Nektar::SpatialDomains::BoundaryConditions::GetBoundaryRegions(), GetNormals(), Nektar::FieldUtils::Interpolator< T >::Interpolate(), Nektar::NekConstants::kNekUnsetDouble, Nektar::FieldUtils::Module::m_config, Nektar::FieldUtils::Module::m_f, m_spacedim, Vmath::Neg(), Nektar::LibUtilities::NullPtsInfoMap, Vmath::Smul(), tinysimd::sqrt(), and Nektar::FieldUtils::ProcessBoundaryExtract::v_Process().

Member Data Documentation

◆ className

ModuleKey Nektar::FieldUtils::ProcessWallNormalData::className
static
Initial value:
=
ModuleKey(eProcessModule, "wallNormalData"),
"Export data in wall-normal direction from a single point on the "
"wall.")
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:197
std::pair< ModuleType, std::string > ModuleKey
Definition: Module.h:180
ModuleFactory & GetModuleFactory()
Definition: Module.cpp:47

Definition at line 55 of file ProcessWallNormalData.h.

◆ m_spacedim

int Nektar::FieldUtils::ProcessWallNormalData::m_spacedim
private

Definition at line 85 of file ProcessWallNormalData.h.

Referenced by GetNormals(), and v_Process().