Skip to content

Commit 88e2922

Browse files
committed
support per-species flux or value
1 parent 9dc1597 commit 88e2922

File tree

6 files changed

+273
-55
lines changed

6 files changed

+273
-55
lines changed

Common/include/CConfig.hpp

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -200,6 +200,7 @@ class CConfig {
200200
nMarker_Inlet_Species, /*!< \brief Number of inlet species markers. */
201201
nSpecies_per_Inlet, /*!< \brief Number of species defined per inlet markers. */
202202
nMarker_Wall_Species, /*!< \brief Number of wall species markers. */
203+
nSpecies_per_Wall, /*!< \brief Number of species defined per wall markers. */
203204
nMarker_Inlet_Turb, /*!< \brief Number of inlet turbulent markers. */
204205
nTurb_Properties, /*!< \brief Number of turbulent properties per inlet markers. */
205206
nMarker_Riemann, /*!< \brief Number of Riemann flow markers. */
@@ -296,8 +297,8 @@ class CConfig {
296297
su2double **Inlet_Velocity; /*!< \brief Specified flow velocity vectors for supersonic inlet boundaries. */
297298
su2double **Inlet_SpeciesVal; /*!< \brief Specified species vector for inlet boundaries. */
298299
su2double **Inlet_TurbVal; /*!< \brief Specified turbulent intensity and viscosity ratio for inlet boundaries. */
299-
unsigned short *Kind_Wall_Species; /*!< \brief Species boundary condition type for wall boundaries (FLUX or VALUE). */
300-
su2double *Wall_SpeciesVal; /*!< \brief Specified species flux or value for wall boundaries. */
300+
unsigned short **Kind_Wall_Species; /*!< \brief Species boundary condition type for wall boundaries (FLUX or VALUE) per species. */
301+
su2double **Wall_SpeciesVal; /*!< \brief Specified species flux or value for wall boundaries per species. */
301302
su2double *EngineInflow_Target; /*!< \brief Specified fan face targets for nacelle boundaries. */
302303
su2double *Inflow_Mach; /*!< \brief Specified fan face mach for nacelle boundaries. */
303304
su2double *Inflow_Pressure; /*!< \brief Specified fan face pressure for nacelle boundaries. */
@@ -1396,8 +1397,9 @@ class CConfig {
13961397
su2double* & var1, su2double* & var2, su2double** & FlowDir, su2double* & relaxfactor1, su2double* & relaxfactor2);
13971398

13981399
template <class Tenum>
1399-
void addWallSpeciesOption(const string name, unsigned short & nMarker_Wall_Species, string * & Marker_Wall_Species, unsigned short* & option_field, const map<string, Tenum> & enum_map,
1400-
su2double* & value);
1400+
void addWallSpeciesOption(const string name, unsigned short & nMarker_Wall_Species, string * & Marker_Wall_Species,
1401+
unsigned short** & option_field, const map<string, Tenum> & enum_map,
1402+
su2double** & value, unsigned short & nSpecies_per_Wall);
14011403

14021404
void addExhaustOption(const string& name, unsigned short & nMarker_Exhaust, string * & Marker_Exhaust,
14031405
su2double* & Ttotal, su2double* & Ptotal);
@@ -7140,18 +7142,20 @@ class CConfig {
71407142
const su2double* GetInlet_SpeciesVal(const string& val_index) const;
71417143

71427144
/*!
7143-
* \brief Get the species value at a wall boundary
7145+
* \brief Get the species value at a wall boundary for a specific species
71447146
* \param[in] val_marker - Marker tag corresponding to the wall boundary.
7147+
* \param[in] iSpecies - Species index.
71457148
* \return The wall species value (flux or Dirichlet value).
71467149
*/
7147-
su2double GetWall_SpeciesVal(const string& val_marker) const;
7150+
su2double GetWall_SpeciesVal(const string& val_marker, unsigned short iSpecies) const;
71487151

71497152
/*!
7150-
* \brief Get the species boundary condition type at a wall boundary
7153+
* \brief Get the species boundary condition type at a wall boundary for a specific species
71517154
* \param[in] val_marker - Marker tag corresponding to the wall boundary.
7155+
* \param[in] iSpecies - Species index.
71527156
* \return The wall species type (WALL_SPECIES_FLUX or WALL_SPECIES_VALUE).
71537157
*/
7154-
unsigned short GetWall_SpeciesType(const string& val_marker) const;
7158+
unsigned short GetWall_SpeciesType(const string& val_marker, unsigned short iSpecies) const;
71557159

71567160
/*!
71577161
* \brief Get the turbulent properties values at an inlet boundary

Common/include/option_structure.inl

Lines changed: 100 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1309,13 +1309,16 @@ class COptionWallSpecies : public COptionBase {
13091309
string name; // identifier for the option
13101310
unsigned short& size;
13111311
string*& marker;
1312-
unsigned short*& field; // Reference to the field name
1313-
su2double*& value;
1312+
unsigned short**& field; // Reference to the field name (now 2D: marker x species)
1313+
su2double**& value; // Now 2D: marker x species
1314+
unsigned short& nSpecies_per_Wall;
13141315

13151316
public:
13161317
COptionWallSpecies(string option_field_name, unsigned short& nMarker_Wall_Species, string*& Marker_Wall_Species,
1317-
unsigned short*& option_field, const map<string, Tenum> m, su2double*& value)
1318-
: size(nMarker_Wall_Species), marker(Marker_Wall_Species), field(option_field), value(value) {
1318+
unsigned short**& option_field, const map<string, Tenum> m, su2double**& value,
1319+
unsigned short& nSpecies_per_Wall)
1320+
: size(nMarker_Wall_Species), marker(Marker_Wall_Species), field(option_field), value(value),
1321+
nSpecies_per_Wall(nSpecies_per_Wall) {
13191322
this->name = option_field_name;
13201323
this->m = m;
13211324
}
@@ -1325,10 +1328,16 @@ class COptionWallSpecies : public COptionBase {
13251328
marker = nullptr;
13261329
}
13271330
if (field) {
1331+
for (unsigned short i = 0; i < size; i++) {
1332+
delete[] field[i];
1333+
}
13281334
delete[] field;
13291335
field = nullptr;
13301336
}
13311337
if (value) {
1338+
for (unsigned short i = 0; i < size; i++) {
1339+
delete[] value[i];
1340+
}
13321341
delete[] value;
13331342
value = nullptr;
13341343
}
@@ -1342,43 +1351,103 @@ class COptionWallSpecies : public COptionBase {
13421351
this->marker = nullptr;
13431352
this->field = nullptr;
13441353
this->value = nullptr;
1354+
this->nSpecies_per_Wall = 0;
13451355
return "";
13461356
}
13471357

1348-
if (totalVals % 3 != 0) {
1358+
/*--- Determine the number of markers and species per marker.
1359+
* Format: marker1, TYPE1, value1, TYPE2, value2, ..., marker2, TYPE1, value1, ...
1360+
* Each marker name starts with a letter, each TYPE is an enum string (starts with letter),
1361+
* and each value is numeric. Pattern: marker, (TYPE, value) x N ---*/
1362+
1363+
vector<unsigned short> marker_indices; // Indices where markers start
1364+
vector<unsigned short> species_counts; // Number of species per marker
1365+
1366+
// Find all marker positions (strings starting with a letter that are not TYPE keywords)
1367+
for (unsigned short i = 0; i < totalVals; i++) {
1368+
if (isalpha(option_value[i][0])) {
1369+
// Check if this could be a TYPE keyword (i.e., is it in the enum map?)
1370+
if (this->m.find(option_value[i]) != m.end()) {
1371+
continue; // This is a TYPE keyword, not a marker
1372+
}
1373+
// This is a marker name
1374+
marker_indices.push_back(i);
1375+
}
1376+
}
1377+
1378+
if (marker_indices.empty()) {
13491379
string newstring;
13501380
newstring.append(this->name);
1351-
newstring.append(": must have a number of entries divisible by 3");
1352-
this->size = 0;
1353-
this->marker = nullptr;
1354-
this->field = nullptr;
1355-
this->value = nullptr;
1381+
newstring.append(": no valid markers found");
13561382
return newstring;
13571383
}
13581384

1359-
unsigned short nVals = totalVals / 3;
1360-
this->size = nVals;
1361-
this->marker = new string[nVals];
1362-
this->field = new unsigned short[nVals];
1363-
this->value = new su2double[nVals];
1385+
// Calculate number of species for each marker
1386+
for (unsigned short i = 0; i < marker_indices.size(); i++) {
1387+
unsigned short start_idx = marker_indices[i] + 1; // Start after marker name
1388+
unsigned short end_idx = (i + 1 < marker_indices.size()) ? marker_indices[i + 1] : totalVals;
1389+
unsigned short entries = end_idx - start_idx;
13641390

1365-
for (unsigned long i = 0; i < nVals; i++) {
1366-
this->marker[i].assign(option_value[3 * i]);
1367-
// Check to see if the enum value is in the map
1368-
if (this->m.find(option_value[3 * i + 1]) == m.end()) {
1369-
string str;
1370-
str.append(this->name);
1371-
str.append(": invalid option value ");
1372-
str.append(option_value[3 * i + 1]);
1373-
str.append(". Check current SU2 options in config_template.cfg.");
1374-
return str;
1391+
// Each species needs 2 entries: TYPE and value
1392+
if (entries % 2 != 0) {
1393+
string newstring;
1394+
newstring.append(this->name);
1395+
newstring.append(": each marker must have pairs of (TYPE, value) entries");
1396+
return newstring;
13751397
}
1376-
Tenum val = this->m[option_value[3 * i + 1]];
1377-
this->field[i] = val;
13781398

1379-
istringstream ss_value(option_value[3 * i + 2]);
1380-
if (!(ss_value >> this->value[i])) {
1381-
return badValue("WallSpecies", this->name);
1399+
species_counts.push_back(entries / 2);
1400+
}
1401+
1402+
// Check that all markers have the same number of species
1403+
this->nSpecies_per_Wall = species_counts[0];
1404+
for (auto count : species_counts) {
1405+
if (count != this->nSpecies_per_Wall) {
1406+
string newstring;
1407+
newstring.append(this->name);
1408+
newstring.append(": all markers must specify the same number of species");
1409+
return newstring;
1410+
}
1411+
}
1412+
1413+
// Allocate arrays
1414+
this->size = marker_indices.size();
1415+
this->marker = new string[this->size];
1416+
this->field = new unsigned short*[this->size];
1417+
this->value = new su2double*[this->size];
1418+
1419+
for (unsigned short i = 0; i < this->size; i++) {
1420+
this->field[i] = new unsigned short[this->nSpecies_per_Wall];
1421+
this->value[i] = new su2double[this->nSpecies_per_Wall];
1422+
}
1423+
1424+
// Parse the values
1425+
for (unsigned short iMarker = 0; iMarker < this->size; iMarker++) {
1426+
unsigned short marker_idx = marker_indices[iMarker];
1427+
this->marker[iMarker].assign(option_value[marker_idx]);
1428+
1429+
// Parse species data for this marker
1430+
for (unsigned short iSpecies = 0; iSpecies < this->nSpecies_per_Wall; iSpecies++) {
1431+
unsigned short type_idx = marker_idx + 1 + 2 * iSpecies;
1432+
unsigned short val_idx = type_idx + 1;
1433+
1434+
// Check TYPE keyword
1435+
if (this->m.find(option_value[type_idx]) == m.end()) {
1436+
string str;
1437+
str.append(this->name);
1438+
str.append(": invalid option value ");
1439+
str.append(option_value[type_idx]);
1440+
str.append(". Check current SU2 options in config_template.cfg.");
1441+
return str;
1442+
}
1443+
1444+
Tenum val = this->m[option_value[type_idx]];
1445+
this->field[iMarker][iSpecies] = val;
1446+
1447+
istringstream ss_value(option_value[val_idx]);
1448+
if (!(ss_value >> this->value[iMarker][iSpecies])) {
1449+
return badValue("WallSpecies", this->name);
1450+
}
13821451
}
13831452
}
13841453

@@ -1390,6 +1459,7 @@ class COptionWallSpecies : public COptionBase {
13901459
this->field = nullptr;
13911460
this->value = nullptr;
13921461
this->size = 0; // There is no default value for list
1462+
this->nSpecies_per_Wall = 0;
13931463
}
13941464
};
13951465

Common/src/CConfig.cpp

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -514,11 +514,12 @@ void CConfig::addRiemannOption(const string name, unsigned short & nMarker_Riema
514514
}
515515

516516
template <class Tenum>
517-
void CConfig::addWallSpeciesOption(const string name, unsigned short & nMarker_Wall_Species, string * & Marker_Wall_Species, unsigned short* & option_field, const map<string, Tenum> & enum_map,
518-
su2double* & value) {
517+
void CConfig::addWallSpeciesOption(const string name, unsigned short & nMarker_Wall_Species, string * & Marker_Wall_Species,
518+
unsigned short** & option_field, const map<string, Tenum> & enum_map,
519+
su2double** & value, unsigned short & nSpecies_per_Wall) {
519520
assert(option_map.find(name) == option_map.end());
520521
all_options.insert(pair<string, bool>(name, true));
521-
COptionBase* val = new COptionWallSpecies<Tenum>(name, nMarker_Wall_Species, Marker_Wall_Species, option_field, enum_map, value);
522+
COptionBase* val = new COptionWallSpecies<Tenum>(name, nMarker_Wall_Species, Marker_Wall_Species, option_field, enum_map, value, nSpecies_per_Wall);
522523
option_map.insert(pair<string, COptionBase *>(name, val));
523524
}
524525

@@ -1628,9 +1629,10 @@ void CConfig::SetConfig_Options() {
16281629
* \n OPTIONS: See \link Riemann_Map \endlink. The variables indicated by the option and the flow direction unit vector must be specified. \ingroup Config*/
16291630
addRiemannOption("MARKER_RIEMANN", nMarker_Riemann, Marker_Riemann, Kind_Data_Riemann, Riemann_Map, Riemann_Var1, Riemann_Var2, Riemann_FlowDir);
16301631
/*!\brief MARKER_WALL_SPECIES \n DESCRIPTION: Wall species boundary marker(s) with the following format:
1631-
* (marker_name, BC_TYPE, value, ...) where BC_TYPE is either FLUX (Neumann) or VALUE (Dirichlet).
1632+
* (marker_name, BC_TYPE, value, BC_TYPE, value, ...) where BC_TYPE is either FLUX (Neumann) or VALUE (Dirichlet).
1633+
* Each marker must specify the same number of species (N species per marker).
16321634
* \n OPTIONS: See \link Wall_Map \endlink. \ingroup Config*/
1633-
addWallSpeciesOption("MARKER_WALL_SPECIES", nMarker_Wall_Species, Marker_Wall_Species, Kind_Wall_Species, Wall_Map, Wall_SpeciesVal);
1635+
addWallSpeciesOption("MARKER_WALL_SPECIES", nMarker_Wall_Species, Marker_Wall_Species, Kind_Wall_Species, Wall_Map, Wall_SpeciesVal, nSpecies_per_Wall);
16341636
/*!\brief MARKER_GILES \n DESCRIPTION: Giles boundary marker(s) with the following formats, a unit vector. */
16351637
/* \n OPTIONS: See \link Giles_Map \endlink. The variables indicated by the option and the flow direction unit vector must be specified. \ingroup Config*/
16361638
addGilesOption("MARKER_GILES", nMarker_Giles, Marker_Giles, Kind_Data_Giles, Giles_Map, Giles_Var1, Giles_Var2, Giles_FlowDir, RelaxFactorAverage, RelaxFactorFourier);
@@ -5720,6 +5722,8 @@ void CConfig::SetPostprocessing(SU2_COMPONENT val_software, unsigned short val_i
57205722
nSpecies_options.insert(nSpecies_options.end(), {nSpecies_Clipping_Min, nSpecies_Clipping_Max});
57215723
if (nMarker_Inlet_Species > 0)
57225724
nSpecies_options.push_back(nSpecies_per_Inlet);
5725+
if (nMarker_Wall_Species > 0)
5726+
nSpecies_options.push_back(nSpecies_per_Wall);
57235727
// Add more options for size check here.
57245728

57255729
/*--- nSpecies_Init is the master, but it simply checks for consistency. ---*/
@@ -5732,6 +5736,7 @@ void CConfig::SetPostprocessing(SU2_COMPONENT val_software, unsigned short val_i
57325736

57335737
/*--- Check whether some variables (or their sums) are in physical bounds. [0,1] for species related quantities. ---*/
57345738
/*--- Note, only for species transport, not for flamelet model ---*/
5739+
/*
57355740
if (Kind_Species_Model == SPECIES_MODEL::SPECIES_TRANSPORT) {
57365741
su2double Species_Init_Sum = 0.0;
57375742
for (unsigned short iSpecies = 0; iSpecies < nSpecies; iSpecies++) {
@@ -5749,7 +5754,7 @@ void CConfig::SetPostprocessing(SU2_COMPONENT val_software, unsigned short val_i
57495754
checkScalarBounds(Inlet_SpeciesVal_Sum, "MARKER_INLET_SPECIES sum", 0.0, 1.0);
57505755
}
57515756
}
5752-
5757+
*/
57535758
} // species transport checks
57545759

57555760
/*--- Define some variables for flamelet model. ---*/
@@ -9244,22 +9249,22 @@ const su2double* CConfig::GetInlet_SpeciesVal(const string& val_marker) const {
92449249
return Inlet_SpeciesVal[iMarker_Inlet_Species];
92459250
}
92469251

9247-
su2double CConfig::GetWall_SpeciesVal(const string& val_marker) const {
9252+
su2double CConfig::GetWall_SpeciesVal(const string& val_marker, unsigned short iSpecies) const {
92489253
/*--- Search for the marker in the wall species list ---*/
92499254
for (unsigned short iMarker_Wall_Species = 0; iMarker_Wall_Species < nMarker_Wall_Species; iMarker_Wall_Species++) {
92509255
if (Marker_Wall_Species[iMarker_Wall_Species] == val_marker) {
9251-
return Wall_SpeciesVal[iMarker_Wall_Species];
9256+
return Wall_SpeciesVal[iMarker_Wall_Species][iSpecies];
92529257
}
92539258
}
92549259
/*--- If marker not found (MARKER_WALL_SPECIES=NONE), return zero flux ---*/
92559260
return 0.0;
92569261
}
92579262

9258-
unsigned short CConfig::GetWall_SpeciesType(const string& val_marker) const {
9263+
unsigned short CConfig::GetWall_SpeciesType(const string& val_marker, unsigned short iSpecies) const {
92599264
/*--- Search for the marker in the wall species list ---*/
92609265
for (unsigned short iMarker_Wall_Species = 0; iMarker_Wall_Species < nMarker_Wall_Species; iMarker_Wall_Species++) {
92619266
if (Marker_Wall_Species[iMarker_Wall_Species] == val_marker) {
9262-
return Kind_Wall_Species[iMarker_Wall_Species];
9267+
return Kind_Wall_Species[iMarker_Wall_Species][iSpecies];
92639268
}
92649269
}
92659270
/*--- If marker not found (MARKER_WALL_SPECIES=NONE), return FLUX type (zero flux BC) ---*/

SU2_CFD/src/solvers/CSpeciesSolver.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -439,10 +439,6 @@ void CSpeciesSolver::BC_Wall_Generic(CGeometry* geometry, CSolver** solver_conta
439439

440440
string Marker_Tag = config->GetMarker_All_TagBound(val_marker);
441441

442-
// Get wall species boundary condition type and value for this marker
443-
su2double WallSpeciesValue = config->GetWall_SpeciesVal(Marker_Tag);
444-
unsigned short wallspeciestype = config->GetWall_SpeciesType(Marker_Tag);
445-
446442
SU2_OMP_FOR_DYN(OMP_MIN_SIZE)
447443
for (auto iVertex = 0u; iVertex < geometry->nVertex[val_marker]; iVertex++) {
448444

@@ -456,6 +452,10 @@ void CSpeciesSolver::BC_Wall_Generic(CGeometry* geometry, CSolver** solver_conta
456452

457453
for (auto iVar = 0u; iVar < nVar; iVar++) {
458454

455+
// Get wall species boundary condition type and value for this marker and species
456+
su2double WallSpeciesValue = config->GetWall_SpeciesVal(Marker_Tag, iVar);
457+
unsigned short wallspeciestype = config->GetWall_SpeciesType(Marker_Tag, iVar);
458+
459459
su2double WallSpecies = WallSpeciesValue;
460460

461461
/*--- Get the scalar values from the python wrapper. ---*/

0 commit comments

Comments
 (0)