120 const int nFields =
m_f->m_variables.size();
121 const int nCoordDim =
m_f->m_exp[0]->GetCoordim(0);
122 const int nSpaceDim = nCoordDim +
m_f->m_numHomogeneousDir;
123 const int nAddFields = nSpaceDim + 1;
132 const bool isCheckAngle =
m_config[
"checkAngle"].as<
bool>();
133 const bool isOutputBfc =
m_config[
"bfcOut"].as<
bool>();
136 vector<NekDouble> assistDir;
139 "Failed to interpret assistance direction");
142 for (
int i = 0; i < 3; ++i)
144 assistVec[i] = (assistDir.size() > i) ? assistDir[i] : 0.0;
155 ASSERTL0(
false,
"Error. The amplitude of assist vector is smaller than \
156 the geometry tolerence 1.0e-12.");
158 Vmath::Smul(3, 1.0 / norm, assistVec, 1, assistVec, 1);
163 m_f->m_exp[0]->GetGraph());
166 map<int, int> BndRegionMap;
168 for (
auto &breg_it : bregions)
170 BndRegionMap[breg_it.first] = cnt++;
172 int bnd = BndRegionMap[
m_f->m_bndRegionsToWrite[0]];
179 int npoints =
m_f->m_exp[0]->GetNpoints();
182 for (
int i = 0; i < nSpaceDim; ++i)
186 for (
int j = 0; j < nSpaceDim; ++j)
195 isCheckAngle, distTol, iterTol, dirTol,
203 for (
int i = 0; i < nSpaceDim; ++i)
212 for (
int i = 0; i < nSpaceDim; ++i)
214 for (
int j = 0; j < nSpaceDim; ++j)
216 Vmath::Vmul(npoints, vel_car[j], 1, bfcsDir[i][j], 1, vel_tmp, 1);
217 Vmath::Vadd(npoints, vel_tmp, 1, vel_bfc[i], 1, vel_bfc[i], 1);
222 m_f->m_variables.push_back(
"distanceToWall");
223 m_f->m_variables.push_back(
"u_bfc");
224 m_f->m_variables.push_back(
"v_bfc");
227 m_f->m_variables.push_back(
"w_bfc");
229 else if (nSpaceDim == 1)
231 ASSERTL0(
false,
"Velocity in 1D case is already in the body fitted \
232 coordinate. The dimension should be 2 or 3.");
237 m_f->m_exp.resize(nFields + nAddFields);
239 m_f->m_exp[nFields] =
m_f->AppendExpList(
m_f->m_numHomogeneousDir);
240 Vmath::Vcopy(npoints, distance, 1,
m_f->m_exp[nFields]->UpdatePhys(), 1);
241 m_f->m_exp[nFields]->FwdTransLocalElmt(distance,
242 m_f->m_exp[nFields]->UpdateCoeffs());
245 for (
int i = 1; i < nAddFields; ++i)
247 m_f->m_exp[nFields + i] =
m_f->AppendExpList(
m_f->m_numHomogeneousDir);
249 m_f->m_exp[nFields + i]->UpdatePhys(), 1);
250 m_f->m_exp[nFields + i]->FwdTransLocalElmt(
251 vel_bfc[i - 1],
m_f->m_exp[nFields + i]->UpdateCoeffs());
262 m_f->m_variables.push_back(
"bfc_dir0_x");
263 m_f->m_variables.push_back(
"bfc_dir0_y");
266 m_f->m_variables.push_back(
"bfc_dir0_z");
268 m_f->m_variables.push_back(
"bfc_dir1_x");
269 m_f->m_variables.push_back(
"bfc_dir1_y");
272 m_f->m_variables.push_back(
"bfc_dir1_z");
274 m_f->m_variables.push_back(
"bfc_dir2_x");
275 m_f->m_variables.push_back(
"bfc_dir2_y");
276 m_f->m_variables.push_back(
"bfc_dir2_z");
279 int nAddFields_coord = (nSpaceDim == 3) ? 9 : 4;
280 m_f->m_exp.resize(nFields + nAddFields + nAddFields_coord);
283 for (
int i = 0; i < nSpaceDim; ++i)
285 for (
int j = 0; j < nSpaceDim; ++j)
288 m_f->m_exp[nFields + nAddFields + cnt] =
289 m_f->AppendExpList(
m_f->m_numHomogeneousDir);
292 npoints, bfcsDir[i][j], 1,
293 m_f->m_exp[nFields + nAddFields + cnt]->UpdatePhys(), 1);
294 m_f->m_exp[nFields + nAddFields + cnt]->FwdTransLocalElmt(
296 m_f->m_exp[nFields + nAddFields + cnt]->UpdateCoeffs());
372 bool isConverge =
false;
373 while (cnt < iterMax)
375 tmpLx = bndXmap->PhysEvaluate(etaLR, pts[0]);
376 tmpLy = bndXmap->PhysEvaluate(etaLR, pts[1]);
377 tmpRx = bndXmap->PhysEvaluate(etaLR + 1, pts[0]);
378 tmpRy = bndXmap->PhysEvaluate(etaLR + 1, pts[1]);
380 distL2 = (tmpLx - inGloCoord[0]) * (tmpLx - inGloCoord[0]) +
381 (tmpLy - inGloCoord[1]) * (tmpLy - inGloCoord[1]);
382 distR2 = (tmpRx - inGloCoord[0]) * (tmpRx - inGloCoord[0]) +
383 (tmpRy - inGloCoord[1]) * (tmpRy - inGloCoord[1]);
385 if (distL2 >= distR2)
387 etaLR[0] = 0.5 * (etaLR[0] + etaLR[1]);
391 etaLR[1] = 0.5 * (etaLR[0] + etaLR[1]);
394 if ((etaLR[1] - etaLR[0]) < iterTol)
396 locCoord[0] = 0.5 * (etaLR[0] + etaLR[1]);
397 gloCoord[0] = 0.5 * (tmpLx + tmpRx);
398 gloCoord[1] = 0.5 * (tmpLy + tmpRy);
399 dist =
sqrt(0.5 * (distL2 + distR2));
410 WARNINGL1(
false,
"Bisection iteration is not converged");
512 const int nFields =
m_f->m_variables.size();
513 const int nCoordDim =
m_f->m_exp[0]->GetCoordim(0);
514 const int nSpaceDim = nCoordDim +
m_f->m_numHomogeneousDir;
515 const int nBndLcoordDim = nCoordDim - 1;
519 for (
int i = 0; i < nFields; ++i)
521 BndExp[i] =
m_f->m_exp[i]->UpdateBndCondExpansion(targetBndId);
524 const int nElmts =
m_f->m_exp[0]->GetNumElmts();
525 const int nBndElmts = BndExp[0]->GetNumElmts();
529 m_f->m_exp[0]->GetBoundaryNormals(targetBndId, normalQ);
540 vector<int> bndElmtIds;
541 int bndElmtId, bndElmtId_bak;
542 int phys_offset, bnd_phys_offset;
562 for (
int eId = 0; eId < nElmts; ++eId)
565 nPts =
m_f->m_exp[0]->GetExp(eId)->GetTotPoints();
567 for (
int i = 0; i < nCoordDim; ++i)
574 m_f->m_exp[0]->GetExp(eId)->GetCoords(pts[0], pts[1]);
576 else if (nCoordDim == 3)
578 m_f->m_exp[0]->GetExp(eId)->GetCoords(pts[0], pts[1], pts[2]);
582 phys_offset =
m_f->m_exp[0]->GetPhys_Offset(eId);
585 for (
int pId = 0; pId < nPts; ++pId)
599 for (
int beId = 0; beId < nBndElmts; ++beId)
602 bndGeom = BndExp[0]->GetExp(beId)->GetGeom();
604 nBndPts = bndXmap->GetTotPoints();
606 for (
int i = 0; i < nCoordDim; ++i)
610 bndXmap->BwdTrans(bndCoeffs[i], bndPts[i]);
616 if ((dist_tmp < (distance[phys_offset + pId] - geoTol)) &&
617 (dist_tmp < (distance[phys_offset + pId] - distTol)))
621 distance[phys_offset + pId] = dist_tmp;
623 bndElmtIds.push_back(beId);
625 else if ((dist_tmp < (distance[phys_offset + pId] + geoTol)) ||
626 (dist_tmp < (distance[phys_offset + pId] + distTol)))
631 bndElmtIds.push_back(beId);
643 for (
int i = 0; i < nCoordDim; ++i)
645 inGloCoord[i] = pts[i][pId];
650 distance[phys_offset + pId] = 9999;
656 for (
int i = 0; i < bndElmtIds.size(); ++i)
660 bndGeom = BndExp[0]->GetExp(bndElmtIds[i])->GetGeom();
663 inGloCoord, bndGeom, locCoord_tmp, gloCoord_tmp, dist_tmp,
668 WARNINGL1(
false,
"Bisection iteration is not converged!!!");
676 if (isCheckAngle && (dist_tmp > geoTol))
681 Vmath::Vadd(nCoordDim, inGloCoord, 1, normalChk, 1,
686 normalChk, 1, normalChk, 1);
689 wnd.
GetNormals(bndGeom, locCoord_tmp, normal);
692 bnd_phys_offset = BndExp[0]->GetPhys_Offset(bndElmtIds[i]);
693 for (
int j = 0; j < nCoordDim; ++j)
695 normalRef[j] = normalQ[j][bnd_phys_offset];
698 if (
Vmath::Dot(nCoordDim, normal, normalRef) > 0.0)
704 if (
Vmath::Dot(nCoordDim, normalChk, 1, normal, 1) <
709 if (dist_tmp < dist_bak)
711 bndElmtId_bak = bndElmtIds[i];
714 for (
int j = 0; j < nBndLcoordDim; ++j)
716 locCoord_bak[j] = locCoord_tmp[j];
719 for (
int j = 0; j < 3; ++j)
721 gloCoord_bak[j] = gloCoord_tmp[j];
733 if (dist_tmp < distance[phys_offset + pId])
735 bndElmtId = bndElmtIds[i];
736 distance[phys_offset + pId] = dist_tmp;
738 for (
int j = 0; j < nBndLcoordDim; ++j)
740 locCoord[j] = locCoord_tmp[j];
743 for (
int j = 0; j < 3; ++j)
745 gloCoord[j] = gloCoord_tmp[j];
753 if (bndElmtIds.size() == 0)
755 ASSERTL0(
false,
"No boundary element is found to be the \
756 possible nearest element. Please check.");
759 distance[phys_offset + pId] = dist_bak;
760 bndElmtId = bndElmtId_bak;
762 for (
int i = 0; i < nBndLcoordDim; ++i)
764 locCoord[i] = locCoord_bak[i];
767 for (
int i = 0; i < 3; ++i)
769 gloCoord[i] = gloCoord_bak[i];
773 "The boundary element is not found under given \
774 tolerence. Please check and reset the \
775 tolerence, or just turn off the angle check. \
776 If you would like to continue, the nearest \
777 boundary element is used.");
781 bndGeom = BndExp[0]->GetExp(bndElmtId)->GetGeom();
785 bnd_phys_offset = BndExp[0]->GetPhys_Offset(bndElmtId);
786 for (
int i = 0; i < nCoordDim; ++i)
788 normalRef[i] = normalQ[i][bnd_phys_offset];
792 if (
Vmath::Dot(nCoordDim, normal, normalRef) > 0.0)
810 for (
int i = 0; i < nSpaceDim; ++i)
812 bfcsDir[0][i][phys_offset + pId] = tangential1[i];
813 bfcsDir[1][i][phys_offset + pId] = normal[i];
819 for (
int i = 0; i < 3; ++i)
821 bfcsDir[2][i][phys_offset + pId] = tangential2[i];
838 int spacedim =
m_f->m_exp[0]->GetCoordim(0) +
m_f->m_numHomogeneousDir;
839 int nfields =
m_f->m_variables.size();
840 int npoints =
m_f->m_exp[0]->GetNpoints();
844 vector<string> vars =
m_f->m_exp[0]->GetSession()->GetVariables();
845 if (boost::iequals(vars[0],
"rho") && boost::iequals(vars[1],
"rhou"))
847 var_offset = spacedim + 2;
855 if (
m_f->m_fieldMetaDataMap.count(
"MappingCartesianVel"))
857 if (
m_f->m_fieldMetaDataMap[
"MappingCartesianVel"] ==
"False")
860 for (
int i = 0; i < spacedim; ++i)
863 if (
m_f->m_exp[0]->GetWaveSpace())
865 m_f->m_exp[0]->HomogeneousBwdTrans(
866 npoints,
m_f->m_exp[var_offset + i]->GetPhys(), vel[i]);
875 mapping->ContravarToCartesian(vel, vel);
877 if (
m_f->m_exp[0]->GetWaveSpace())
879 for (
int i = 0; i < spacedim; ++i)
881 m_f->m_exp[0]->HomogeneousFwdTrans(npoints, vel[i], vel[i]);
887 for (
int i = 0; i < spacedim; ++i)
897 for (
int i = 0; i < spacedim && i < nfields; ++i)
bool LocCoordForNearestPntOnBndElmt(const Array< OneD, const NekDouble > &inGloCoord, SpatialDomains::Geometry *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....
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....
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_2D(const Array< OneD, const NekDouble > &inGloCoord, SpatialDomains::Geometry *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...
const Array< OneD, const NekDouble > & GetCoeffs(const int i) const
Return the coefficients of the transformation Geometry::m_xmap in coordinate direction i.
StdRegions::StdExpansionSharedPtr GetXmap() const
Return the mapping object Geometry::m_xmap that represents the coordinate transformation from standar...