@@ -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
0 commit comments