54        "Export data in wall-normal direction from a single point on the " 
   60    f->m_writeBndFld = 
false; 
 
   64                     "The point to be projected onto the wall to get the \ 
   65                          sampling origin. default=[0.5,0,0]");
 
   68                     "The direction to project the point onto the wall to \ 
   69                          get the sampling origin. default=[0,1,0]");
 
   71        false, 
"1.0", 
"Distance to limit projection distance to find the \ 
   72                          desired sampling origin. defalut=1.0");
 
   74        false, 
"0.01", 
"Sampling distance along the wall normal at the \ 
   75                          sampling origin. default=0.1");
 
   77        false, 
"5", 
"Number of sampling points along the wall normal. \ 
   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");
 
  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;
 
  129    std::vector<NekDouble> xorig, searchDir;
 
  131             "Failed to interpret origin coordinates string");
 
  134        "Failed to interpret search direction string");
 
  137    const int nptsH         = 
m_config[
"nptsH"].as<
int>();
 
  141    for (
int i = 0; i < 3; ++i)
 
  143        orig[i]    = (xorig.size() >= (i + 1)) ? xorig[i] : 0.0;
 
  144        projDir[i] = (searchDir.size() >= (i + 1)) ? searchDir[i] : 0.0;
 
  154    if (
m_f->m_numHomogeneousDir == 1)
 
  156        int nPlanes    = 
m_f->m_exp[0]->GetHomogeneousBasis()->GetZ().size();
 
  158        if (orig[2] < 0.0 || orig[2] > lHom)
 
  165            NekDouble zTmp, zCur = 0.0, distTmp, distCur = 999.0;
 
  166            for (
int i = 0; i <= nPlanes; ++i)
 
  169                distTmp = fabs(orig[2] - zTmp);
 
  170                if (distTmp < distCur)
 
  186                                           m_f->m_exp[0]->GetGraph());
 
  189    map<int, int> BndRegionMap;
 
  191    for (
auto &breg_it : bregions)
 
  193        BndRegionMap[breg_it.first] = cnt++;
 
  195    int bnd = BndRegionMap[
m_f->m_bndRegionsToWrite[0]];
 
  199    for (
int i = 0; i < nfields; ++i)
 
  201        BndExp[i] = 
m_f->m_exp[i]->UpdateBndCondExpansion(bnd);
 
  210    bool isInside = 
false;
 
  213    const int nElmts = BndExp[0]->GetNumElmts();
 
  214    for (elmtid = 0; elmtid < nElmts; ++elmtid) 
 
  216        bndGeom  = BndExp[0]->GetExp(elmtid)->GetGeom();
 
  224    ASSERTL0(isInside, 
"Failed to find the sampling origin on the boundary.");
 
  228    const int npts                            = bndXmap->GetTotPoints();
 
  232    for (
int i = 0; i < nCoordDim; ++i)
 
  235        bndCoeffs[i] = bndGeom->GetCoeffs(i); 
 
  236        bndXmap->BwdTrans(bndCoeffs[i], pts[i]);
 
  237        orig[i] = bndXmap->PhysEvaluate(locCoord, pts[i]); 
 
  243    m_f->m_exp[0]->GetBoundaryNormals(bnd, normalsQ);
 
  248    int from_nPtsPerElmt = 1;
 
  249    for (
int i = 0; i < nBndLcoordDim; ++i)
 
  251        from_key[i] = BndExp[0]->GetExp(elmtid)->GetBasis(i)->GetPointsKey();
 
  252        from_nPtsPerElmt *= from_key[i].GetNumPoints();
 
  257    int refId = elmtid * from_nPtsPerElmt + 0; 
 
  260        normalsRef[i] = normalsQ[i][refId];
 
  275        cout << 
"------ wallNormalData module ------\n";
 
  276        cout << 
"Input point:\n";
 
  277        cout << 
"  - [Px,Py,Pz] = [" << xorig[0] << 
", " << xorig[1];
 
  278        if (xorig.size() >= 3)
 
  280            cout << 
", " << xorig[2] << 
"]\n";
 
  284            cout << 
", " << 0.0 << 
"]\n";
 
  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] << 
", " 
  292        cout << 
"Normals at the origin:\n";
 
  293        cout << 
"  - [nx,ny,nz] = [" << normals[0] << 
", " << normals[1] << 
", " 
  294             << normals[2] << 
"]\n";
 
  296            << 
"Ref normals (at quadrature points in the projected element):\n";
 
  297        for (
int i = 0; i < from_nPtsPerElmt; ++i)
 
  299            cout << 
"  - " << i << 
": [nx,ny,nz] = [" 
  300                 << -normalsQ[0][elmtid * from_nPtsPerElmt + i] << 
", " 
  301                 << -normalsQ[1][elmtid * from_nPtsPerElmt + i];
 
  304                cout << 
", " << -normalsQ[2][elmtid * from_nPtsPerElmt + i]
 
  318    if (delta > 0 && delta <= 0.95)
 
  327        for (
int i = 1; i < nptsH; ++i)
 
  329            tmp1 = 1.0 - i * tmp2; 
 
  330            h[i] = 1 - tanh(tmp1 * tmp4) * tmp5;
 
  334    else if (delta > 0.95)
 
  338        for (
int i = 1; i < nptsH; ++i)
 
  346        ASSERTL0(
false, 
"Input error. Delta needs to be greater than 0.0.");
 
  351    for (
int i = 0; i < totVars; ++i)
 
  358        for (
int j = 0; j < nptsH; ++j)
 
  360            ptsH[i][j] = orig[i] + h[j] * normals[i]; 
 
  388    tmp1 = 
Vmath::Dot(3, gloCoord, 1, projDir, 1); 
 
  389    Vmath::Smul(3, distToOrig - tmp1, projDir, 1, tmp2,
 
  391    Vmath::Vadd(3, gloCoord, 1, tmp2, 1, projGloCoord, 1); 
 
  407    const int nCoordDim = pts.size(); 
 
  408    const int npts      = pts[0].size();
 
  413    for (
int i = 0; i < npts; ++i)
 
  416        for (
int j = 0; j < nCoordDim; ++j)
 
  418            singlePnt[j] = pts[j][i];
 
  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);
 
  427        for (
int j = 0; j < nCoordDim; ++j)
 
  429            projPts[j][i] = singlePnt[j];
 
  449    const NekDouble npts = projPts[0].size();
 
  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];
 
  463    if ((fabs(vec1[0] + vec2[0]) + fabs(vec1[1] + vec2[1])) < paralTol)
 
  482    const NekDouble npts = projPts[0].size();
 
  485    const int nptsPolygon = 4 * nptsEdge - 4;
 
  487    for (
int i = 0; i < 3; ++i)
 
  491        for (
int j = 0; j < nptsEdge; ++j)
 
  493            ptsPolygon[i][j] = projPts[i][j];
 
  495        for (
int j = 0; j < nptsEdge - 2; ++j)
 
  497            ptsPolygon[i][nptsEdge + j] = projPts[i][(j + 2) * nptsEdge - 1];
 
  499        for (
int j = 0; j < nptsEdge; ++j)
 
  501            ptsPolygon[i][2 * nptsEdge - 2 + j] = projPts[i][npts - 1 - j];
 
  503        for (
int j = 0; j < nptsEdge - 2; ++j)
 
  505            ptsPolygon[i][3 * nptsEdge - 2 + j] =
 
  506                projPts[i][nptsEdge * (nptsEdge - j - 2)];
 
  511    NekDouble angleCos, angleAbs, angleSign, angleSum = 0.0;
 
  515    for (
int i = 0; i < nptsPolygon; ++i)
 
  518        id2 = (id1 == (nptsPolygon - 1)) ? 0 : (id1 + 1);
 
  520        for (
int j = 0; j < 3; ++j)
 
  522            vec1[j] = ptsPolygon[j][id1] - projGloCoord[j];
 
  523            vec2[j] = ptsPolygon[j][id2] - projGloCoord[j];
 
  531        if ((fabs(vec1[0] + vec2[0]) + fabs(vec1[1] + vec2[1]) +
 
  532             fabs(vec1[2] + vec2[2])) < paralTol)
 
  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];
 
  547            angleSign = 
Vmath::Dot(3, vec3, 1, projDir, 1) > 0.0 ? 1.0 : -1.0;
 
  555            else if (angleCos < -1.0)
 
  560            angleAbs = acos(angleCos);
 
  561            angleSum += angleSign * angleAbs;
 
  566    angleSum = fabs(angleSum);
 
  567    if (fabs(angleSum - 2.0 * M_PI) < angleTol)
 
  596    const NekDouble iterTol, 
const int iterMax)
 
  607    bool isConverge                           = 
false;
 
  608    while (cnt < iterMax)
 
  610        tmpL = bndXmap->PhysEvaluate(etaLR, pts[dirUse[0]]);
 
  611        tmpR = bndXmap->PhysEvaluate(etaLR + 1, pts[dirUse[0]]);
 
  613        if (fabs(gloCoord[dirUse[0]] - tmpL) >=
 
  614            fabs(gloCoord[dirUse[0]] - tmpR))
 
  616            etaLR[0] = 0.5 * (etaLR[0] + etaLR[1]);
 
  620            etaLR[1] = 0.5 * (etaLR[0] + etaLR[1]);
 
  623        if ((etaLR[1] - etaLR[0]) < iterTol)
 
  625            locCoord[0] = 0.5 * (etaLR[0] + etaLR[1]);
 
  636        WARNINGL1(
false, 
"Bisection iteration is not converged");
 
  655        bndGeom->GetMetricInfo()->GetJac(bndXmap->GetPointsKeys());
 
  658    scaledTol *= iterTol;
 
  661    const int dir1 = dirUse[0];
 
  662    const int dir2 = dirUse[1];
 
  670    bndXmap->PhysDeriv(pts[dir1], Dx1D1, Dx1D2);
 
  671    bndXmap->PhysDeriv(pts[dir2], Dx2D1, Dx2D2);
 
  678    NekDouble derx1_1, derx1_2, derx2_1, derx2_2, jac;
 
  681    bool isConverge = 
false;
 
  684    resid   = 
sqrt(F1 * F1 + F2 * F2);
 
  685    while (cnt++ < iterMax)
 
  687        x1map = bndXmap->PhysEvaluate(locCoord, pts[dir1]);
 
  688        x2map = bndXmap->PhysEvaluate(locCoord, pts[dir2]);
 
  690        F1 = gloCoord[dir1] - x1map;
 
  691        F2 = gloCoord[dir2] - x2map;
 
  693        if (F1 * F1 + F2 * F2 < scaledTol)
 
  695            resid      = 
sqrt(F1 * F1 + F2 * F2);
 
  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);
 
  706        jac = derx2_2 * derx1_1 - derx2_1 * derx1_2;
 
  710        locCoord[0] = locCoord[0] + (derx2_2 * (gloCoord[dir1] - x1map) -
 
  711                                     derx1_2 * (gloCoord[dir2] - x2map)) /
 
  714        locCoord[1] = locCoord[1] + (-derx2_1 * (gloCoord[dir1] - x1map) +
 
  715                                     derx1_1 * (gloCoord[dir2] - x2map)) /
 
  719        if (!(std::isfinite(locCoord[0]) && std::isfinite(locCoord[1])))
 
  722            std::ostringstream ss;
 
  723            ss << 
"nan or inf found in NewtonIterForLocCoordOnProjBndElmt in " 
  725               << bndGeom->GetGlobalID();
 
  729        if (fabs(locCoord[0]) > LcoordDiv || fabs(locCoord[1]) > LcoordDiv)
 
  737    bndXmap->LocCoordToLocCollapsed(locCoord, eta);
 
  739    if (bndGeom->ClampLocCoords(eta, 0.0))
 
  742        x1map = bndXmap->PhysEvaluate(eta, pts[dir1]);
 
  743        x2map = bndXmap->PhysEvaluate(eta, pts[dir2]);
 
  745        F1 = gloCoord[dir1] - x1map;
 
  746        F2 = gloCoord[dir2] - x2map;
 
  748        dist = 
sqrt(F1 * F1 + F2 * F2);
 
  759        bndXmap->LocCoordToLocCollapsed(locCoord, collCoords);
 
  762        if ((collCoords[0] >= -1.0 && collCoords[0] <= 1.0) &&
 
  763            (collCoords[1] >= -1.0 && collCoords[1] <= 1.0))
 
  765            std::ostringstream ss;
 
  767            ss << 
"Reached MaxIterations (" << iterMax
 
  768               << 
") in Newton iteration ";
 
  769            ss << 
"Init value (" << setprecision(4) << 0 << 
"," << 0 << 
"," 
  771            ss << 
"Fin  value (" << locCoord[0] << 
"," << locCoord[1] << 
"," 
  773            ss << 
"Resid = " << resid << 
" Tolerance = " << 
sqrt(scaledTol);
 
  805    const int npts                            = bndXmap->GetTotPoints();
 
  806    const int nCoordDim = 
m_f->m_exp[0]->GetCoordim(0); 
 
  813    for (
int i = 0; i < nCoordDim; ++i)
 
  817        bndCoeffs[i] = bndGeom->GetCoeffs(i); 
 
  818        bndXmap->BwdTrans(bndCoeffs[i], pts[i]);
 
  831    for (
int i = 1; i < nCoordDim; ++i)
 
  833        if (fabs(projDir[i]) > fabs(projDir[dirMaxId]))
 
  865        else if (dirMaxId == 1)
 
  885            bool isConverge, isDesired;
 
  888                bndGeom, projGloCoord, projPts, dirUse, locCoord, iterTol);
 
  891            tmp[0]   = bndXmap->PhysEvaluate(locCoord, pts[0]) - gloCoord[0];
 
  892            tmp[1]   = bndXmap->PhysEvaluate(locCoord, pts[1]) - gloCoord[1];
 
  895            isDesired = (projDist > 0.0) && (projDist < maxDist);
 
  897            return isConverge && isDesired;
 
  910            bool isConverge, isDesired;
 
  914                                               dirUse, locCoord, dist, iterTol);
 
  918                std::ostringstream ss;
 
  919                ss << 
"Collapsed locCoord out of range.\n" 
  920                   << 
"Newton iteration gives the distance: " << dist;
 
  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];
 
  930            isDesired = (projDist > 0.0) && (projDist < maxDist);
 
  932            return isConverge && isDesired;
 
  952    const int nCoordDim = 
m_f->m_exp[0]->GetCoordim(0); 
 
  956    int npts = bndXmap->GetTotPoints();
 
  959    for (
int i = 0; i < nCoordDim; ++i)
 
  962        bndCoeffs[i] = bndGeom->GetCoeffs(i); 
 
  963        bndXmap->BwdTrans(bndCoeffs[i], pts[i]);
 
  972        bndXmap->PhysDeriv(pts[0], DxD1);
 
  973        bndXmap->PhysDeriv(pts[1], DyD1);
 
  976        dxd1 = bndXmap->PhysEvaluate(locCoord, DxD1);
 
  977        dyd1 = bndXmap->PhysEvaluate(locCoord, DyD1);
 
  978        norm = 
sqrt(dxd1 * dxd1 + dyd1 * dyd1);
 
  980        normals[0] = dyd1 / norm;
 
  981        normals[1] = -dxd1 / norm;
 
  993        bndXmap->PhysDeriv(pts[0], DxD1, DxD2);
 
  994        bndXmap->PhysDeriv(pts[1], DyD1, DyD2);
 
  995        bndXmap->PhysDeriv(pts[2], DzD1, DzD2);
 
  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);
 
 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);
 
 1011        normals[0] = n1 / norm;
 
 1012        normals[1] = n2 / norm;
 
 1013        normals[2] = n3 / norm;
 
#define WARNINGL1(condition, msg)
 
#define ASSERTL0(condition, msg)
 
A class that contains algorithms for interpolation between pts fields, expansions and different meshe...
 
FIELD_UTILS_EXPORT void Interpolate(const T expInField, T &expOutField, NekDouble def_value=0., NekDouble tolerance=NekConstants::kFindDistanceMin)
Interpolate from an expansion to an expansion.
 
FieldSharedPtr m_f
Field object.
 
std::map< std::string, ConfigOption > m_config
List of configuration values.
 
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.
 
static ModuleKey className
 
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,...
 
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)
 
ProcessWallNormalData(FieldSharedPtr f)
 
~ProcessWallNormalData() override
 
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...
 
static std::shared_ptr< Module > create(FieldSharedPtr f)
Creates an instance of this class.
 
void GetNormals(SpatialDomains::GeometrySharedPtr bndGeom, const Array< OneD, const NekDouble > &locCoord, Array< OneD, NekDouble > &normals)
Get the normals for a given locCoord.
 
void v_Process(po::variables_map &vm) override
Write mesh to output file.
 
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.
 
tKey RegisterCreatorFunction(tKey idKey, CreatorFunction classCreator, std::string pDesc="")
Register a class with the factory.
 
static std::shared_ptr< DataType > AllocateSharedPtr(const Args &...args)
Allocate a shared pointer from the memory pool.
 
static bool GenerateVector(const std::string &str, std::vector< T > &out)
Takes a comma-separated string and converts it to entries in a vector.
 
const BoundaryRegionCollection & GetBoundaryRegions(void) const
 
std::shared_ptr< Field > FieldSharedPtr
 
std::pair< ModuleType, std::string > ModuleKey
 
ModuleFactory & GetModuleFactory()
 
static std::map< PtsInfo, int > NullPtsInfoMap
 
static const NekDouble kNekUnsetDouble
 
std::map< int, BoundaryRegionShPtr > BoundaryRegionCollection
 
std::shared_ptr< Geometry > GeometrySharedPtr
 
std::shared_ptr< StdExpansion > StdExpansionSharedPtr
 
void Neg(int n, T *x, const int incx)
Negate x = -x.
 
T Vsum(int n, const T *x, const int incx)
Subtract return sum(x)
 
T Dot(int n, const T *w, const T *x)
dot product
 
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.
 
void Smul(int n, const T alpha, const T *x, const int incx, T *y, const int incy)
Scalar multiply y = alpha*x.
 
scalarT< T > sqrt(scalarT< T > in)
 
Represents a command-line configuration option.