|
26 | 26 | * License along with SU2. If not, see <http://www.gnu.org/licenses/>. |
27 | 27 | */ |
28 | 28 |
|
| 29 | +#include "parallelization/mpi_structure.hpp" |
29 | 30 | using namespace std; |
30 | 31 |
|
31 | 32 | template <class Tenum, class TField> |
@@ -965,58 +966,6 @@ public: |
965 | 966 |
|
966 | 967 | }; |
967 | 968 |
|
968 | | -// Class where the option is represented by (String, su2double, string, su2double, ...) |
969 | | -class COptionStringDoubleList : public COptionBase { |
970 | | - string name; // identifier for the option |
971 | | - unsigned short & size; // how many strings are there (same as number of su2doubles) |
972 | | - |
973 | | - string * & s_f; // Reference to the string fields |
974 | | - su2double* & d_f; // reference to the su2double fields |
975 | | - |
976 | | -public: |
977 | | - 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) { |
978 | | - this->name = option_field_name; |
979 | | - } |
980 | | - |
981 | | - ~COptionStringDoubleList() override {}; |
982 | | - string SetValue(vector<string> option_value) override { |
983 | | - COptionBase::SetValue(option_value); |
984 | | - // There must be an even number of entries (same number of strings and doubles |
985 | | - unsigned short totalVals = option_value.size(); |
986 | | - if ((totalVals % 2) != 0) { |
987 | | - if ((totalVals == 1) && (option_value[0].compare("NONE") == 0)) { |
988 | | - // It's okay to say its NONE |
989 | | - this->size = 0; |
990 | | - return ""; |
991 | | - } |
992 | | - string newstring; |
993 | | - newstring.append(this->name); |
994 | | - newstring.append(": must have an even number of entries"); |
995 | | - return newstring; |
996 | | - } |
997 | | - unsigned short nVals = totalVals / 2; |
998 | | - this->size = nVals; |
999 | | - this->s_f = new string[nVals]; |
1000 | | - this->d_f = new su2double[nVals]; |
1001 | | - |
1002 | | - for (unsigned long i = 0; i < nVals; i++) { |
1003 | | - this->s_f[i].assign(option_value[2*i]); // 2 because have su2double and string |
1004 | | - istringstream is(option_value[2*i + 1]); |
1005 | | - su2double val; |
1006 | | - if (!(is >> val)) { |
1007 | | - return badValue(option_value, "string su2double", this->name); |
1008 | | - } |
1009 | | - this->d_f[i] = val; |
1010 | | - } |
1011 | | - // Need to return something... |
1012 | | - return ""; |
1013 | | - } |
1014 | | - |
1015 | | - void SetDefault() override { |
1016 | | - this->size = 0; // There is no default value for list |
1017 | | - } |
1018 | | -}; |
1019 | | - |
1020 | 969 | class COptionInlet : public COptionBase { |
1021 | 970 | string name; // identifier for the option |
1022 | 971 | unsigned short & size; |
@@ -1101,6 +1050,101 @@ public: |
1101 | 1050 | } |
1102 | 1051 | }; |
1103 | 1052 |
|
| 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. |
| 1076 | + |
| 1077 | +public: |
| 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_) { |
| 1081 | + } |
| 1082 | + |
| 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 | + } |
| 1086 | + |
| 1087 | + string SetValue(vector<string> option_value) override { |
| 1088 | + COptionBase::SetValue(option_value); |
| 1089 | + unsigned short option_size = option_value.size(); |
| 1090 | + if ((option_size == 1) && (option_value[0].compare("NONE") == 0)) { |
| 1091 | + size = 0; |
| 1092 | + num_vals = 0; |
| 1093 | + return ""; |
| 1094 | + } |
| 1095 | + |
| 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); |
| 1104 | + } else { |
| 1105 | + num_vals_per_string.back()++; |
| 1106 | + } |
| 1107 | + } |
| 1108 | + |
| 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(); |
| 1116 | + |
| 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); |
| 1120 | + |
| 1121 | + strings = new string[size]; |
| 1122 | + values = new Type[size]; |
| 1123 | + |
| 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); |
| 1135 | + } |
| 1136 | + } |
| 1137 | + } |
| 1138 | + return ""; |
| 1139 | + } |
| 1140 | + |
| 1141 | + void SetDefault() override { |
| 1142 | + size = 0; // There is no default value for lists |
| 1143 | + num_vals = 0; |
| 1144 | + } |
| 1145 | +}; |
| 1146 | + |
| 1147 | + |
1104 | 1148 | template <class Tenum> |
1105 | 1149 | class COptionRiemann : public COptionBase { |
1106 | 1150 |
|
|
0 commit comments