@@ -966,58 +966,6 @@ public:
966966
967967};
968968
969- // Class where the option is represented by (String, su2double, string, su2double, ...)
970- class COptionStringDoubleList : public COptionBase {
971- string name; // identifier for the option
972- unsigned short & size; // how many strings are there (same as number of su2doubles)
973-
974- string * & s_f; // Reference to the string fields
975- su2double* & d_f; // reference to the su2double fields
976-
977- public:
978- COptionStringDoubleList (string option_field_name, unsigned short & list_size, string * & string_field, su2double* & double_field) : size(list_size), s_f(string_field), d_f(double_field) {
979- this ->name = option_field_name;
980- }
981-
982- ~COptionStringDoubleList () override {};
983- string SetValue (vector<string> option_value) override {
984- COptionBase::SetValue (option_value);
985- // There must be an even number of entries (same number of strings and doubles
986- unsigned short totalVals = option_value.size ();
987- if ((totalVals % 2 ) != 0 ) {
988- if ((totalVals == 1 ) && (option_value[0 ].compare (" NONE" ) == 0 )) {
989- // It's okay to say its NONE
990- this ->size = 0 ;
991- return " " ;
992- }
993- string newstring;
994- newstring.append (this ->name );
995- newstring.append (" : must have an even number of entries" );
996- return newstring;
997- }
998- unsigned short nVals = totalVals / 2 ;
999- this ->size = nVals;
1000- this ->s_f = new string[nVals];
1001- this ->d_f = new su2double[nVals];
1002-
1003- for (unsigned long i = 0 ; i < nVals; i++) {
1004- this ->s_f [i].assign (option_value[2 *i]); // 2 because have su2double and string
1005- istringstream is (option_value[2 *i + 1 ]);
1006- su2double val;
1007- if (!(is >> val)) {
1008- return badValue (option_value, " string su2double" , this ->name );
1009- }
1010- this ->d_f [i] = val;
1011- }
1012- // Need to return something...
1013- return " " ;
1014- }
1015-
1016- void SetDefault () override {
1017- this ->size = 0 ; // There is no default value for list
1018- }
1019- };
1020-
1021969class COptionInlet : public COptionBase {
1022970 string name; // identifier for the option
1023971 unsigned short & size;
@@ -1102,94 +1050,101 @@ public:
11021050 }
11031051};
11041052
1105- class COptionInletSpecies final : public COptionBase {
1106- const string name; // identifier for the option
1107- unsigned short & size; // number of inlets for that options
1108- string * & marker; // contains marker names
1109- su2double ** & inletspeciesval; // contains all values specified for each inlet
1110- unsigned short & nSpecies; // contains how many species are defined per inlet
1053+ // Base helper for when T is not an array, does dummy allocation and de-allocation.
1054+ template <class T >
1055+ struct CStringValuesListHelper {
1056+ static T resize (unsigned short ) { return T (); }
1057+ static T& access (T& val, unsigned short ) { return val; }
1058+ };
1059+
1060+ // Specialization for pointer types (multiple values per string).
1061+ template <class T >
1062+ struct CStringValuesListHelper <T*> {
1063+ static T* resize (unsigned short n) { return new T[n]; }
1064+ static T& access (T* ptr, unsigned short i) { return ptr[i]; }
1065+ };
1066+
1067+ // Class where the option is represented by (string, N * "some type", string, N * "some type", ...)
1068+ template <class Type >
1069+ class COptionStringValuesList final : public COptionBase {
1070+ const string name; // identifier for the option
1071+ unsigned short & size; // number of string-value pairs
1072+ string*& strings; // the strings in the option
1073+ Type*& values; // the values per string
1074+ unsigned short & num_vals; // how many values per string
1075+ unsigned short optional_num_vals = 0 ; // num_vals points to this when it is not provided in the ctor.
11111076
11121077public:
1113- COptionInletSpecies (string option_field_name, unsigned short & nMarker_Inlet_Species, string* & Marker_Inlet_Species,
1114- su2double** & option_field, unsigned short & nSpecies_per_Inlet) :
1115- name (option_field_name),
1116- size (nMarker_Inlet_Species),
1117- marker (Marker_Inlet_Species),
1118- inletspeciesval (option_field),
1119- nSpecies (nSpecies_per_Inlet) {
1078+ COptionStringValuesList (string name_, unsigned short & size_, string*& strings_,
1079+ Type*& values_, unsigned short & num_vals_) :
1080+ name (name_), size(size_), strings(strings_), values(values_), num_vals(num_vals_) {
11201081 }
11211082
1122- ~COptionInletSpecies () override {
1123- delete[] marker;
1124-
1125- if (inletspeciesval != nullptr ) {
1126- for (unsigned short i = 0 ; i < size; i++) {
1127- delete[] inletspeciesval[i];
1128- }
1129- }
1130- delete[] inletspeciesval;
1131- };
1083+ COptionStringValuesList (string name_, unsigned short & size_, string*& strings_, Type*& values_) :
1084+ name (name_), size(size_), strings(strings_), values(values_), num_vals(optional_num_vals) {
1085+ }
11321086
11331087 string SetValue (vector<string> option_value) override {
11341088 COptionBase::SetValue (option_value);
11351089 unsigned short option_size = option_value.size ();
11361090 if ((option_size == 1 ) && (option_value[0 ].compare (" NONE" ) == 0 )) {
11371091 size = 0 ;
1138- marker = nullptr ;
1139- inletspeciesval = nullptr ;
1140- nSpecies = 0 ;
1092+ num_vals = 0 ;
11411093 return " " ;
11421094 }
11431095
1144- /* --- Determine the number of inlets: A new inlet is found if the first char in the string is a letter.
1145- * This will fail in if a marker starts with a number!
1146- * Additionally, determine the number of values that are prescribed per inlet. ---*/
1147- vector<unsigned short > nSpecies_per_Inlet;
1148- /* --- Loop through the fields of the marker. ---*/
1149- for (unsigned long i = 0 ; i < option_size; i++) {
1150- /* --- If the string starts with a letter, a new marker tag is found. ---*/
1151- if (isalpha (option_value[i][0 ])) {
1152- nSpecies_per_Inlet.push_back (0 );
1096+ /* --- Determine the number of strings: A new string is found if the first char in the option is a letter.
1097+ * This will fail in if a string starts with a number! Additionally, determine the number of values that
1098+ * are prescribed per string. ---*/
1099+ vector<unsigned short > num_vals_per_string;
1100+ /* --- Loop through the fields of the option. ---*/
1101+ for (const auto & val : option_value) {
1102+ if (isalpha (val[0 ])) {
1103+ num_vals_per_string.push_back (0 );
11531104 } else {
1154- /* -- Else, a species fractions values is found and the respective counter is incremented. ---*/
1155- nSpecies_per_Inlet.back ()++;
1105+ num_vals_per_string.back ()++;
11561106 }
11571107 }
11581108
1159- /* --- Check that the same amount of values are defined per marker . ---*/
1160- for (auto elem : nSpecies_per_Inlet)
1161- if (nSpecies_per_Inlet [0 ] != elem )
1162- SU2_MPI::Error (" Unequal number of species defined for MARKER_INLET_SPECIES. " , CURRENT_FUNCTION);
1163-
1164- nSpecies = nSpecies_per_Inlet [0 ];
1165- size = nSpecies_per_Inlet .size ();
1109+ /* --- Check that the same amount of values are defined per string . ---*/
1110+ for (auto n : num_vals_per_string) {
1111+ if (num_vals_per_string [0 ] != n )
1112+ SU2_MPI::Error (string ( " Unequal number of values defined for " ) + name , CURRENT_FUNCTION);
1113+ }
1114+ num_vals = num_vals_per_string [0 ];
1115+ size = num_vals_per_string .size ();
11661116
1167- marker = new string[size];
1168- inletspeciesval = new su2double*[size];
1169- for (unsigned short i = 0 ; i < size; i++) {
1170- inletspeciesval[i] = new su2double[nSpecies];
1117+ /* --- If num_vals was taken as optional, it can only be one. ---*/
1118+ if (optional_num_vals > 1 )
1119+ SU2_MPI::Error (string (" More than one value provided for \" string-value\" pair, in " ) + name, CURRENT_FUNCTION);
11711120
1172- marker[i].assign (option_value[(1 +nSpecies)*i]);
1121+ strings = new string[size];
1122+ values = new Type[size];
11731123
1174- for (unsigned short j = 0 ; j < nSpecies; j++){
1175- istringstream ss_nd (option_value[(1 +nSpecies)*i + 1 +j]);
1176- if (!(ss_nd >> inletspeciesval[i][j])) {
1177- return badValue (option_value, " inlet" , name);
1124+ auto option_it = option_value.begin ();
1125+ for (unsigned short i = 0 ; i < size; i++) {
1126+ strings[i].assign (*option_it);
1127+ ++option_it;
1128+
1129+ values[i] = CStringValuesListHelper<Type>::resize (num_vals);
1130+ for (unsigned short j = 0 ; j < num_vals; j++) {
1131+ istringstream ss_nd (*option_it);
1132+ ++option_it;
1133+ if (!(ss_nd >> CStringValuesListHelper<Type>::access (values[i], j))) {
1134+ return badValue (option_value, " \" string + values\" " , name);
11781135 }
11791136 }
11801137 }
1181-
11821138 return " " ;
11831139 }
11841140
11851141 void SetDefault () override {
1186- marker = nullptr ;
1187- inletspeciesval = nullptr ;
1188- size = 0 ; // There is no default value for list
1189- nSpecies = 0 ;
1142+ size = 0 ; // There is no default value for lists
1143+ num_vals = 0 ;
11901144 }
11911145};
11921146
1147+
11931148template <class Tenum >
11941149class COptionRiemann : public COptionBase {
11951150
0 commit comments