Skip to content

Commit

Permalink
Merge pull request #2327 from su2code/supersonic_profile
Browse files Browse the repository at this point in the history
Supersonic inlet profile
  • Loading branch information
pcarruscag authored Aug 10, 2024
2 parents 476acd3 + 0b905f4 commit 1843a75
Show file tree
Hide file tree
Showing 15 changed files with 167 additions and 329 deletions.
15 changes: 7 additions & 8 deletions SU2_CFD/include/solvers/CFVMFlowSolverBase.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -1099,22 +1099,21 @@ class CFVMFlowSolverBase : public CSolver {
/*!
* \brief Store of a set of provided inlet profile values at a vertex.
* \param[in] val_inlet - vector containing the inlet values for the current vertex.
* \param[in] iMarker - Surface marker where the coefficient is computed.
* \param[in] iMarker - Index of the surface marker.
* \param[in] iVertex - Vertex of the marker <i>iMarker</i> where the inlet is being set.
*/
void SetInletAtVertex(const su2double* val_inlet, unsigned short iMarker, unsigned long iVertex) final;

/*!
* \brief Get the set of value imposed at an inlet.
* \param[in] val_inlet - vector returning the inlet values for the current vertex.
* \param[in] val_inlet_point - Node index where the inlet is being set.
* \param[in] val_kind_marker - Enumerated type for the particular inlet type.
* \brief Get the set of values imposed at an inlet.
* \param[in] iMarker - Index of the surface marker.
* \param[in] iVertex - Vertex of the marker <i>iMarker</i> where the inlet is being set.
* \param[in] geometry - Geometrical definition of the problem.
* \param config - Definition of the particular problem.
* \param[in,out] val_inlet - vector returning the inlet values for the current vertex.
* \return Value of the face area at the vertex.
*/
su2double GetInletAtVertex(su2double* val_inlet, unsigned long val_inlet_point, unsigned short val_kind_marker,
string val_marker, const CGeometry* geometry, const CConfig* config) const final;
su2double GetInletAtVertex(unsigned short iMarker, unsigned long iVertex,
const CGeometry* geometry, su2double* val_inlet) const final;

/*!
* \author T. Kattmann
Expand Down
79 changes: 27 additions & 52 deletions SU2_CFD/include/solvers/CFVMFlowSolverBase.inl
Original file line number Diff line number Diff line change
Expand Up @@ -722,73 +722,48 @@ void CFVMFlowSolverBase<V, R>::SetInletAtVertex(const su2double* val_inlet, unsi
}

template <class V, ENUM_REGIME R>
su2double CFVMFlowSolverBase<V, R>::GetInletAtVertex(su2double* val_inlet, unsigned long val_inlet_point,
unsigned short val_kind_marker, string val_marker,
const CGeometry* geometry, const CConfig* config) const {
/*--- Local variables ---*/

unsigned short iMarker, iDim;
unsigned long iPoint, iVertex;
su2double Area = 0.0;
su2double Normal[3] = {0.0, 0.0, 0.0};

/*--- Alias positions within inlet file for readability ---*/

unsigned short T_position = nDim;
unsigned short P_position = nDim + 1;
unsigned short FlowDir_position = nDim + 2;

if (val_kind_marker == INLET_FLOW) {
for (iMarker = 0; iMarker < config->GetnMarker_All(); iMarker++) {
if ((config->GetMarker_All_KindBC(iMarker) == INLET_FLOW) &&
(config->GetMarker_All_TagBound(iMarker) == val_marker)) {
for (iVertex = 0; iVertex < nVertex[iMarker]; iVertex++) {
iPoint = geometry->vertex[iMarker][iVertex]->GetNode();

if (iPoint == val_inlet_point) {
/*-- Compute boundary face area for this vertex. ---*/

geometry->vertex[iMarker][iVertex]->GetNormal(Normal);
Area = GeometryToolbox::Norm(nDim, Normal);

/*--- Access and store the inlet variables for this vertex. ---*/

val_inlet[T_position] = Inlet_Ttotal[iMarker][iVertex];
val_inlet[P_position] = Inlet_Ptotal[iMarker][iVertex];
for (iDim = 0; iDim < nDim; iDim++) {
val_inlet[FlowDir_position + iDim] = Inlet_FlowDir[iMarker][iVertex][iDim];
}

/*--- Exit once we find the point. ---*/

return Area;
}
}
}
}
su2double CFVMFlowSolverBase<V, R>::GetInletAtVertex(unsigned short iMarker, unsigned long iVertex,
const CGeometry* geometry, su2double* val_inlet) const {
const auto T_position = nDim;
const auto P_position = nDim + 1;
const auto FlowDir_position = nDim + 2;
val_inlet[T_position] = Inlet_Ttotal[iMarker][iVertex];
val_inlet[P_position] = Inlet_Ptotal[iMarker][iVertex];
for (unsigned short iDim = 0; iDim < nDim; iDim++) {
val_inlet[FlowDir_position + iDim] = Inlet_FlowDir[iMarker][iVertex][iDim];
}

/*--- If we don't find a match, then the child point is not on the
current inlet boundary marker. Return zero area so this point does
not contribute to the restriction operator and continue. ---*/
/*--- Compute boundary face area for this vertex. ---*/

return Area;
su2double Normal[MAXNDIM] = {0.0};
geometry->vertex[iMarker][iVertex]->GetNormal(Normal);
return GeometryToolbox::Norm(nDim, Normal);
}

template <class V, ENUM_REGIME R>
void CFVMFlowSolverBase<V, R>::SetUniformInlet(const CConfig* config, unsigned short iMarker) {
if (config->GetMarker_All_KindBC(iMarker) == INLET_FLOW) {
string Marker_Tag = config->GetMarker_All_TagBound(iMarker);
su2double p_total = config->GetInletPtotal(Marker_Tag);
su2double t_total = config->GetInletTtotal(Marker_Tag);
auto flow_dir = config->GetInletFlowDir(Marker_Tag);
const string Marker_Tag = config->GetMarker_All_TagBound(iMarker);
const su2double p_total = config->GetInletPtotal(Marker_Tag);
const su2double t_total = config->GetInletTtotal(Marker_Tag);
const su2double* flow_dir = config->GetInletFlowDir(Marker_Tag);

for (unsigned long iVertex = 0; iVertex < nVertex[iMarker]; iVertex++) {
Inlet_Ttotal[iMarker][iVertex] = t_total;
Inlet_Ptotal[iMarker][iVertex] = p_total;
for (unsigned short iDim = 0; iDim < nDim; iDim++) Inlet_FlowDir[iMarker][iVertex][iDim] = flow_dir[iDim];
}
} else if (config->GetMarker_All_KindBC(iMarker) == SUPERSONIC_INLET) {
const string Marker_Tag = config->GetMarker_All_TagBound(iMarker);
const su2double p = config->GetInlet_Pressure(Marker_Tag);
const su2double t = config->GetInlet_Temperature(Marker_Tag);
const su2double* vel = config->GetInlet_Velocity(Marker_Tag);

for (unsigned long iVertex = 0; iVertex < nVertex[iMarker]; iVertex++) {
Inlet_Ttotal[iMarker][iVertex] = t;
Inlet_Ptotal[iMarker][iVertex] = p;
for (unsigned short iDim = 0; iDim < nDim; iDim++) Inlet_FlowDir[iMarker][iVertex][iDim] = vel[iDim];
}
} else {
/*--- For now, non-inlets just get set to zero. In the future, we
can do more customization for other boundary types here. ---*/
Expand Down
21 changes: 8 additions & 13 deletions SU2_CFD/include/solvers/CSolver.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -2895,7 +2895,7 @@ class CSolver {
* \param[in] config - Definition of the particular problem.
* \param[in] iMarker - Surface marker where the coefficient is computed.
*/
inline virtual void SetUniformInlet(const CConfig* config, unsigned short iMarker) {};
inline virtual void SetUniformInlet(const CConfig* config, unsigned short iMarker) {}

/*!
* \brief A virtual member
Expand All @@ -2905,23 +2905,18 @@ class CSolver {
*/
inline virtual void SetInletAtVertex(const su2double *val_inlet,
unsigned short iMarker,
unsigned long iVertex) { };
unsigned long iVertex) { }

/*!
* \brief A virtual member
* \param[in] val_inlet - vector returning the inlet values for the current vertex.
* \param[in] val_inlet_point - Node index where the inlet is being set.
* \param[in] val_kind_marker - Enumerated type for the particular inlet type.
* \brief Get the set of values imposed at an inlet.
* \param[in] iMarker - Index of the surface marker.
* \param[in] iVertex - Vertex of the marker <i>iMarker</i> where the inlet is being set.
* \param[in] geometry - Geometrical definition of the problem.
* \param config - Definition of the particular problem.
* \param[in,out] val_inlet - vector returning the inlet values for the current vertex.
* \return Value of the face area at the vertex.
*/
inline virtual su2double GetInletAtVertex(su2double *val_inlet,
unsigned long val_inlet_point,
unsigned short val_kind_marker,
string val_marker,
const CGeometry *geometry,
const CConfig *config) const { return 0; }
inline virtual su2double GetInletAtVertex(unsigned short iMarker, unsigned long iVertex,
const CGeometry* geometry, su2double* val_inlet) const { return 0; }

/*!
* \brief Update the multi-grid structure for the customized boundary conditions.
Expand Down
13 changes: 6 additions & 7 deletions SU2_CFD/include/solvers/CSpeciesSolver.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -113,16 +113,15 @@ class CSpeciesSolver : public CScalarSolver<CSpeciesVariable> {
void SetInletAtVertex(const su2double* val_inlet, unsigned short iMarker, unsigned long iVertex) override;

/*!
* \brief Get the set of value imposed at an inlet.
* \param[in] val_inlet - vector returning the inlet values for the current vertex.
* \param[in] val_inlet_point - Node index where the inlet is being set.
* \param[in] val_kind_marker - Enumerated type for the particular inlet type.
* \brief Get the set of values imposed at an inlet.
* \param[in] iMarker - Index of the surface marker.
* \param[in] iVertex - Vertex of the marker <i>iMarker</i> where the inlet is being set.
* \param[in] geometry - Geometrical definition of the problem.
* \param config - Definition of the particular problem.
* \param[in,out] val_inlet - vector returning the inlet values for the current vertex.
* \return Value of the face area at the vertex.
*/
su2double GetInletAtVertex(su2double* val_inlet, unsigned long val_inlet_point, unsigned short val_kind_marker,
string val_marker, const CGeometry* geometry, const CConfig* config) const override;
su2double GetInletAtVertex(unsigned short iMarker, unsigned long iVertex,
const CGeometry* geometry, su2double* val_inlet) const override;

/*!
* \brief Set a uniform inlet profile
Expand Down
17 changes: 6 additions & 11 deletions SU2_CFD/include/solvers/CTurbSASolver.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -345,20 +345,15 @@ class CTurbSASolver final : public CTurbSolver {
unsigned long iVertex) override;

/*!
* \brief Get the set of value imposed at an inlet.
* \param[in] val_inlet - vector returning the inlet values for the current vertex.
* \param[in] val_inlet_point - Node index where the inlet is being set.
* \param[in] val_kind_marker - Enumerated type for the particular inlet type.
* \brief Get the set of values imposed at an inlet.
* \param[in] iMarker - Index of the surface marker.
* \param[in] iVertex - Vertex of the marker <i>iMarker</i> where the inlet is being set.
* \param[in] geometry - Geometrical definition of the problem.
* \param config - Definition of the particular problem.
* \param[in,out] val_inlet - vector returning the inlet values for the current vertex.
* \return Value of the face area at the vertex.
*/
su2double GetInletAtVertex(su2double *val_inlet,
unsigned long val_inlet_point,
unsigned short val_kind_marker,
string val_marker,
const CGeometry *geometry,
const CConfig *config) const override;
su2double GetInletAtVertex(unsigned short iMarker, unsigned long iVertex,
const CGeometry* geometry, su2double* val_inlet) const override;

/*!
* \brief Set a uniform inlet profile
Expand Down
17 changes: 6 additions & 11 deletions SU2_CFD/include/solvers/CTurbSSTSolver.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -269,20 +269,15 @@ class CTurbSSTSolver final : public CTurbSolver {
unsigned long iVertex) override;

/*!
* \brief Get the set of value imposed at an inlet.
* \param[in] val_inlet - vector returning the inlet values for the current vertex.
* \param[in] val_inlet_point - Node index where the inlet is being set.
* \param[in] val_kind_marker - Enumerated type for the particular inlet type.
* \brief Get the set of values imposed at an inlet.
* \param[in] iMarker - Index of the surface marker.
* \param[in] iVertex - Vertex of the marker <i>iMarker</i> where the inlet is being set.
* \param[in] geometry - Geometrical definition of the problem.
* \param config - Definition of the particular problem.
* \param[in,out] val_inlet - vector returning the inlet values for the current vertex.
* \return Value of the face area at the vertex.
*/
su2double GetInletAtVertex(su2double *val_inlet,
unsigned long val_inlet_point,
unsigned short val_kind_marker,
string val_marker,
const CGeometry *geometry,
const CConfig *config) const override;
su2double GetInletAtVertex(unsigned short iMarker, unsigned long iVertex,
const CGeometry* geometry, su2double* val_inlet) const override;

/*!
* \brief Set a uniform inlet profile
Expand Down
28 changes: 14 additions & 14 deletions SU2_CFD/src/drivers/CDriver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1052,27 +1052,27 @@ void CDriver::PreprocessInlet(CSolver ***solver, CGeometry **geometry, CConfig *
/*--- Use LoadInletProfile() routines for the particular solver. ---*/

if (rank == MASTER_NODE) {
cout << endl;
cout << "Reading inlet profile from file: ";
cout << config->GetInlet_FileName() << endl;
cout << "\nReading inlet profile from file: " << config->GetInlet_FileName() << endl;
}

if (solver[MESH_0][FLOW_SOL]) {
solver[MESH_0][FLOW_SOL]->LoadInletProfile(geometry, solver, config, val_iter, FLOW_SOL, INLET_FLOW);
}
if (solver[MESH_0][TURB_SOL]) {
solver[MESH_0][TURB_SOL]->LoadInletProfile(geometry, solver, config, val_iter, TURB_SOL, INLET_FLOW);
}
if (solver[MESH_0][SPECIES_SOL]) {
solver[MESH_0][SPECIES_SOL]->LoadInletProfile(geometry, solver, config, val_iter, SPECIES_SOL, INLET_FLOW);
for (const auto marker_type : {INLET_FLOW, SUPERSONIC_INLET}) {
if (solver[MESH_0][FLOW_SOL]) {
solver[MESH_0][FLOW_SOL]->LoadInletProfile(geometry, solver, config, val_iter, FLOW_SOL, marker_type);
}
if (solver[MESH_0][TURB_SOL]) {
solver[MESH_0][TURB_SOL]->LoadInletProfile(geometry, solver, config, val_iter, TURB_SOL, marker_type);
}
if (solver[MESH_0][SPECIES_SOL]) {
solver[MESH_0][SPECIES_SOL]->LoadInletProfile(geometry, solver, config, val_iter, SPECIES_SOL, marker_type);
}
}

/*--- Exit if profiles were requested for a solver that is not available. ---*/

if (!config->GetFluidProblem()) {
SU2_MPI::Error(string("Inlet profile specification via file (C++) has not been \n") +
string("implemented yet for this solver.\n") +
string("Please set SPECIFIED_INLET_PROFILE= NO and try again."), CURRENT_FUNCTION);
SU2_MPI::Error("Inlet profile specification via file (C++) has not been \n"
"implemented yet for this solver.\n"
"Please set SPECIFIED_INLET_PROFILE= NO and try again.", CURRENT_FUNCTION);
}

} else {
Expand Down
55 changes: 25 additions & 30 deletions SU2_CFD/src/solvers/CEulerSolver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7343,59 +7343,54 @@ void CEulerSolver::BC_Supersonic_Inlet(CGeometry *geometry, CSolver **solver_con
const bool tkeNeeded = (config->GetKind_Turb_Model() == TURB_MODEL::SST);

/*--- Supersonic inlet flow: there are no outgoing characteristics,
so all flow variables can be imposed at the inlet.
First, retrieve the specified values for the primitive variables. ---*/
so all flow variables can be imposed at the inlet. ---*/

const su2double Temperature = config->GetInlet_Temperature(Marker_Tag) / config->GetTemperature_Ref();
const su2double Pressure = config->GetInlet_Pressure(Marker_Tag) / config->GetPressure_Ref();
const auto* Vel = config->GetInlet_Velocity(Marker_Tag);

su2double Velocity[MAXNDIM] = {0.0};
for (unsigned short iDim = 0; iDim < nDim; iDim++)
Velocity[iDim] = Vel[iDim] / config->GetVelocity_Ref();
SU2_OMP_FOR_DYN(OMP_MIN_SIZE)
for (auto iVertex = 0ul; iVertex < geometry->nVertex[val_marker]; iVertex++) {
const auto iPoint = geometry->vertex[val_marker][iVertex]->GetNode();

/*--- Density at the inlet from the gas law ---*/
if (!geometry->nodes->GetDomain(iPoint)) continue;

const su2double Density = Pressure / (Gas_Constant * Temperature);
/*--- Retrieve the inlet profile, note that total conditions are reused as static. ---*/

/*--- Compute the energy from the specified state ---*/
const su2double Temperature = Inlet_Ttotal[val_marker][iVertex] / config->GetTemperature_Ref();
const su2double Pressure = Inlet_Ptotal[val_marker][iVertex] / config->GetPressure_Ref();
su2double Velocity[MAXNDIM] = {0.0};
for (unsigned short iDim = 0; iDim < nDim; iDim++) {
Velocity[iDim] = Inlet_FlowDir[val_marker][iVertex][iDim] / config->GetVelocity_Ref();
}

const su2double Velocity2 = GeometryToolbox::SquaredNorm(int(MAXNDIM), Velocity);
su2double Energy = Pressure / (Density * Gamma_Minus_One) + 0.5 * Velocity2;
if (tkeNeeded) Energy += GetTke_Inf();
/*--- Density at the inlet from the gas law. ---*/

/*--- Loop over all the vertices on this boundary marker ---*/
const su2double Density = Pressure / (Gas_Constant * Temperature);

SU2_OMP_FOR_DYN(OMP_MIN_SIZE)
for (auto iVertex = 0ul; iVertex < geometry->nVertex[val_marker]; iVertex++) {
const auto iPoint = geometry->vertex[val_marker][iVertex]->GetNode();
/*--- Compute the energy from the specified state. ---*/

if (!geometry->nodes->GetDomain(iPoint)) continue;
const su2double Velocity2 = GeometryToolbox::SquaredNorm(int(MAXNDIM), Velocity);
su2double Energy = Pressure / (Density * Gamma_Minus_One) + 0.5 * Velocity2;
if (tkeNeeded) Energy += GetTke_Inf();

/*--- Allocate the value at the inlet ---*/
/*--- Primitive variables, using the derived quantities. ---*/

auto* V_inlet = GetCharacPrimVar(val_marker, iVertex);

/*--- Primitive variables, using the derived quantities ---*/

V_inlet[prim_idx.Temperature()] = Temperature;
V_inlet[prim_idx.Pressure()] = Pressure;
V_inlet[prim_idx.Density()] = Density;
V_inlet[prim_idx.Enthalpy()] = Energy + Pressure / Density;
for (unsigned short iDim = 0; iDim < nDim; iDim++)
V_inlet[iDim+prim_idx.Velocity()] = Velocity[iDim];

/*--- Current solution at this boundary node ---*/
/*--- Current solution at this boundary node. ---*/

auto* V_domain = nodes->GetPrimitive(iPoint);
const auto* V_domain = nodes->GetPrimitive(iPoint);

/*--- Normal vector for this vertex (negate for outward convention) ---*/
/*--- Normal vector for this vertex (negate for outward convention). ---*/

su2double Normal[MAXNDIM] = {0.0};
geometry->vertex[val_marker][iVertex]->GetNormal(Normal);
for (unsigned short iDim = 0; iDim < nDim; iDim++) Normal[iDim] = -Normal[iDim];

/*--- Set various quantities in the solver class ---*/
/*--- Set various quantities in the solver class. ---*/

conv_numerics->SetNormal(Normal);
conv_numerics->SetPrimitive(V_domain, V_inlet);
Expand All @@ -7404,13 +7399,13 @@ void CEulerSolver::BC_Supersonic_Inlet(CGeometry *geometry, CSolver **solver_con
conv_numerics->SetGridVel(geometry->nodes->GetGridVel(iPoint),
geometry->nodes->GetGridVel(iPoint));

/*--- Compute the residual using an upwind scheme ---*/
/*--- Compute the residual using an upwind scheme. ---*/

auto residual = conv_numerics->ComputeResidual(config);

LinSysRes.AddBlock(iPoint, residual);

/*--- Jacobian contribution for implicit integration ---*/
/*--- Jacobian contribution for implicit integration. ---*/

if (implicit)
Jacobian.AddBlock2Diag(iPoint, residual.jacobian_i);
Expand Down
Loading

0 comments on commit 1843a75

Please sign in to comment.