diff --git a/.gitmodules b/.gitmodules index ae2967618b2..066d68e15e6 100644 --- a/.gitmodules +++ b/.gitmodules @@ -18,3 +18,6 @@ [submodule "externals/opdi"] path = externals/opdi url = https://github.com/SciCompKL/OpDiLib +[submodule "externals/mel"] + path = externals/mel + url = https://github.com/pcarruscag/MEL.git diff --git a/Common/include/CConfig.hpp b/Common/include/CConfig.hpp index 81e06b919eb..719359af7d2 100644 --- a/Common/include/CConfig.hpp +++ b/Common/include/CConfig.hpp @@ -80,7 +80,6 @@ class CConfig { su2double EA_ScaleFactor; /*!< \brief Equivalent Area scaling factor */ su2double AdjointLimit; /*!< \brief Adjoint variable limit */ string* ConvField; /*!< \brief Field used for convergence check.*/ - string ConvCriteria; // This option is deprecated. After a grace period until 7.2.0 the usage warning should become an error. string* WndConvField; /*!< \brief Function where to apply the windowed convergence criteria for the time average of the unsteady (single zone) flow problem. */ unsigned short nConvField; /*!< \brief Number of fields used to monitor convergence.*/ @@ -436,7 +435,7 @@ class CConfig { Unst_CFL; /*!< \brief Unsteady CFL number. */ bool ReorientElements; /*!< \brief Flag for enabling element reorientation. */ - bool AddIndNeighbor; /*!< \brief Include indirect neighbor in the agglomeration process. */ + string CustomObjFunc; /*!< \brief User-defined objective function. */ unsigned short nDV, /*!< \brief Number of design variables. */ nObj, nObjW; /*! \brief Number of objective functions. */ unsigned short* nDV_Value; /*!< \brief Number of values for each design variable (might be different than 1 if we allow arbitrary movement). */ @@ -5177,6 +5176,11 @@ class CConfig { */ void SetWeight_ObjFunc(unsigned short val_obj, su2double val) { Weight_ObjFunc[val_obj] = val; } + /*! + * \brief Get the user expression for the custom objective function. + */ + const string& GetCustomObjFunc() const { return CustomObjFunc; } + /*! * \brief Get the kind of sensitivity smoothing technique. * \return Kind of sensitivity smoothing technique. @@ -5469,12 +5473,6 @@ class CConfig { */ string GetObjFunc_Extension(string val_filename) const; - /*! - * \brief Get the criteria for structural residual (relative/absolute). - * \return Relative/Absolute criteria for structural convergence. - */ - unsigned short GetResidual_Criteria_FEM(void) const { return Res_FEM_CRIT; } - /*! * \brief Get functional that is going to be used to evaluate the residual flow convergence. * \return Functional that is going to be used to evaluate the residual flow convergence. diff --git a/Common/include/option_structure.hpp b/Common/include/option_structure.hpp index ee22f281bde..884843db74f 100644 --- a/Common/include/option_structure.hpp +++ b/Common/include/option_structure.hpp @@ -1563,17 +1563,8 @@ enum ENUM_OBJECTIVE { SURFACE_SPECIES_0 = 58, /*!< \brief Surface Avg. Species_0 objective function definition. */ SURFACE_SPECIES_VARIANCE = 59,/*!< \brief Species Variance objective function definition. */ CUSTOM_OBJFUNC = 31, /*!< \brief Custom objective function definition. */ - TOTAL_PRESSURE_LOSS = 39, - KINETIC_ENERGY_LOSS = 40, - TOTAL_EFFICIENCY = 41, - TOTAL_STATIC_EFFICIENCY = 42, - EULERIAN_WORK = 43, - TOTAL_ENTHALPY_IN = 44, - FLOW_ANGLE_IN = 45, FLOW_ANGLE_OUT = 46, MASS_FLOW_IN = 47, - MASS_FLOW_OUT = 48, - PRESSURE_RATIO = 49, ENTROPY_GENERATION = 50, REFERENCE_GEOMETRY = 60, /*!< \brief Norm of displacements with respect to target geometry. */ REFERENCE_NODE = 61, /*!< \brief Objective function defined as the difference of a particular node respect to a reference position. */ @@ -1617,18 +1608,9 @@ static const MapType Objective_Map = { MakePair("SURFACE_SPECIES_0", SURFACE_SPECIES_0) MakePair("SURFACE_SPECIES_VARIANCE", SURFACE_SPECIES_VARIANCE) MakePair("CUSTOM_OBJFUNC", CUSTOM_OBJFUNC) - MakePair("TOTAL_EFFICIENCY", TOTAL_EFFICIENCY) - MakePair("TOTAL_STATIC_EFFICIENCY", TOTAL_STATIC_EFFICIENCY) - MakePair("TOTAL_PRESSURE_LOSS", TOTAL_PRESSURE_LOSS) - MakePair("EULERIAN_WORK", EULERIAN_WORK) - MakePair("TOTAL_ENTHALPY_IN", TOTAL_ENTHALPY_IN) - MakePair("FLOW_ANGLE_IN", FLOW_ANGLE_IN) MakePair("FLOW_ANGLE_OUT", FLOW_ANGLE_OUT) MakePair("MASS_FLOW_IN", MASS_FLOW_IN) - MakePair("MASS_FLOW_OUT", MASS_FLOW_OUT) - MakePair("PRESSURE_RATIO", PRESSURE_RATIO) MakePair("ENTROPY_GENERATION", ENTROPY_GENERATION) - MakePair("KINETIC_ENERGY_LOSS", KINETIC_ENERGY_LOSS) MakePair("REFERENCE_GEOMETRY", REFERENCE_GEOMETRY) MakePair("REFERENCE_NODE", REFERENCE_NODE) MakePair("VOLUME_FRACTION", VOLUME_FRACTION) @@ -1637,46 +1619,6 @@ static const MapType Objective_Map = { MakePair("STRESS_PENALTY", STRESS_PENALTY) }; -/*! - * \brief Types of residual criteria equations - */ -enum ENUM_RESIDUAL { - RHO_RESIDUAL = 1, /*!< \brief Rho equation residual criteria equation. */ - RHO_ENERGY_RESIDUAL = 2 /*!< \brief RhoE equation residual criteria equation. */ -}; -static const MapType Residual_Map = { - MakePair("RHO", RHO_RESIDUAL) - MakePair("RHO_ENERGY", RHO_ENERGY_RESIDUAL) -}; - -/*! - * \brief Types of residual criteria for structural problems - */ -enum ENUM_RESFEM { - RESFEM_RELATIVE = 1, /*!< \brief Relative criteria: Res/Res0. */ - RESFEM_ABSOLUTE = 2 /*!< \brief Absolute criteria: abs(Res). */ -}; -static const MapType ResFem_Map = { - MakePair("RELATIVE", RESFEM_RELATIVE) - MakePair("ABSOLUTE", RESFEM_ABSOLUTE) -}; - -/*! - * \brief Types of sensitivities to compute - */ -enum ENUM_SENS { - SENS_GEOMETRY = 1, /*!< \brief Geometrical sensitivity. */ - SENS_MACH = 2, /*!< \brief Mach number sensitivity. */ - SENS_AOA = 3, /*!< \brief Angle of attack sensitivity. */ - SENS_AOS = 4 /*!< \brief Angle of Sideslip sensitivity. */ -}; -static const MapType Sens_Map = { - MakePair("SENS_GEOMETRY", SENS_GEOMETRY) - MakePair("SENS_MACH", SENS_MACH) - MakePair("SENS_AOA", SENS_AOA) - MakePair("SENS_AOS", SENS_AOS) -}; - /*! * \brief Types of input file formats */ @@ -1823,32 +1765,6 @@ static const MapType MG_Cycle_Map = { MakePair("FULLMG_CYCLE", FULLMG_CYCLE) }; -/*! - * \brief Type of solution output variables - */ -enum ENUM_OUTPUT_VARS { - DENSITY = 1, /*!< \brief Density. */ - VEL_X = 2, /*!< \brief X-component of velocity. */ - VEL_Y = 3, /*!< \brief Y-component of velocity. */ - VEL_Z = 4, /*!< \brief Z-component of velocity. */ - PRESSURE = 5, /*!< \brief Static pressure. */ - MACH = 6, /*!< \brief Mach number. */ - TEMPERATURE = 7, /*!< \brief Temperature. */ - LAM_VISC = 8, /*!< \brief Laminar viscosity. */ - EDDY_VISC = 9 /*!< \brief Eddy viscosity. */ -}; -static const MapType Output_Vars_Map = { - MakePair("DENSITY", DENSITY) - MakePair("VEL_X", VEL_X) - MakePair("VEL_Y", VEL_Y) - MakePair("VEL_Z", VEL_Z) - MakePair("PRESSURE", PRESSURE) - MakePair("MACH", MACH) - MakePair("TEMPERATURE", TEMPERATURE) - MakePair("LAM_VISC", LAM_VISC) - MakePair("EDDY_VISC", EDDY_VISC) -}; - /*! * \brief Types of design parameterizations */ @@ -2352,17 +2268,20 @@ class COptionBase { private: std::vector value; public: - COptionBase() {}; - virtual ~COptionBase() = 0; + virtual ~COptionBase() = default; + + const std::vector& GetValue() const {return value;} - virtual std::string SetValue(std::vector value){this->value = value; return "";} - std::vector GetValue() {return value;} + virtual std::string SetValue(const std::vector& val) { + value = val; + return ""; + } virtual void SetDefault() = 0; - std::string optionCheckMultipleValues(std::vector & option_value, std::string type_id, std::string option_name) { + std::string optionCheckMultipleValues(const std::vector& option_value, + std::string type_id, const std::string& option_name) { if (option_value.size() != 1) { - std::string newString; - newString.append(option_name); + std::string newString(option_name); newString.append(": multiple values for type "); newString.append(type_id); return newString; @@ -2370,17 +2289,14 @@ class COptionBase { return ""; } - std::string badValue(std::vector & option_value, std::string type_id, std::string option_name) { - std::string newString; - newString.append(option_name); + std::string badValue(std::string type_id, const std::string& option_name) { + std::string newString(option_name); newString.append(": improper option value for type "); newString.append(type_id); return newString; } }; -inline COptionBase::~COptionBase() {} - #ifdef ENABLE_MAPS #include "option_structure.inl" #endif diff --git a/Common/include/option_structure.inl b/Common/include/option_structure.inl index 596fac58823..fcfeca9b1dc 100644 --- a/Common/include/option_structure.inl +++ b/Common/include/option_structure.inl @@ -47,9 +47,7 @@ public: name(std::move(option_field_name)) { } - ~COptionEnum() = default; - - string SetValue(vector option_value) override { + string SetValue(const vector& option_value) override { COptionBase::SetValue(option_value); // Check if there is more than one string string out = optionCheckMultipleValues(option_value, "enum", name); @@ -96,9 +94,7 @@ public: typeName(type_name) { } - ~COptionScalar() = default; - - string SetValue(vector option_value) override { + string SetValue(const vector& option_value) override { COptionBase::SetValue(option_value); string out = optionCheckMultipleValues(option_value, typeName, name); @@ -107,7 +103,7 @@ public: istringstream is(option_value.front()); if (is >> field) return ""; - return badValue(option_value, typeName, name); + return badValue(typeName, name); } void SetDefault() final { @@ -155,14 +151,6 @@ public: } }; -class COptionString final : public COptionScalar { -public: - template - COptionString(Ts&&... args) : - COptionScalar("string", args...) { - } -}; - class COptionBool final : public COptionScalar { public: template @@ -170,7 +158,7 @@ public: COptionScalar("bool", args...) { } - string SetValue(vector option_value) override { + string SetValue(const vector& option_value) override { COptionBase::SetValue(option_value); string result; @@ -187,7 +175,39 @@ public: return ""; } - return badValue(option_value, "bool", name); + return badValue("bool", name); + } +}; + +class COptionString final : public COptionBase { +protected: + string& field; // Reference to the fieldname + const string def; // Default value + const string name; // identifier for the option + +public: + COptionString() = delete; + + COptionString(const string& option_field_name, + string& option_field, + string default_value) : + field(option_field), + def(default_value), + name(option_field_name) { + } + + string SetValue(const vector& option_value) override { + COptionBase::SetValue(option_value); + + string out = optionCheckMultipleValues(option_value, "string", name); + if (!out.empty()) return out; + + field = option_value.front(); + return ""; + } + + void SetDefault() override { + field = def; } }; @@ -209,9 +229,7 @@ public: name(option_field_name) { } - ~COptionEnumList() = default; - - string SetValue(vector option_value) override { + string SetValue(const vector& option_value) override { COptionBase::SetValue(option_value); if (option_value.size() == 1 && option_value[0].compare("NONE") == 0) { mySize = 0; @@ -255,9 +273,7 @@ public: field(option_field) { } - ~COptionArray() override {}; - - string SetValue(vector option_value) override { + string SetValue(const vector& option_value) override { COptionBase::SetValue(option_value); // Check that the size is correct if (option_value.size() != (unsigned long)this->size) { @@ -277,7 +293,7 @@ public: for (int i = 0; i < this->size; i++) { istringstream is(option_value[i]); if (!(is >> field[i])) { - return badValue(option_value, " array", this->name); + return badValue(" array", this->name); } } return ""; @@ -306,9 +322,7 @@ public: typeName(type_name) { } - ~COptionScalarList() = default; - - string SetValue(vector option_value) final { + string SetValue(const vector& option_value) final { COptionBase::SetValue(option_value); // The size is the length of option_value mySize = option_value.size(); @@ -324,7 +338,7 @@ public: istringstream is(option_value[i]); Scalar val; if (!(is >> val)) { - return badValue(option_value, typeName+" list", name); + return badValue(typeName+" list", name); } field[i] = std::move(val); } @@ -378,7 +392,7 @@ public: COptionConvect(string option_field_name, unsigned short & space_field, unsigned short & centered_field, unsigned short & upwind_field) : name(option_field_name), space(space_field), centered(centered_field), upwind(upwind_field) { } - string SetValue(vector option_value) override { + string SetValue(const vector& option_value) override { COptionBase::SetValue(option_value); string out = optionCheckMultipleValues(option_value, "unsigned short", this->name); @@ -400,7 +414,7 @@ public: } // Make them defined in case something weird happens SetDefault(); - return badValue(option_value, "convect", this->name); + return badValue("convect", this->name); } @@ -422,7 +436,7 @@ public: } ~COptionFEMConvect() override {}; - string SetValue(vector option_value) override { + string SetValue(const vector& option_value) override { COptionBase::SetValue(option_value); string out = optionCheckMultipleValues(option_value, "unsigned short", this->name); @@ -438,7 +452,7 @@ public: // Make them defined in case something weird happens this->fem = NO_FEM; - return badValue(option_value, "convect", this->name); + return badValue("convect", this->name); } @@ -465,14 +479,14 @@ public: } ~COptionMathProblem() override {}; - string SetValue(vector option_value) override { + string SetValue(const vector& option_value) override { COptionBase::SetValue(option_value); string out = optionCheckMultipleValues(option_value, "unsigned short", name); if (out.compare("") != 0) { return out; } else if (option_value[0] == "ADJOINT") { - return badValue(option_value, "math problem (try CONTINUOUS_ADJOINT)", name); + return badValue("math problem (try CONTINUOUS_ADJOINT)", name); } else if (option_value[0] == "DIRECT") { cont_adjoint = false; @@ -492,7 +506,7 @@ public: restart = true; return ""; } - return badValue(option_value, "math problem", name); + return badValue("math problem", name); } void SetDefault() override { @@ -517,7 +531,7 @@ public: ~COptionDVParam() override {}; - string SetValue(vector option_value) override { + string SetValue(const vector& option_value) override { COptionBase::SetValue(option_value); if ((option_value.size() == 1) && (option_value[0].compare("NONE") == 0)) { this->nDV = 0; @@ -689,7 +703,7 @@ public: ~COptionDVValue() override {}; - string SetValue(vector option_value) override { + string SetValue(const vector& option_value) override { COptionBase::SetValue(option_value); if ((option_value.size() == 1) && (option_value[0].compare("NONE") == 0)) { this->nDV_Value = nullptr; @@ -795,7 +809,7 @@ public: ~COptionFFDDef() override {}; - string SetValue(vector option_value) override { + string SetValue(const vector& option_value) override { COptionBase::SetValue(option_value); if ((option_value.size() == 1) && (option_value[0].compare("NONE") == 0)) { this->nFFD = 0; @@ -890,7 +904,7 @@ public: ~COptionFFDDegree() override {}; - string SetValue(vector option_value) override { + string SetValue(const vector& option_value) override { COptionBase::SetValue(option_value); if ((option_value.size() == 1) && (option_value[0].compare("NONE") == 0)) { this->nFFD = 0; @@ -980,7 +994,7 @@ public: } ~COptionInlet() override {}; - string SetValue(vector option_value) override { + string SetValue(const vector& option_value) override { COptionBase::SetValue(option_value); unsigned short totalVals = option_value.size(); if ((totalVals == 1) && (option_value[0].compare("NONE") == 0)) { @@ -1018,23 +1032,23 @@ public: this->marker[i].assign(option_value[6*i]); istringstream ss_1st(option_value[6*i + 1]); if (!(ss_1st >> this->ttotal[i])) { - return badValue(option_value, "inlet", this->name); + return badValue("inlet", this->name); } istringstream ss_2nd(option_value[6*i + 2]); if (!(ss_2nd >> this->ptotal[i])) { - return badValue(option_value, "inlet", this->name); + return badValue("inlet", this->name); } istringstream ss_3rd(option_value[6*i + 3]); if (!(ss_3rd >> this->flowdir[i][0])) { - return badValue(option_value, "inlet", this->name); + return badValue("inlet", this->name); } istringstream ss_4th(option_value[6*i + 4]); if (!(ss_4th >> this->flowdir[i][1])) { - return badValue(option_value, "inlet", this->name); + return badValue("inlet", this->name); } istringstream ss_5th(option_value[6*i + 5]); if (!(ss_5th >> this->flowdir[i][2])) { - return badValue(option_value, "inlet", this->name); + return badValue("inlet", this->name); } } @@ -1084,7 +1098,7 @@ public: name(name_), size(size_), strings(strings_), values(values_), num_vals(optional_num_vals) { } - string SetValue(vector option_value) override { + string SetValue(const vector& option_value) override { COptionBase::SetValue(option_value); unsigned short option_size = option_value.size(); if ((option_size == 1) && (option_value[0].compare("NONE") == 0)) { @@ -1131,7 +1145,7 @@ public: istringstream ss_nd(*option_it); ++option_it; if (!(ss_nd >> CStringValuesListHelper::access(values[i], j))) { - return badValue(option_value, "\"string + values\"", name); + return badValue("\"string + values\"", name); } } } @@ -1166,7 +1180,7 @@ public: } ~COptionRiemann() override {}; - string SetValue(vector option_value) override { + string SetValue(const vector& option_value) override { COptionBase::SetValue(option_value); unsigned short totalVals = option_value.size(); if ((totalVals == 1) && (option_value[0].compare("NONE") == 0)) { @@ -1220,23 +1234,23 @@ public: istringstream ss_1st(option_value[7*i + 2]); if (!(ss_1st >> this->var1[i])) { - return badValue(option_value, "Riemann", this->name); + return badValue("Riemann", this->name); } istringstream ss_2nd(option_value[7*i + 3]); if (!(ss_2nd >> this->var2[i])) { - return badValue(option_value, "Riemann", this->name); + return badValue("Riemann", this->name); } istringstream ss_3rd(option_value[7*i + 4]); if (!(ss_3rd >> this->flowdir[i][0])) { - return badValue(option_value, "Riemann", this->name); + return badValue("Riemann", this->name); } istringstream ss_4th(option_value[7*i + 5]); if (!(ss_4th >> this->flowdir[i][1])) { - return badValue(option_value, "Riemann", this->name); + return badValue("Riemann", this->name); } istringstream ss_5th(option_value[7*i + 6]); if (!(ss_5th >> this->flowdir[i][2])) { - return badValue(option_value, "Riemann", this->name); + return badValue("Riemann", this->name); } } @@ -1274,7 +1288,7 @@ public: } ~COptionGiles() override {}; - string SetValue(vector option_value) override { + string SetValue(const vector& option_value) override { COptionBase::SetValue(option_value); unsigned long totalVals = option_value.size(); if ((totalVals == 1) && (option_value[0].compare("NONE") == 0)) { @@ -1334,31 +1348,31 @@ public: istringstream ss_1st(option_value[9*i + 2]); if (!(ss_1st >> this->var1[i])) { - return badValue(option_value, "Giles BC", this->name); + return badValue("Giles BC", this->name); } istringstream ss_2nd(option_value[9*i + 3]); if (!(ss_2nd >> this->var2[i])) { - return badValue(option_value, "Giles BC", this->name); + return badValue("Giles BC", this->name); } istringstream ss_3rd(option_value[9*i + 4]); if (!(ss_3rd >> this->flowdir[i][0])) { - return badValue(option_value, "Giles BC", this->name); + return badValue("Giles BC", this->name); } istringstream ss_4th(option_value[9*i + 5]); if (!(ss_4th >> this->flowdir[i][1])) { - return badValue(option_value, "Giles BC", this->name); + return badValue("Giles BC", this->name); } istringstream ss_5th(option_value[9*i + 6]); if (!(ss_5th >> this->flowdir[i][2])) { - return badValue(option_value, "Giles BC", this->name); + return badValue("Giles BC", this->name); } istringstream ss_6th(option_value[9*i + 7]); if (!(ss_6th >> this->relfac1[i])) { - return badValue(option_value, "Giles BC", this->name); + return badValue("Giles BC", this->name); } istringstream ss_7th(option_value[9*i + 8]); if (!(ss_7th >> this->relfac2[i])) { - return badValue(option_value, "Giles BC", this->name); + return badValue("Giles BC", this->name); } } @@ -1391,7 +1405,7 @@ public: ~COptionExhaust() override {}; - string SetValue(vector option_value) override { + string SetValue(const vector& option_value) override { COptionBase::SetValue(option_value); unsigned short totalVals = option_value.size(); if ((totalVals == 1) && (option_value[0].compare("NONE") == 0)) { @@ -1423,10 +1437,10 @@ public: this->marker[i].assign(option_value[3*i]); istringstream ss_1st(option_value[3*i + 1]); if (!(ss_1st >> this->ttotal[i])) - return badValue(option_value, "exhaust fixed", this->name); + return badValue("exhaust fixed", this->name); istringstream ss_2nd(option_value[3*i + 2]); if (!(ss_2nd >> this->ptotal[i])) - return badValue(option_value, "exhaust fixed", this->name); + return badValue("exhaust fixed", this->name); } return ""; @@ -1458,7 +1472,7 @@ public: } ~COptionPeriodic() override {}; - string SetValue(vector option_value) override { + string SetValue(const vector& option_value) override { COptionBase::SetValue(option_value); const int mod_num = 11; @@ -1506,39 +1520,39 @@ public: this->marker_donor[i].assign(option_value[mod_num*i+1]); istringstream ss_1st(option_value[mod_num*i + 2]); if (!(ss_1st >> this->rot_center[i][0])) { - return badValue(option_value, "periodic", this->name); + return badValue("periodic", this->name); } istringstream ss_2nd(option_value[mod_num*i + 3]); if (!(ss_2nd >> this->rot_center[i][1])) { - return badValue(option_value, "periodic", this->name); + return badValue("periodic", this->name); } istringstream ss_3rd(option_value[mod_num*i + 4]); if (!(ss_3rd >> this->rot_center[i][2])) { - return badValue(option_value, "periodic", this->name); + return badValue("periodic", this->name); } istringstream ss_4th(option_value[mod_num*i + 5]); if (!(ss_4th >> this->rot_angles[i][0])) { - return badValue(option_value, "periodic", this->name); + return badValue("periodic", this->name); } istringstream ss_5th(option_value[mod_num*i + 6]); if (!(ss_5th >> this->rot_angles[i][1])) { - return badValue(option_value, "periodic", this->name); + return badValue("periodic", this->name); } istringstream ss_6th(option_value[mod_num*i + 7]); if (!(ss_6th >> this->rot_angles[i][2])) { - return badValue(option_value, "periodic", this->name); + return badValue("periodic", this->name); } istringstream ss_7th(option_value[mod_num*i + 8]); if (!(ss_7th >> this->translation[i][0])) { - return badValue(option_value, "periodic", this->name); + return badValue("periodic", this->name); } istringstream ss_8th(option_value[mod_num*i + 9]); if (!(ss_8th >> this->translation[i][1])) { - return badValue(option_value, "periodic", this->name); + return badValue("periodic", this->name); } istringstream ss_9th(option_value[mod_num*i + 10]); if (!(ss_9th >> this->translation[i][2])) { - return badValue(option_value, "periodic", this->name); + return badValue("periodic", this->name); } this->rot_angles[i][0] *= deg2rad; this->rot_angles[i][1] *= deg2rad; @@ -1550,39 +1564,39 @@ public: this->marker_donor[i].assign(option_value[mod_num*(i-nVals/2)]); istringstream ss_1st(option_value[mod_num*(i-nVals/2) + 2]); if (!(ss_1st >> this->rot_center[i][0])) { - return badValue(option_value, "periodic", this->name); + return badValue("periodic", this->name); } istringstream ss_2nd(option_value[mod_num*(i-nVals/2) + 3]); if (!(ss_2nd >> this->rot_center[i][1])) { - return badValue(option_value, "periodic", this->name); + return badValue("periodic", this->name); } istringstream ss_3rd(option_value[mod_num*(i-nVals/2) + 4]); if (!(ss_3rd >> this->rot_center[i][2])) { - return badValue(option_value, "periodic", this->name); + return badValue("periodic", this->name); } istringstream ss_4th(option_value[mod_num*(i-nVals/2) + 5]); if (!(ss_4th >> this->rot_angles[i][0])) { - return badValue(option_value, "periodic", this->name); + return badValue("periodic", this->name); } istringstream ss_5th(option_value[mod_num*(i-nVals/2) + 6]); if (!(ss_5th >> this->rot_angles[i][1])) { - return badValue(option_value, "periodic", this->name); + return badValue("periodic", this->name); } istringstream ss_6th(option_value[mod_num*(i-nVals/2) + 7]); if (!(ss_6th >> this->rot_angles[i][2])) { - return badValue(option_value, "periodic", this->name); + return badValue("periodic", this->name); } istringstream ss_7th(option_value[mod_num*(i-nVals/2) + 8]); if (!(ss_7th >> this->translation[i][0])) { - return badValue(option_value, "periodic", this->name); + return badValue("periodic", this->name); } istringstream ss_8th(option_value[mod_num*(i-nVals/2) + 9]); if (!(ss_8th >> this->translation[i][1])) { - return badValue(option_value, "periodic", this->name); + return badValue("periodic", this->name); } istringstream ss_9th(option_value[mod_num*(i-nVals/2) + 10]); if (!(ss_9th >> this->translation[i][2])) { - return badValue(option_value, "periodic", this->name); + return badValue("periodic", this->name); } /*--- Mirror the rotational angles and translation vector (rotational center does not need to move) ---*/ @@ -1623,7 +1637,7 @@ public: } ~COptionTurboPerformance() override {}; - string SetValue(vector option_value) override { + string SetValue(const vector& option_value) override { COptionBase::SetValue(option_value); const int mod_num = 2; @@ -1673,7 +1687,7 @@ public: } ~COptionPython() override {}; // No checking happens with python options - string SetValue(vector option_value) override { + string SetValue(const vector& option_value) override { COptionBase::SetValue(option_value); return ""; } @@ -1703,7 +1717,7 @@ public: } ~COptionActDisk() override {}; - string SetValue(vector option_value) override { + string SetValue(const vector& option_value) override { COptionBase::SetValue(option_value); const int mod_num = 8; unsigned short totalVals = option_value.size(); @@ -1742,27 +1756,27 @@ public: this->marker_outlet[i].assign(option_value[mod_num*i+1]); istringstream ss_1st(option_value[mod_num*i + 2]); if (!(ss_1st >> this->press_jump[i][0])) { - return badValue(option_value, tname, this->name); + return badValue(tname, this->name); } istringstream ss_2nd(option_value[mod_num*i + 3]); if (!(ss_2nd >> this->temp_jump[i][0])) { - return badValue(option_value, tname, this->name); + return badValue(tname, this->name); } istringstream ss_3rd(option_value[mod_num*i + 4]); if (!(ss_3rd >> this->omega[i][0])) { - return badValue(option_value, tname, this->name); + return badValue(tname, this->name); } istringstream ss_4th(option_value[mod_num*i + 5]); if (!(ss_4th >> this->press_jump[i][1])) { - return badValue(option_value, tname, this->name); + return badValue(tname, this->name); } istringstream ss_5th(option_value[mod_num*i + 6]); if (!(ss_5th >> this->temp_jump[i][1])) { - return badValue(option_value, tname, this->name); + return badValue(tname, this->name); } istringstream ss_6th(option_value[mod_num*i + 7]); if (!(ss_6th >> this->omega[i][1])) { - return badValue(option_value, tname, this->name); + return badValue(tname, this->name); } } return ""; @@ -1797,7 +1811,7 @@ public: ~COptionWallFunction() override{} - string SetValue(vector option_value) override { + string SetValue(const vector& option_value) override { COptionBase::SetValue(option_value); /*--- First check if NONE is specified. ---*/ unsigned short totalSize = option_value.size(); @@ -1909,17 +1923,17 @@ public: istringstream ss_1st(option_value[counter++]); if (!(ss_1st >> this->doubleInfo[i][0])) { - return badValue(option_value, "su2double", this->name); + return badValue("su2double", this->name); } istringstream ss_2nd(option_value[counter++]); if (!(ss_2nd >> this->doubleInfo[i][1])) { - return badValue(option_value, "su2double", this->name); + return badValue("su2double", this->name); } istringstream ss_3rd(option_value[counter++]); if (!(ss_3rd >> this->intInfo[i][0])) { - return badValue(option_value, "unsigned short", this->name); + return badValue("unsigned short", this->name); } break; @@ -1951,7 +1965,7 @@ public: /* Extract the exchange distance. */ istringstream ss_1st(option_value[counter++]); if (!(ss_1st >> this->doubleInfo[i][0])) { - return badValue(option_value, "su2double", this->name); + return badValue("su2double", this->name); } break; @@ -1965,17 +1979,17 @@ public: istringstream ss_1st(option_value[counter++]); if (!(ss_1st >> this->doubleInfo[i][0])) { - return badValue(option_value, "su2double", this->name); + return badValue("su2double", this->name); } istringstream ss_2nd(option_value[counter++]); if (!(ss_2nd >> this->doubleInfo[i][1])) { - return badValue(option_value, "su2double", this->name); + return badValue("su2double", this->name); } istringstream ss_3rd(option_value[counter++]); if (!(ss_3rd >> this->intInfo[i][0])) { - return badValue(option_value, "unsigned short", this->name); + return badValue("unsigned short", this->name); } break; diff --git a/Common/src/CConfig.cpp b/Common/src/CConfig.cpp index 3e4026ae742..a3b37d65ee2 100644 --- a/Common/src/CConfig.cpp +++ b/Common/src/CConfig.cpp @@ -1925,10 +1925,12 @@ void CConfig::SetConfig_Options() { /*!\brief OBJECTIVE_WEIGHT \n DESCRIPTION: Adjoint problem boundary condition weights. Applies scaling factor to objective(s) \ingroup Config*/ addDoubleListOption("OBJECTIVE_WEIGHT", nObjW, Weight_ObjFunc); - /*!\brief OBJECTIVE_FUNCTION - * \n DESCRIPTION: Adjoint problem boundary condition \n OPTIONS: see \link Objective_Map \endlink \n DEFAULT: DRAG_COEFFICIENT \ingroup Config*/ + /*!\brief OBJECTIVE_FUNCTION \n DESCRIPTION: Adjoint problem boundary condition \n OPTIONS: see \link Objective_Map \endlink \n DEFAULT: DRAG_COEFFICIENT \ingroup Config*/ addEnumListOption("OBJECTIVE_FUNCTION", nObj, Kind_ObjFunc, Objective_Map); + /*!\brief CUSTOM_OBJFUNC \n DESCRIPTION: User-provided definition of a custom objective function. \ingroup Config*/ + addStringOption("CUSTOM_OBJFUNC", CustomObjFunc, ""); + /* DESCRIPTION: parameter for the definition of a complex objective function */ addDoubleOption("DCD_DCL_VALUE", dCD_dCL, 0.0); /* DESCRIPTION: parameter for the definition of a complex objective function */ @@ -3466,10 +3468,10 @@ void CConfig::SetPostprocessing(SU2_COMPONENT val_software, unsigned short val_i nObjW = nObj; } else if(nObj>1) { - SU2_MPI::Error(string("When using more than one OBJECTIVE_FUNCTION, MARKER_MONITORING must be the same length or length 1.\n ") + - string("For multiple surfaces per objective, either use one objective or list the objective multiple times.\n") + - string("For multiple objectives per marker either use one marker or list the marker multiple times.\n")+ - string("Similar rules apply for multi-objective optimization using OPT_OBJECTIVE rather than OBJECTIVE_FUNCTION."), + SU2_MPI::Error("When using more than one OBJECTIVE_FUNCTION, MARKER_MONITORING must be the same length or length 1.\n" + "For multiple surfaces per objective, either use one objective or list the objective multiple times.\n" + "For multiple objectives per marker either use one marker or list the marker multiple times.\n" + "Similar rules apply for multi-objective optimization using OPT_OBJECTIVE rather than OBJECTIVE_FUNCTION.", CURRENT_FUNCTION); } } @@ -3479,8 +3481,8 @@ void CConfig::SetPostprocessing(SU2_COMPONENT val_software, unsigned short val_i if (nObjW1) { - SU2_MPI::Error(string("The option OBJECTIVE_WEIGHT must either have the same length as OBJECTIVE_FUNCTION,\n") + - string("be lenght 1, or be deleted from the config file (equal weights will be applied)."), CURRENT_FUNCTION); + SU2_MPI::Error("The option OBJECTIVE_WEIGHT must either have the same length as OBJECTIVE_FUNCTION,\n" + "be lenght 1, or be deleted from the config file (equal weights will be applied).", CURRENT_FUNCTION); } Weight_ObjFunc = new su2double[nObj]; for (unsigned short iObj=0; iObj @@ -8203,15 +8217,8 @@ string CConfig::GetObjFunc_Extension(string val_filename) const { case SURFACE_SPECIES_VARIANCE: AdjExt = "_specvar"; break; case SURFACE_MACH: AdjExt = "_mach"; break; case CUSTOM_OBJFUNC: AdjExt = "_custom"; break; - case KINETIC_ENERGY_LOSS: AdjExt = "_ke"; break; - case TOTAL_PRESSURE_LOSS: AdjExt = "_pl"; break; case FLOW_ANGLE_OUT: AdjExt = "_fao"; break; - case FLOW_ANGLE_IN: AdjExt = "_fai"; break; - case TOTAL_EFFICIENCY: AdjExt = "_teff"; break; - case TOTAL_STATIC_EFFICIENCY: AdjExt = "_tseff"; break; - case EULERIAN_WORK: AdjExt = "_ew"; break; case MASS_FLOW_IN: AdjExt = "_mfi"; break; - case MASS_FLOW_OUT: AdjExt = "_mfo"; break; case ENTROPY_GENERATION: AdjExt = "_entg"; break; case REFERENCE_GEOMETRY: AdjExt = "_refgeom"; break; case REFERENCE_NODE: AdjExt = "_refnode"; break; diff --git a/SU2_CFD/include/output/CElasticityOutput.hpp b/SU2_CFD/include/output/CElasticityOutput.hpp index 0cc787b5ba6..fb3975e9277 100644 --- a/SU2_CFD/include/output/CElasticityOutput.hpp +++ b/SU2_CFD/include/output/CElasticityOutput.hpp @@ -50,11 +50,6 @@ class CElasticityOutput final: public COutput { */ CElasticityOutput(CConfig *config, unsigned short nDim); - /*! - * \brief Destructor of the class. - */ - ~CElasticityOutput(void) override; - /*! * \brief Load the history output field values * \param[in] config - Definition of the particular problem. diff --git a/SU2_CFD/include/output/CHeatOutput.hpp b/SU2_CFD/include/output/CHeatOutput.hpp index 41e72382717..a5a9d22b3fd 100644 --- a/SU2_CFD/include/output/CHeatOutput.hpp +++ b/SU2_CFD/include/output/CHeatOutput.hpp @@ -44,11 +44,6 @@ class CHeatOutput final: public CFVMOutput { */ CHeatOutput(CConfig *config, unsigned short nDim); - /*! - * \brief Destructor of the class. - */ - ~CHeatOutput(void) override; - /*! * \brief Set the available history output fields * \param[in] config - Definition of the particular problem. diff --git a/SU2_CFD/include/output/CMultizoneOutput.hpp b/SU2_CFD/include/output/CMultizoneOutput.hpp index b29ca8d853b..8a852d3dc12 100644 --- a/SU2_CFD/include/output/CMultizoneOutput.hpp +++ b/SU2_CFD/include/output/CMultizoneOutput.hpp @@ -66,16 +66,14 @@ class CMultizoneOutput final: public COutput { /*! * \brief Load the multizone history output field values * \param[in] output - Container holding the output instances per zone. - * \param[in] config - Definition of the particular problem. */ - void LoadMultizoneHistoryData(COutput **output, CConfig **config) override; + void LoadMultizoneHistoryData(const COutput* const* output) override; /*! * \brief Set the available multizone history output fields * \param[in] output - Container holding the output instances per zone. - * \param[in] config - Definition of the particular problem per zone. */ - void SetMultizoneHistoryOutputFields(COutput **output, CConfig **config) override; + void SetMultizoneHistoryOutputFields(const COutput* const* output) override; /*! * \brief Determines if the history file output. diff --git a/SU2_CFD/include/output/COutput.hpp b/SU2_CFD/include/output/COutput.hpp index 3a92c2e3397..6ce459df7ee 100644 --- a/SU2_CFD/include/output/COutput.hpp +++ b/SU2_CFD/include/output/COutput.hpp @@ -39,6 +39,16 @@ #include "tools/CWindowingTools.hpp" #include "../../../Common/include/option_structure.hpp" +/*--- AD workaround for a cmath function not defined in CoDi. ---*/ +namespace mel { +namespace internal { +inline su2double hypot(const su2double& a, const su2double& b) { + return sqrt(a*a + b*b); +} +} +} +#include "mel.hpp" + class CGeometry; class CSolver; class CFileWriter; @@ -159,6 +169,20 @@ class COutput { //! Structure to store the value initial residuals for relative residual computation std::map initialResiduals; + /** \brief Struct to hold a parsed user-defined expression. */ + struct CustomHistoryOutput { + mel::ExpressionTree expression; + /*--- Pointers to values in the history output maps, to avoid key lookup every time. ---*/ + std::vector symbolValues; + bool ready = false; + + su2double eval() const { + return mel::Eval(expression, [&](int i) {return *symbolValues[i];}); + } + }; + + CustomHistoryOutput customObjFunc; /*!< \brief User-defined expression for a custom objective. */ + /*----------------------------- Volume output ----------------------------*/ CParallelDataSorter* volumeDataSorter; //!< Volume data sorter @@ -371,11 +395,11 @@ class COutput { * \param[in] field - Name of the field * \return Value of the field */ - su2double GetHistoryFieldValue(string field){ + su2double GetHistoryFieldValue(const string& field) const { return historyOutput_Map.at(field).value; } - su2double GetHistoryFieldValuePerSurface(string field, unsigned short iMarker){ + su2double GetHistoryFieldValuePerSurface(const string& field, unsigned short iMarker) const { return historyOutputPerSurface_Map.at(field)[iMarker].value; } @@ -398,7 +422,7 @@ class COutput { * \brief Get the list of all output fields * \return Vector container all output fields */ - vector GetHistoryOutput_List(){ + const vector& GetHistoryOutput_List() const { return historyOutput_List; } @@ -406,7 +430,7 @@ class COutput { * \brief Get the map containing all output fields * \return Map containing all output fields */ - map GetHistoryFields(){ + const map& GetHistoryFields() const { return historyOutput_Map; } @@ -447,7 +471,7 @@ class COutput { /*! * \brief Print a list of all history output fields to screen. */ - void PrintHistoryFields(); + void PrintHistoryFields() const; /*! * \brief Print a list of all volume output fields to screen. @@ -580,6 +604,13 @@ class COutput { } } + /*! + * \brief Setup a custom history output object for a given expression. + * \param[in] expression - Some user-defined math with the history field names as variables. + * \param[out] output - Custom output ready to evaluate. + */ + void SetupCustomHistoryOutput(const string& expression, CustomHistoryOutput& output) const; + /*! * \brief Add a new field to the volume output. * \param[in] name - Name for referencing it (in the config file and in the code). @@ -683,6 +714,15 @@ class COutput { */ void AllocateDataSorters(CConfig *config, CGeometry *geometry); + /*! + * \brief Computes the custom and combo objectives. + * \note To be called after all other history outputs are set. + * \param[in] idxSol - Index of the main solver. + * \param[in] config - Definition of the particular problem. + * \param[in] solver - The container holding all solution data. + */ + void SetCustomAndComboObjectives(int idxSol, const CConfig *config, CSolver **solver); + /*--------------------------------- Virtual functions ---------------------------------------- */ public: @@ -775,9 +815,8 @@ class COutput { /*! * \brief Load the multizone history output field values * \param[in] output - Container holding the output instances per zone. - * \param[in] config - Definition of the particular problem. */ - inline virtual void LoadMultizoneHistoryData(COutput **output, CConfig **config) {} + inline virtual void LoadMultizoneHistoryData(const COutput* const* output) {} /*! * \brief Set the available history output fields @@ -788,9 +827,8 @@ class COutput { /*! * \brief Set the available multizone history output fields * \param[in] output - Container holding the output instances per zone. - * \param[in] config - Definition of the particular problem per zone. */ - inline virtual void SetMultizoneHistoryOutputFields(COutput **output, CConfig **config) {} + inline virtual void SetMultizoneHistoryOutputFields(const COutput* const* output) {} /*! * \brief Write any additional files defined for the current solver. diff --git a/SU2_CFD/include/solvers/CEulerSolver.hpp b/SU2_CFD/include/solvers/CEulerSolver.hpp index 03a95e3de73..fd6eea62de1 100644 --- a/SU2_CFD/include/solvers/CEulerSolver.hpp +++ b/SU2_CFD/include/solvers/CEulerSolver.hpp @@ -434,8 +434,9 @@ class CEulerSolver : public CFVMFlowSolverBaseGetKind_ObjFunc()) { case REFERENCE_GEOMETRY: - ObjFunc = GetTotal_OFRefGeom(); + Total_ComboObj = GetTotal_OFRefGeom(); break; case REFERENCE_NODE: - ObjFunc = GetTotal_OFRefNode(); + Total_ComboObj = GetTotal_OFRefNode(); break; case TOPOL_COMPLIANCE: - ObjFunc = GetTotal_OFCompliance(); + Total_ComboObj = GetTotal_OFCompliance(); break; case VOLUME_FRACTION: - ObjFunc = GetTotal_OFVolFrac(); + Total_ComboObj = GetTotal_OFVolFrac(); break; case TOPOL_DISCRETENESS: - ObjFunc = GetTotal_OFDiscreteness(); + Total_ComboObj = GetTotal_OFDiscreteness(); break; case STRESS_PENALTY: - ObjFunc = GetTotal_OFStressPenalty(); + Total_ComboObj = GetTotal_OFStressPenalty(); + break; + case CUSTOM_OBJFUNC: + Total_ComboObj = Total_Custom_ObjFunc; break; } } - /*! - * \brief Provide the total "combo" objective (weighted sum of other values). - */ - inline su2double GetTotal_ComboObj() const final { return ObjFunc; } - /*! * \brief Determines whether there is an element-based file or not. * \return Bool that defines whether the solution has an element-based file or not diff --git a/SU2_CFD/include/solvers/CFVMFlowSolverBase.hpp b/SU2_CFD/include/solvers/CFVMFlowSolverBase.hpp index 031dde9c64e..5923515e5c1 100644 --- a/SU2_CFD/include/solvers/CFVMFlowSolverBase.hpp +++ b/SU2_CFD/include/solvers/CFVMFlowSolverBase.hpp @@ -152,9 +152,6 @@ class CFVMFlowSolverBase : public CSolver { su2double AeroCoeffForceRef = 1.0; /*!< \brief Reference force for aerodynamic coefficients. */ su2double DynamicPressureRef = 1.0; /*!< \brief Reference dynamic pressure. */ - su2double InverseDesign = 0.0; /*!< \brief Inverse design functional for each boundary. */ - su2double Total_ComboObj = 0.0; /*!< \brief Total 'combo' objective for all monitored boundaries */ - su2double Total_Custom_ObjFunc = 0.0; /*!< \brief Total custom objective function for all the boundaries. */ su2double Total_CpDiff = 0.0; /*!< \brief Total Equivalent Area coefficient for all the boundaries. */ su2double Total_HeatFluxDiff = 0.0; /*!< \brief Total Equivalent Area coefficient for all the boundaries. */ su2double Total_CEquivArea = 0.0; /*!< \brief Total Equivalent Area coefficient for all the boundaries. */ @@ -1995,20 +1992,6 @@ class CFVMFlowSolverBase : public CSolver { */ inline void SetTotal_CNearFieldOF(su2double val_cnearfieldpress) final { Total_CNearFieldOF = val_cnearfieldpress; } - /*! - * \author H. Kline - * \brief Set the total "combo" objective (weighted sum of other values). - * \param[in] ComboObj - Value of the combined objective. - */ - inline void SetTotal_ComboObj(su2double ComboObj) final { Total_ComboObj = ComboObj; } - - /*! - * \author H. Kline - * \brief Provide the total "combo" objective (weighted sum of other values). - * \return Value of the "combo" objective values. - */ - inline su2double GetTotal_ComboObj() const final { return Total_ComboObj; } - /*! * \brief Provide the total (inviscid + viscous) non dimensional Equivalent Area coefficient. * \return Value of the Equivalent Area coefficient (inviscid + viscous contribution). @@ -2027,24 +2010,6 @@ class CFVMFlowSolverBase : public CSolver { */ inline su2double GetTotal_CEquivArea() const final { return Total_CEquivArea; } - /*! - * \brief Set the value of the custom objective function. - * \param[in] val_Total_Custom_ObjFunc - Value of the total custom objective function. - * \param[in] val_weight - Value of the weight for the custom objective function. - */ - inline void SetTotal_Custom_ObjFunc(su2double val_total_custom_objfunc, su2double val_weight) final { - Total_Custom_ObjFunc = val_total_custom_objfunc * val_weight; - } - - /*! - * \brief Add the value of the custom objective function. - * \param[in] val_Total_Custom_ObjFunc - Value of the total custom objective function. - * \param[in] val_weight - Value of the weight for the custom objective function. - */ - inline void AddTotal_Custom_ObjFunc(su2double val_total_custom_objfunc, su2double val_weight) final { - Total_Custom_ObjFunc += val_total_custom_objfunc * val_weight; - } - /*! * \brief Provide the total heat load. * \return Value of the heat load (viscous contribution). @@ -2069,12 +2034,6 @@ class CFVMFlowSolverBase : public CSolver { */ inline void SetTotal_MaxHeatFlux(su2double val_Total_MaxHeat) final { Total_MaxHeat = val_Total_MaxHeat; } - /*! - * \brief Provide the total custom objective function. - * \return Value of the custom objective function. - */ - inline su2double GetTotal_Custom_ObjFunc() const final { return Total_Custom_ObjFunc; } - /*! * \brief Provide the Pressure coefficient. * \param[in] val_marker - Surface marker where the coefficient is computed. diff --git a/SU2_CFD/include/solvers/CHeatSolver.hpp b/SU2_CFD/include/solvers/CHeatSolver.hpp index 05918861ccd..7d8b7ef2e33 100644 --- a/SU2_CFD/include/solvers/CHeatSolver.hpp +++ b/SU2_CFD/include/solvers/CHeatSolver.hpp @@ -307,6 +307,27 @@ class CHeatSolver final : public CSolver { */ inline su2double GetTotal_AvgTemperature() const override { return Total_AverageT; } + /*! + * \brief Compute objective output + * \param[in] config - Definition of the problem. + * \param[in] solver - Container vector with all the solutions. + */ + void Evaluate_ObjFunc(const CConfig *config, CSolver**) override { + switch (config->GetKind_ObjFunc()) { + case TOTAL_HEATFLUX: + Total_ComboObj = Total_HeatFlux; + break; + case AVG_TEMPERATURE: + Total_ComboObj = Total_AverageT; + break; + case CUSTOM_OBJFUNC: + Total_ComboObj = Total_Custom_ObjFunc; + break; + default: + Total_ComboObj = 0.0; + } + } + /*! * \brief Update the solution using an implicit solver. * \param[in] geometry - Geometrical definition of the problem. diff --git a/SU2_CFD/include/solvers/CIncEulerSolver.hpp b/SU2_CFD/include/solvers/CIncEulerSolver.hpp index c37cc182452..d654b483727 100644 --- a/SU2_CFD/include/solvers/CIncEulerSolver.hpp +++ b/SU2_CFD/include/solvers/CIncEulerSolver.hpp @@ -240,9 +240,15 @@ class CIncEulerSolver : public CFVMFlowSolverBaseGetWeakly_Coupled_Heat()) { + solver[HEAT_SOL]->Evaluate_ObjFunc(config, solver); + Total_ComboObj += solver[HEAT_SOL]->GetTotal_ComboObj(); + } } /*! diff --git a/SU2_CFD/include/solvers/CNSSolver.hpp b/SU2_CFD/include/solvers/CNSSolver.hpp index 9ccdf42d331..4aac93e9112 100644 --- a/SU2_CFD/include/solvers/CNSSolver.hpp +++ b/SU2_CFD/include/solvers/CNSSolver.hpp @@ -174,8 +174,9 @@ class CNSSolver final : public CEulerSolver { /*! * \brief Compute weighted-sum "combo" objective output * \param[in] config - Definition of the particular problem. + * \param[in] solver - Container vector with all the solutions. */ - void Evaluate_ObjFunc(const CConfig *config) override; + void Evaluate_ObjFunc(const CConfig *config, CSolver **solver) override; /*! * \brief Impose a constant heat-flux condition at the wall. diff --git a/SU2_CFD/include/solvers/CSolver.hpp b/SU2_CFD/include/solvers/CSolver.hpp index 729c15d6027..bcd401347fc 100644 --- a/SU2_CFD/include/solvers/CSolver.hpp +++ b/SU2_CFD/include/solvers/CSolver.hpp @@ -99,6 +99,9 @@ class CSolver { su2activematrix Point_Max_Coord; /*!< \brief Vector with pointers to the coords of the maximal residual for each variable. */ su2activematrix Point_Max_Coord_BGS; /*!< \brief Vector with pointers to the coords of the maximal residual for each variable. */ + su2double Total_Custom_ObjFunc = 0.0; /*!< \brief Total custom objective function. */ + su2double Total_ComboObj = 0.0; /*!< \brief Total 'combo' objective for all monitored boundaries */ + /*--- Variables that need to go. ---*/ su2double *Residual, /*!< \brief Auxiliary nVar vector. */ @@ -760,8 +763,9 @@ class CSolver { * \author H. Kline * \brief Compute weighted-sum "combo" objective output * \param[in] config - Definition of the particular problem. + * \param[in] solver - Container vector with all the solutions. */ - inline virtual void Evaluate_ObjFunc(const CConfig *config) {}; + inline virtual void Evaluate_ObjFunc(const CConfig *config, CSolver **solver) {}; /*! * \brief A virtual member. @@ -1684,20 +1688,6 @@ class CSolver { */ inline virtual void SetTotal_DC60(su2double val_Total_DC60) { } - /*! - * \brief A virtual member. - * \param[in] val_Total_Custom_ObjFunc - Value of the total custom objective function. - * \param[in] val_weight - Value of the weight for the custom objective function. - */ - inline virtual void SetTotal_Custom_ObjFunc(su2double val_total_custom_objfunc, su2double val_weight) { } - - /*! - * \brief A virtual member. - * \param[in] val_Total_Custom_ObjFunc - Value of the total custom objective function. - * \param[in] val_weight - Value of the weight for the custom objective function. - */ - inline virtual void AddTotal_Custom_ObjFunc(su2double val_total_custom_objfunc, su2double val_weight) { } - /*! * \brief A virtual member. * \param[in] val_Total_CT - Value of the total thrust coefficient. @@ -1758,6 +1748,19 @@ class CSolver { CNumerics *numerics, CConfig *config) { } + /*! + * \author H. Kline + * \brief Provide the total "combo" objective (weighted sum of other values). + * \return Value of the "combo" objective values. + */ + inline su2double GetTotal_ComboObj() const { return Total_ComboObj; } + + /*! + * \brief Sets the value of the custom objective function. + * \param[in] value - Value of the total custom objective function. + */ + inline void SetTotal_Custom_ObjFunc(su2double value) { Total_Custom_ObjFunc = value; } + /*! * \brief A virtual member. * \param[in] val_marker - Surface marker where the coefficient is computed. @@ -2174,20 +2177,6 @@ class CSolver { */ inline virtual su2double GetCD_Visc(unsigned short val_marker) const { return 0; } - /*! - * \author H. Kline - * \brief Set the total "combo" objective (weighted sum of other values). - * \param[in] ComboObj - Value of the combined objective. - */ - inline virtual void SetTotal_ComboObj(su2double ComboObj) {} - - /*! - * \author H. Kline - * \brief Provide the total "combo" objective (weighted sum of other values). - * \return Value of the "combo" objective values. - */ - inline virtual su2double GetTotal_ComboObj(void) const { return 0;} - /*! * \brief A virtual member. * \return Value of the sideforce coefficient (inviscid + viscous contribution). @@ -2272,13 +2261,6 @@ class CSolver { */ inline virtual su2double GetTotal_CNearFieldOF() const { return 0; } - /*! - * \author H. Kline - * \brief Add to the value of the total 'combo' objective. - * \param[in] val_obj - Value of the contribution to the 'combo' objective. - */ - inline virtual void AddTotal_ComboObj(su2double val_obj) {} - /*! * \brief A virtual member. * \return Value of the objective function for a reference geometry. @@ -2463,12 +2445,6 @@ class CSolver { */ inline virtual su2double GetTotal_DC60() const { return 0; } - /*! - * \brief A virtual member. - * \return Value of the custom objective function. - */ - inline virtual su2double GetTotal_Custom_ObjFunc() const { return 0; } - /*! * \brief A virtual member. * \return Value of the moment x coefficient (inviscid + viscous contribution). diff --git a/SU2_CFD/include/variables/CEulerVariable.hpp b/SU2_CFD/include/variables/CEulerVariable.hpp index 553c25cbe22..b2fafc60134 100644 --- a/SU2_CFD/include/variables/CEulerVariable.hpp +++ b/SU2_CFD/include/variables/CEulerVariable.hpp @@ -27,6 +27,7 @@ #pragma once +#include #include "CFlowVariable.hpp" /*! diff --git a/SU2_CFD/include/variables/CIncEulerVariable.hpp b/SU2_CFD/include/variables/CIncEulerVariable.hpp index abbf33243c3..dd72041ef06 100644 --- a/SU2_CFD/include/variables/CIncEulerVariable.hpp +++ b/SU2_CFD/include/variables/CIncEulerVariable.hpp @@ -27,6 +27,7 @@ #pragma once +#include #include "CFlowVariable.hpp" /*! diff --git a/SU2_CFD/src/drivers/CDiscAdjMultizoneDriver.cpp b/SU2_CFD/src/drivers/CDiscAdjMultizoneDriver.cpp index 5e03e34d476..951083b0fc1 100644 --- a/SU2_CFD/src/drivers/CDiscAdjMultizoneDriver.cpp +++ b/SU2_CFD/src/drivers/CDiscAdjMultizoneDriver.cpp @@ -729,16 +729,19 @@ void CDiscAdjMultizoneDriver::SetObjFunction(RECORDING kind_recording) { } direct_output[iZone]->SetHistory_Output(geometry, solvers, config); - - solvers[FLOW_SOL]->Evaluate_ObjFunc(config); + ObjFunc += solvers[FLOW_SOL]->GetTotal_ComboObj(); break; case MAIN_SOLVER::DISC_ADJ_HEAT: solvers[HEAT_SOL]->Heat_Fluxes(geometry, solvers, config); + direct_output[iZone]->SetHistory_Output(geometry, solvers, config); + ObjFunc += solvers[HEAT_SOL]->GetTotal_ComboObj(); break; case MAIN_SOLVER::DISC_ADJ_FEM: solvers[FEA_SOL]->Postprocessing(geometry, config, numerics_container[iZone][INST_0][MESH_0][FEA_SOL], true); + direct_output[iZone]->SetHistory_Output(geometry, solvers, config); + ObjFunc += solvers[FEA_SOL]->GetTotal_ComboObj(); break; default: @@ -746,56 +749,6 @@ void CDiscAdjMultizoneDriver::SetObjFunction(RECORDING kind_recording) { } } - /*--- Extract objective function values. ---*/ - - for (iZone = 0; iZone < nZone; iZone++) { - - auto config = config_container[iZone]; - auto solvers = solver_container[iZone][INST_0][MESH_0]; - - const auto Weight_ObjFunc = config->GetWeight_ObjFunc(0); - - switch (config->GetKind_Solver()) { - - case MAIN_SOLVER::DISC_ADJ_EULER: case MAIN_SOLVER::DISC_ADJ_NAVIER_STOKES: case MAIN_SOLVER::DISC_ADJ_RANS: - case MAIN_SOLVER::DISC_ADJ_INC_EULER: case MAIN_SOLVER::DISC_ADJ_INC_NAVIER_STOKES: case MAIN_SOLVER::DISC_ADJ_INC_RANS: - { - auto val = solvers[FLOW_SOL]->GetTotal_ComboObj(); - - if (config->GetWeakly_Coupled_Heat()) { - if (config->GetKind_ObjFunc() == TOTAL_HEATFLUX) { - val += solvers[HEAT_SOL]->GetTotal_HeatFlux(); - } - else if (config->GetKind_ObjFunc() == AVG_TEMPERATURE) { - val += solvers[HEAT_SOL]->GetTotal_AvgTemperature(); - } - } - ObjFunc += val*Weight_ObjFunc; - break; - } - case MAIN_SOLVER::DISC_ADJ_HEAT: - { - switch(config->GetKind_ObjFunc()) { - case TOTAL_HEATFLUX: - ObjFunc += solvers[HEAT_SOL]->GetTotal_HeatFlux()*Weight_ObjFunc; - break; - case AVG_TEMPERATURE: - ObjFunc += solvers[HEAT_SOL]->GetTotal_AvgTemperature()*Weight_ObjFunc; - break; - } - break; - } - case MAIN_SOLVER::DISC_ADJ_FEM: - { - solvers[FEA_SOL]->Evaluate_ObjFunc(config); - ObjFunc += solvers[FEA_SOL]->GetTotal_ComboObj()*Weight_ObjFunc; - break; - } - default: - break; - } - } - if (rank == MASTER_NODE) { AD::RegisterOutput(ObjFunc); AD::SetIndex(ObjFunc_Index, ObjFunc); diff --git a/SU2_CFD/src/drivers/CDiscAdjSinglezoneDriver.cpp b/SU2_CFD/src/drivers/CDiscAdjSinglezoneDriver.cpp index b599773da22..0f4a792bbb3 100644 --- a/SU2_CFD/src/drivers/CDiscAdjSinglezoneDriver.cpp +++ b/SU2_CFD/src/drivers/CDiscAdjSinglezoneDriver.cpp @@ -346,16 +346,8 @@ void CDiscAdjSinglezoneDriver::SetAdj_ObjFunction(){ void CDiscAdjSinglezoneDriver::SetObjFunction(){ - bool heat = (config->GetWeakly_Coupled_Heat()); - bool turbo = (config->GetBoolTurbomachinery()); - ObjFunc = 0.0; - direct_output->SetHistory_Output(geometry, solver, config, - config->GetTimeIter(), - config->GetOuterIter(), - config->GetInnerIter()); - /*--- Specific scalar objective functions ---*/ switch (config->GetKind_Solver()) { @@ -363,26 +355,15 @@ void CDiscAdjSinglezoneDriver::SetObjFunction(){ case MAIN_SOLVER::DISC_ADJ_EULER: case MAIN_SOLVER::DISC_ADJ_NAVIER_STOKES: case MAIN_SOLVER::DISC_ADJ_RANS: case MAIN_SOLVER::DISC_ADJ_FEM_EULER: case MAIN_SOLVER::DISC_ADJ_FEM_NS: case MAIN_SOLVER::DISC_ADJ_FEM_RANS: - solver[FLOW_SOL]->SetTotal_ComboObj(0.0); - /*--- Surface based obj. function ---*/ - solver[FLOW_SOL]->Evaluate_ObjFunc(config); + direct_output->SetHistory_Output(geometry, solver, config, config->GetTimeIter(), + config->GetOuterIter(), config->GetInnerIter()); ObjFunc += solver[FLOW_SOL]->GetTotal_ComboObj(); - if (heat){ - if (config->GetKind_ObjFunc() == TOTAL_HEATFLUX) { - ObjFunc += solver[HEAT_SOL]->GetTotal_HeatFlux(); - } - else if (config->GetKind_ObjFunc() == AVG_TEMPERATURE) { - ObjFunc += solver[HEAT_SOL]->GetTotal_AvgTemperature(); - } - } - /*--- This calls to be moved to a generic framework at a next stage ---*/ + /*--- These calls to be moved to a generic framework at a next stage ---*/ /*--- Some things that are currently hacked into output must be reorganized ---*/ - if (turbo){ - - solver[FLOW_SOL]->SetTotal_ComboObj(0.0); + if (config->GetBoolTurbomachinery()) { output_legacy->ComputeTurboPerformance(solver[FLOW_SOL], geometry, config); unsigned short nMarkerTurboPerf = config->GetnMarker_TurboPerformance(); @@ -390,44 +371,36 @@ void CDiscAdjSinglezoneDriver::SetObjFunction(){ switch (config_container[ZONE_0]->GetKind_ObjFunc()){ case ENTROPY_GENERATION: - solver[FLOW_SOL]->AddTotal_ComboObj(output_legacy->GetEntropyGen(nMarkerTurboPerf-1, nSpanSections)); + ObjFunc += output_legacy->GetEntropyGen(nMarkerTurboPerf-1, nSpanSections); break; case FLOW_ANGLE_OUT: - solver[FLOW_SOL]->AddTotal_ComboObj(output_legacy->GetFlowAngleOut(nMarkerTurboPerf-1, nSpanSections)); + ObjFunc += output_legacy->GetFlowAngleOut(nMarkerTurboPerf-1, nSpanSections); break; case MASS_FLOW_IN: - solver[FLOW_SOL]->AddTotal_ComboObj(output_legacy->GetMassFlowIn(nMarkerTurboPerf-1, nSpanSections)); + ObjFunc += output_legacy->GetMassFlowIn(nMarkerTurboPerf-1, nSpanSections); break; default: break; } - - ObjFunc = solver[FLOW_SOL]->GetTotal_ComboObj(); - } break; case MAIN_SOLVER::DISC_ADJ_HEAT: - switch (config->GetKind_ObjFunc()){ - case TOTAL_HEATFLUX: - ObjFunc = solver[HEAT_SOL]->GetTotal_HeatFlux(); - break; - case AVG_TEMPERATURE: - ObjFunc = solver[HEAT_SOL]->GetTotal_AvgTemperature(); - break; - default: - break; - } + direct_output->SetHistory_Output(geometry, solver, config, config->GetTimeIter(), + config->GetOuterIter(), config->GetInnerIter()); + ObjFunc = solver[HEAT_SOL]->GetTotal_ComboObj(); break; case MAIN_SOLVER::DISC_ADJ_FEM: solver[FEA_SOL]->Postprocessing(geometry, config, numerics_container[ZONE_0][INST_0][MESH_0][FEA_SOL], true); - solver[FEA_SOL]->Evaluate_ObjFunc(config); + + direct_output->SetHistory_Output(geometry, solver, config, config->GetTimeIter(), + config->GetOuterIter(), config->GetInnerIter()); ObjFunc = solver[FEA_SOL]->GetTotal_ComboObj(); break; default: - break; + break; } if (rank == MASTER_NODE){ diff --git a/SU2_CFD/src/iteration/CDiscAdjFEAIteration.cpp b/SU2_CFD/src/iteration/CDiscAdjFEAIteration.cpp index 8427fe3a357..42548add832 100644 --- a/SU2_CFD/src/iteration/CDiscAdjFEAIteration.cpp +++ b/SU2_CFD/src/iteration/CDiscAdjFEAIteration.cpp @@ -337,7 +337,7 @@ void CDiscAdjFEAIteration::Postprocess(COutput* output, CIntegration**** integra myfile_res << config[iZone]->GetTimeIter() << "\t"; - solvers0[FEA_SOL]->Evaluate_ObjFunc(config[iZone]); + solvers0[FEA_SOL]->Evaluate_ObjFunc(config[iZone], solvers0); myfile_res << scientific << solvers0[FEA_SOL]->GetTotal_ComboObj() << "\t"; for (iVar = 0; iVar < config[iZone]->GetnElasticityMod(); iVar++) diff --git a/SU2_CFD/src/output/CAdjElasticityOutput.cpp b/SU2_CFD/src/output/CAdjElasticityOutput.cpp index c64c993cb61..b6b729ab6d3 100644 --- a/SU2_CFD/src/output/CAdjElasticityOutput.cpp +++ b/SU2_CFD/src/output/CAdjElasticityOutput.cpp @@ -103,15 +103,15 @@ void CAdjElasticityOutput::SetHistoryOutputFields(CConfig *config){ AddHistoryOutput("ADJOINT_DISP_Z", "rms[Uz_adj]", ScreenOutputFormat::FIXED, "RMS_RES", "Root-mean square residual of the adjoint of the Z displacements.", HistoryFieldType::RESIDUAL); //Sensitivities - AddHistoryOutput("SENS_E", "Sens[E]", ScreenOutputFormat::SCIENTIFIC, "SENSITIVITY", ""); - AddHistoryOutput("SENS_NU","Sens[Nu]", ScreenOutputFormat::SCIENTIFIC, "SENSITIVITY", ""); + AddHistoryOutput("SENS_E", "Sens[E]", ScreenOutputFormat::SCIENTIFIC, "SENSITIVITY", "d Objective / d Elasticity modulus"); + AddHistoryOutput("SENS_NU", "Sens[Nu]", ScreenOutputFormat::SCIENTIFIC, "SENSITIVITY", "d Objective / d Poisson ratio"); AddHistoryOutput("LINSOL_ITER", "LinSolIter", ScreenOutputFormat::INTEGER, "LINSOL", "Number of iterations of the linear solver."); AddHistoryOutput("LINSOL_RESIDUAL", "LinSolRes", ScreenOutputFormat::FIXED, "LINSOL", "Residual of the linear solver."); - AddHistoryOutput("BGS_ADJ_DISP_X", "bgs[A_Ux]", ScreenOutputFormat::FIXED, "BGS_RES", "BGS residual of the adjoint X displacement.", HistoryFieldType::RESIDUAL); - AddHistoryOutput("BGS_ADJ_DISP_Y", "bgs[A_Uy]", ScreenOutputFormat::FIXED, "BGS_RES", "BGS residual of the adjoint Y displacement.", HistoryFieldType::RESIDUAL); - AddHistoryOutput("BGS_ADJ_DISP_Z", "bgs[A_Uz]", ScreenOutputFormat::FIXED, "BGS_RES", "BGS residual of the adjoint Z displacement.", HistoryFieldType::RESIDUAL); + AddHistoryOutput("BGS_ADJ_DISP_X", "bgs[A_Ux]", ScreenOutputFormat::FIXED, "BGS_RES", "BGS residual of the adjoint X displacement.", HistoryFieldType::RESIDUAL); + AddHistoryOutput("BGS_ADJ_DISP_Y", "bgs[A_Uy]", ScreenOutputFormat::FIXED, "BGS_RES", "BGS residual of the adjoint Y displacement.", HistoryFieldType::RESIDUAL); + AddHistoryOutput("BGS_ADJ_DISP_Z", "bgs[A_Uz]", ScreenOutputFormat::FIXED, "BGS_RES", "BGS residual of the adjoint Z displacement.", HistoryFieldType::RESIDUAL); } diff --git a/SU2_CFD/src/output/CElasticityOutput.cpp b/SU2_CFD/src/output/CElasticityOutput.cpp index 6a26a18b4e4..054df1866d5 100644 --- a/SU2_CFD/src/output/CElasticityOutput.cpp +++ b/SU2_CFD/src/output/CElasticityOutput.cpp @@ -102,8 +102,6 @@ CElasticityOutput::CElasticityOutput(CConfig *config, unsigned short nDim) : COu } -CElasticityOutput::~CElasticityOutput(void) {} - void CElasticityOutput::LoadHistoryData(CConfig *config, CGeometry *geometry, CSolver **solver) { CSolver* fea_solver = solver[FEA_SOL]; @@ -148,42 +146,45 @@ void CElasticityOutput::LoadHistoryData(CConfig *config, CGeometry *geometry, CS SetHistoryOutputValue("VOLUME_FRACTION", fea_solver->GetTotal_OFVolFrac()); SetHistoryOutputValue("TOPOL_DISCRETENESS", fea_solver->GetTotal_OFDiscreteness()); } + /*--- Keep this as last, since it uses the history values that were set. ---*/ + SetCustomAndComboObjectives(FEA_SOL, config, solver); } -void CElasticityOutput::SetHistoryOutputFields(CConfig *config){ +void CElasticityOutput::SetHistoryOutputFields(CConfig *config) { AddHistoryOutput("LINSOL_ITER", "LinSolIter", ScreenOutputFormat::INTEGER, "LINSOL", "Number of iterations of the linear solver."); AddHistoryOutput("LINSOL_RESIDUAL", "LinSolRes", ScreenOutputFormat::FIXED, "LINSOL", "Residual of the linear solver."); - // Residuals - - AddHistoryOutput("RMS_UTOL", "rms[U]", ScreenOutputFormat::FIXED, "RMS_RES", "", HistoryFieldType::RESIDUAL); - AddHistoryOutput("RMS_RTOL", "rms[R]", ScreenOutputFormat::FIXED, "RMS_RES", "", HistoryFieldType::RESIDUAL); - AddHistoryOutput("RMS_ETOL", "rms[E]", ScreenOutputFormat::FIXED, "RMS_RES", "", HistoryFieldType::RESIDUAL); - - AddHistoryOutput("RMS_DISP_X", "rms[DispX]", ScreenOutputFormat::FIXED, "RMS_RES", "", HistoryFieldType::RESIDUAL); - AddHistoryOutput("RMS_DISP_Y", "rms[DispY]", ScreenOutputFormat::FIXED, "RMS_RES", "", HistoryFieldType::RESIDUAL); - AddHistoryOutput("RMS_DISP_Z", "rms[DispZ]", ScreenOutputFormat::FIXED, "RMS_RES", "", HistoryFieldType::RESIDUAL); - - AddHistoryOutput("BGS_DISP_X", "bgs[DispX]", ScreenOutputFormat::FIXED, "BGS_RES", "", HistoryFieldType::RESIDUAL); - AddHistoryOutput("BGS_DISP_Y", "bgs[DispY]", ScreenOutputFormat::FIXED, "BGS_RES", "", HistoryFieldType::RESIDUAL); - AddHistoryOutput("BGS_DISP_Z", "bgs[DispZ]", ScreenOutputFormat::FIXED, "BGS_RES", "", HistoryFieldType::RESIDUAL); - - AddHistoryOutput("VMS", "VonMises", ScreenOutputFormat::SCIENTIFIC, "", "VMS"); - AddHistoryOutput("LOAD_INCREMENT", "Load[%]", ScreenOutputFormat::PERCENT, "", "LOAD_INCREMENT"); - AddHistoryOutput("LOAD_RAMP", "Load_Ramp",ScreenOutputFormat::FIXED, "", "LOAD_RAMP"); + if (nonlinear_analysis) { + AddHistoryOutput("RMS_UTOL", "rms[U]", ScreenOutputFormat::FIXED, "RMS_RES", "Norm of displacement increment", HistoryFieldType::RESIDUAL); + AddHistoryOutput("RMS_RTOL", "rms[R]", ScreenOutputFormat::FIXED, "RMS_RES", "Norm of residual", HistoryFieldType::RESIDUAL); + AddHistoryOutput("RMS_ETOL", "rms[E]", ScreenOutputFormat::FIXED, "RMS_RES", "Norm of energy/work increment", HistoryFieldType::RESIDUAL); + } else if (linear_analysis) { + AddHistoryOutput("RMS_DISP_X", "rms[DispX]", ScreenOutputFormat::FIXED, "RMS_RES", "Residual of X displacement", HistoryFieldType::RESIDUAL); + AddHistoryOutput("RMS_DISP_Y", "rms[DispY]", ScreenOutputFormat::FIXED, "RMS_RES", "Residual of Y displacement", HistoryFieldType::RESIDUAL); + AddHistoryOutput("RMS_DISP_Z", "rms[DispZ]", ScreenOutputFormat::FIXED, "RMS_RES", "Residual of Z displacement", HistoryFieldType::RESIDUAL); + } + if (multiZone) { + AddHistoryOutput("BGS_DISP_X", "bgs[DispX]", ScreenOutputFormat::FIXED, "BGS_RES", "BGS residual of X displacement", HistoryFieldType::RESIDUAL); + AddHistoryOutput("BGS_DISP_Y", "bgs[DispY]", ScreenOutputFormat::FIXED, "BGS_RES", "BGS residual of Y displacement", HistoryFieldType::RESIDUAL); + AddHistoryOutput("BGS_DISP_Z", "bgs[DispZ]", ScreenOutputFormat::FIXED, "BGS_RES", "BGS residual of Z displacement", HistoryFieldType::RESIDUAL); + } + AddHistoryOutput("VMS", "VonMises", ScreenOutputFormat::SCIENTIFIC, "Maximum Von-Misses stress", "VMS"); + AddHistoryOutput("LOAD_RAMP", "Load_Ramp", ScreenOutputFormat::FIXED, "Fraction of total load (ramped)", "LOAD_RAMP"); + AddHistoryOutput("LOAD_INCREMENT", "Load[%]", ScreenOutputFormat::PERCENT, "Percent of total load (incremental)", "LOAD_INCREMENT"); - AddHistoryOutput("REFERENCE_NODE", "RefNode", ScreenOutputFormat::SCIENTIFIC, "STRUCT_COEFF", "", HistoryFieldType::COEFFICIENT); - AddHistoryOutput("TOPOL_COMPLIANCE", "TopComp", ScreenOutputFormat::SCIENTIFIC, "STRUCT_COEFF", "", HistoryFieldType::COEFFICIENT); - AddHistoryOutput("STRESS_PENALTY", "StressPen", ScreenOutputFormat::SCIENTIFIC, "STRUCT_COEFF", "", HistoryFieldType::COEFFICIENT); + AddHistoryOutput("REFERENCE_NODE", "RefNode", ScreenOutputFormat::SCIENTIFIC, "STRUCT_COEFF", "Distance to reference node", HistoryFieldType::COEFFICIENT); + AddHistoryOutput("TOPOL_COMPLIANCE", "TopComp", ScreenOutputFormat::SCIENTIFIC, "STRUCT_COEFF", "Structural compliance", HistoryFieldType::COEFFICIENT); + AddHistoryOutput("STRESS_PENALTY", "StressPen", ScreenOutputFormat::SCIENTIFIC, "STRUCT_COEFF", "Aggregate stress penalty", HistoryFieldType::COEFFICIENT); if (config->GetRefGeom()) { - AddHistoryOutput("REFERENCE_GEOMETRY", "RefGeom", ScreenOutputFormat::SCIENTIFIC, "STRUCT_COEFF", "", HistoryFieldType::COEFFICIENT); + AddHistoryOutput("REFERENCE_GEOMETRY", "RefGeom", ScreenOutputFormat::SCIENTIFIC, "STRUCT_COEFF", "L2 norm of difference wrt reference geometry", HistoryFieldType::COEFFICIENT); } if (config->GetTopology_Optimization()) { - AddHistoryOutput("VOLUME_FRACTION", "VolFrac", ScreenOutputFormat::SCIENTIFIC, "STRUCT_COEFF", "", HistoryFieldType::COEFFICIENT); - AddHistoryOutput("TOPOL_DISCRETENESS", "TopDisc", ScreenOutputFormat::SCIENTIFIC, "STRUCT_COEFF", "", HistoryFieldType::COEFFICIENT); + AddHistoryOutput("VOLUME_FRACTION", "VolFrac", ScreenOutputFormat::SCIENTIFIC, "STRUCT_COEFF", "Fraction of solid material", HistoryFieldType::COEFFICIENT); + AddHistoryOutput("TOPOL_DISCRETENESS", "TopDisc", ScreenOutputFormat::SCIENTIFIC, "STRUCT_COEFF", "Discreteness of the material distribution", HistoryFieldType::COEFFICIENT); } + AddHistoryOutput("COMBO", "ComboObj", ScreenOutputFormat::SCIENTIFIC, "COMBO", "Combined obj. function value.", HistoryFieldType::COEFFICIENT); } diff --git a/SU2_CFD/src/output/CFlowCompOutput.cpp b/SU2_CFD/src/output/CFlowCompOutput.cpp index e9a1c0dac72..2b102fe7097 100644 --- a/SU2_CFD/src/output/CFlowCompOutput.cpp +++ b/SU2_CFD/src/output/CFlowCompOutput.cpp @@ -152,30 +152,21 @@ void CFlowCompOutput::SetHistoryOutputFields(CConfig *config){ for (unsigned short iMarker_Monitoring = 0; iMarker_Monitoring < config->GetnMarker_Monitoring(); iMarker_Monitoring++){ Marker_Monitoring.push_back(config->GetMarker_Monitoring_TagBound(iMarker_Monitoring)); } - /// BEGIN_GROUP: AEROELASTIC, DESCRIPTION: Aeroelastic plunge, pitch - /// DESCRIPTION: Aeroelastic plunge - AddHistoryOutputPerSurface("PLUNGE", "plunge", ScreenOutputFormat::FIXED, "AEROELASTIC", Marker_Monitoring, HistoryFieldType::COEFFICIENT); - /// DESCRIPTION: Aeroelastic pitch - AddHistoryOutputPerSurface("PITCH", "pitch", ScreenOutputFormat::FIXED, "AEROELASTIC", Marker_Monitoring, HistoryFieldType::COEFFICIENT); - /// END_GROUP + if (config->GetAeroelastic_Simulation()) { + /// BEGIN_GROUP: AEROELASTIC, DESCRIPTION: Aeroelastic plunge, pitch + /// DESCRIPTION: Aeroelastic plunge + AddHistoryOutputPerSurface("PLUNGE", "plunge", ScreenOutputFormat::FIXED, "AEROELASTIC", Marker_Monitoring, HistoryFieldType::COEFFICIENT); + /// DESCRIPTION: Aeroelastic pitch + AddHistoryOutputPerSurface("PITCH", "pitch", ScreenOutputFormat::FIXED, "AEROELASTIC", Marker_Monitoring, HistoryFieldType::COEFFICIENT); + /// END_GROUP + } /// DESCRIPTION: Linear solver iterations AddHistoryOutput("LINSOL_ITER", "Linear_Solver_Iterations", ScreenOutputFormat::INTEGER, "LINSOL", "Number of iterations of the linear solver."); AddHistoryOutput("LINSOL_RESIDUAL", "LinSolRes", ScreenOutputFormat::FIXED, "LINSOL", "Residual of the linear solver."); AddHistoryOutputFields_ScalarLinsol(config); - /// BEGIN_GROUP: ENGINE_OUTPUT, DESCRIPTION: Engine output - /// DESCRIPTION: Aero CD drag - AddHistoryOutput("AEROCDRAG", "AeroCDrag", ScreenOutputFormat::SCIENTIFIC, "ENGINE_OUTPUT", "Aero CD drag", HistoryFieldType::COEFFICIENT); - /// DESCRIPTION: Solid CD drag - AddHistoryOutput("SOLIDCDRAG", "SolidCDrag", ScreenOutputFormat::SCIENTIFIC, "ENGINE_OUTPUT", "Solid CD drag ", HistoryFieldType::COEFFICIENT); - /// DESCRIPTION: Radial distortion - AddHistoryOutput("RADIAL_DISTORTION", "Radial_Distortion", ScreenOutputFormat::SCIENTIFIC, "ENGINE_OUTPUT", "Radial distortion ", HistoryFieldType::COEFFICIENT); - /// DESCRIPTION: Circumferential distortion - AddHistoryOutput("CIRCUMFERENTIAL_DISTORTION", "Circumferential_Distortion", ScreenOutputFormat::SCIENTIFIC, "ENGINE_OUTPUT", "Circumferential distortion", HistoryFieldType::COEFFICIENT); - /// END_GROUP - /// BEGIN_GROUP: ROTATING_FRAME, DESCRIPTION: Coefficients related to a rotating frame of reference. /// DESCRIPTION: Merit AddHistoryOutput("FIGURE_OF_MERIT", "CMerit", ScreenOutputFormat::SCIENTIFIC, "ROTATING_FRAME", "Merit", HistoryFieldType::COEFFICIENT); @@ -463,7 +454,7 @@ void CFlowCompOutput::LoadHistoryData(CConfig *config, CGeometry *geometry, CSol SetAnalyzeSurface(solver, geometry, config, false); - /*--- Set aeroydnamic coefficients --- */ + /*--- Set aerodynamic coefficients --- */ SetAerodynamicCoefficients(config, flow_solver); @@ -480,8 +471,13 @@ void CFlowCompOutput::LoadHistoryData(CConfig *config, CGeometry *geometry, CSol Set_CpInverseDesign(flow_solver, geometry, config); /*--- Set nearfield diff fields ---*/ + if (config->GetEquivArea()) Set_NearfieldInverseDesign(flow_solver, geometry, config); + /*--- Keep this as last, since it uses the history values that were set. ---*/ + + SetCustomAndComboObjectives(FLOW_SOL, config, solver); + } bool CFlowCompOutput::SetInit_Residuals(const CConfig *config){ diff --git a/SU2_CFD/src/output/CFlowIncOutput.cpp b/SU2_CFD/src/output/CFlowIncOutput.cpp index 29fe2da0e23..5d66c556f61 100644 --- a/SU2_CFD/src/output/CFlowIncOutput.cpp +++ b/SU2_CFD/src/output/CFlowIncOutput.cpp @@ -298,6 +298,10 @@ void CFlowIncOutput::LoadHistoryData(CConfig *config, CGeometry *geometry, CSolv SetRotatingFrameCoefficients(config, flow_solver); + /*--- Keep this as last, since it uses the history values that were set. ---*/ + + SetCustomAndComboObjectives(FLOW_SOL, config, solver); + } void CFlowIncOutput::SetVolumeOutputFields(CConfig *config){ diff --git a/SU2_CFD/src/output/CFlowOutput.cpp b/SU2_CFD/src/output/CFlowOutput.cpp index 2f539692a1c..bfc10a69850 100644 --- a/SU2_CFD/src/output/CFlowOutput.cpp +++ b/SU2_CFD/src/output/CFlowOutput.cpp @@ -72,12 +72,14 @@ void CFlowOutput::AddAnalyzeSurfaceOutput(const CConfig *config){ } else if (rank == MASTER_NODE) { cout << "\nWARNING: SURFACE_PRESSURE_DROP can only be computed for 2 surfaces (outlet, inlet)\n" << endl; } - /// DESCRIPTION: Average Species - for (unsigned short iVar = 0; iVar < config->GetnSpecies(); iVar++) { - AddHistoryOutput("SURFACE_SPECIES_" + std::to_string(iVar), "Avg_Species_" + std::to_string(iVar), ScreenOutputFormat::FIXED, "SPECIES_COEFF", "Total average species " + std::to_string(iVar) + " on all markers set in MARKER_ANALYZE", HistoryFieldType::COEFFICIENT); + if (config->GetKind_Species_Model() != SPECIES_MODEL::NONE) { + /// DESCRIPTION: Average Species + for (unsigned short iVar = 0; iVar < config->GetnSpecies(); iVar++) { + AddHistoryOutput("SURFACE_SPECIES_" + std::to_string(iVar), "Avg_Species_" + std::to_string(iVar), ScreenOutputFormat::FIXED, "SPECIES_COEFF", "Total average species " + std::to_string(iVar) + " on all markers set in MARKER_ANALYZE", HistoryFieldType::COEFFICIENT); + } + /// DESCRIPTION: Species Variance + AddHistoryOutput("SURFACE_SPECIES_VARIANCE", "Species_Variance", ScreenOutputFormat::SCIENTIFIC, "SPECIES_COEFF", "Total species variance, measure for mixing quality. On all markers set in MARKER_ANALYZE", HistoryFieldType::COEFFICIENT); } - /// DESCRIPTION: Species Variance - AddHistoryOutput("SURFACE_SPECIES_VARIANCE", "Species_Variance", ScreenOutputFormat::SCIENTIFIC, "SPECIES_COEFF", "Total species variance, measure for mixing quality. On all markers set in MARKER_ANALYZE", HistoryFieldType::COEFFICIENT); /// END_GROUP /// BEGIN_GROUP: AERO_COEFF_SURF, DESCRIPTION: Surface values on non-solid markers. @@ -112,12 +114,14 @@ void CFlowOutput::AddAnalyzeSurfaceOutput(const CConfig *config){ AddHistoryOutputPerSurface("SURFACE_TOTAL_TEMPERATURE","Avg_TotalTemp", ScreenOutputFormat::SCIENTIFIC, "FLOW_COEFF_SURF", Marker_Analyze, HistoryFieldType::COEFFICIENT); /// DESCRIPTION: Average total pressure AddHistoryOutputPerSurface("SURFACE_TOTAL_PRESSURE", "Avg_TotalPress", ScreenOutputFormat::SCIENTIFIC, "FLOW_COEFF_SURF", Marker_Analyze, HistoryFieldType::COEFFICIENT); - /// DESCRIPTION: Average Species - for (unsigned short iVar = 0; iVar < config->GetnSpecies(); iVar++) { - AddHistoryOutputPerSurface("SURFACE_SPECIES_" + std::to_string(iVar), "Avg_Species_" + std::to_string(iVar), ScreenOutputFormat::FIXED, "SPECIES_COEFF_SURF", Marker_Analyze, HistoryFieldType::COEFFICIENT); + if (config->GetKind_Species_Model() != SPECIES_MODEL::NONE) { + /// DESCRIPTION: Average Species + for (unsigned short iVar = 0; iVar < config->GetnSpecies(); iVar++) { + AddHistoryOutputPerSurface("SURFACE_SPECIES_" + std::to_string(iVar), "Avg_Species_" + std::to_string(iVar), ScreenOutputFormat::FIXED, "SPECIES_COEFF_SURF", Marker_Analyze, HistoryFieldType::COEFFICIENT); + } + /// DESCRIPTION: Species Variance + AddHistoryOutputPerSurface("SURFACE_SPECIES_VARIANCE", "Species_Variance", ScreenOutputFormat::SCIENTIFIC, "SPECIES_COEFF_SURF", Marker_Analyze, HistoryFieldType::COEFFICIENT); } - /// DESCRIPTION: Species Variance - AddHistoryOutputPerSurface("SURFACE_SPECIES_VARIANCE", "Species_Variance", ScreenOutputFormat::SCIENTIFIC, "SPECIES_COEFF_SURF", Marker_Analyze, HistoryFieldType::COEFFICIENT); /// END_GROUP } // clang-format on @@ -508,14 +512,15 @@ void CFlowOutput::SetAnalyzeSurface(const CSolver* const*solver, const CGeometry Tot_Surface_TotalPressure += TotalPressure; config->SetSurface_TotalPressure(iMarker_Analyze, TotalPressure); - for (unsigned short iVar = 0; iVar < nSpecies; iVar++) { - su2double Species = Surface_Species_Total(iMarker_Analyze, iVar); - SetHistoryOutputPerSurfaceValue("SURFACE_SPECIES_" + std::to_string(iVar), Species, iMarker_Analyze); - Tot_Surface_Species[iVar] += Species; - if (iVar == 0) - config->SetSurface_Species_0(iMarker_Analyze, Species); + if (species) { + for (unsigned short iVar = 0; iVar < nSpecies; iVar++) { + su2double Species = Surface_Species_Total(iMarker_Analyze, iVar); + SetHistoryOutputPerSurfaceValue("SURFACE_SPECIES_" + std::to_string(iVar), Species, iMarker_Analyze); + Tot_Surface_Species[iVar] += Species; + if (iVar == 0) + config->SetSurface_Species_0(iMarker_Analyze, Species); + } } - } /*--- Compute the average static pressure drop between two surfaces. Note @@ -545,12 +550,13 @@ void CFlowOutput::SetAnalyzeSurface(const CSolver* const*solver, const CGeometry SetHistoryOutputValue("SURFACE_SECOND_OVER_UNIFORM", Tot_SecondOverUniformity); SetHistoryOutputValue("SURFACE_TOTAL_TEMPERATURE", Tot_Surface_TotalTemperature); SetHistoryOutputValue("SURFACE_TOTAL_PRESSURE", Tot_Surface_TotalPressure); - for (unsigned short iVar = 0; iVar < nSpecies; iVar++) - SetHistoryOutputValue("SURFACE_SPECIES_" + std::to_string(iVar), Tot_Surface_Species[iVar]); + if (species) { + for (unsigned short iVar = 0; iVar < nSpecies; iVar++) + SetHistoryOutputValue("SURFACE_SPECIES_" + std::to_string(iVar), Tot_Surface_Species[iVar]); - if (config->GetKind_Species_Model() != SPECIES_MODEL::NONE) SetAnalyzeSurface_SpeciesVariance(solver, geometry, config, Surface_Species_Total, Surface_MassFlow_Abs_Total, Surface_Area_Total); + } if ((rank == MASTER_NODE) && !config->GetDiscrete_Adjoint() && output) { @@ -1175,8 +1181,6 @@ void CFlowOutput::SetAerodynamicCoefficients(CConfig *config, CSolver *flow_solv } SetHistoryOutputValue("AOA", config->GetAoA()); - - SetHistoryOutputValue("COMBO", flow_solver->GetTotal_ComboObj()); } void CFlowOutput::SetRotatingFrameCoefficients(CConfig *config, CSolver *flow_solver) { @@ -1190,7 +1194,6 @@ void CFlowOutput::SetRotatingFrameCoefficients(CConfig *config, CSolver *flow_so void CFlowOutput::Add_CpInverseDesignOutput(){ AddHistoryOutput("INVERSE_DESIGN_PRESSURE", "Cp_Diff", ScreenOutputFormat::FIXED, "CP_DIFF", "Cp difference for inverse design"); - } void CFlowOutput::Set_CpInverseDesign(CSolver *solver, const CGeometry *geometry, const CConfig *config){ @@ -1283,8 +1286,7 @@ void CFlowOutput::Set_CpInverseDesign(CSolver *solver, const CGeometry *geometry void CFlowOutput::Add_NearfieldInverseDesignOutput(){ - AddHistoryOutput("EQUIVALENT_AREA", "CEquiv_Area", ScreenOutputFormat::SCIENTIFIC, "EQUIVALENT_AREA", "Equivalent area", HistoryFieldType::COEFFICIENT); - + AddHistoryOutput("EQUIVALENT_AREA", "CEquiv_Area", ScreenOutputFormat::SCIENTIFIC, "EQUIVALENT_AREA", "Equivalent area", HistoryFieldType::COEFFICIENT); } void CFlowOutput::Set_NearfieldInverseDesign(CSolver *solver, const CGeometry *geometry, const CConfig *config){ diff --git a/SU2_CFD/src/output/CHeatOutput.cpp b/SU2_CFD/src/output/CHeatOutput.cpp index fab8fe685c0..f593acd2a60 100644 --- a/SU2_CFD/src/output/CHeatOutput.cpp +++ b/SU2_CFD/src/output/CHeatOutput.cpp @@ -71,11 +71,8 @@ CHeatOutput::CHeatOutput(CConfig *config, unsigned short nDim) : CFVMOutput(conf if (convFields.empty() ) convFields.emplace_back("RMS_TEMPERATURE"); - } -CHeatOutput::~CHeatOutput(void) {} - void CHeatOutput::LoadHistoryData(CConfig *config, CGeometry *geometry, CSolver **solver) { CSolver* heat_solver = solver[HEAT_SOL]; @@ -92,6 +89,8 @@ void CHeatOutput::LoadHistoryData(CConfig *config, CGeometry *geometry, CSolver SetHistoryOutputValue("LINSOL_RESIDUAL", log10(heat_solver->GetResLinSolver())); SetHistoryOutputValue("CFL_NUMBER", config->GetCFL(MESH_0)); + /*--- Keep this as last, since it uses the history values that were set. ---*/ + SetCustomAndComboObjectives(HEAT_SOL, config, solver); } @@ -109,6 +108,7 @@ void CHeatOutput::SetHistoryOutputFields(CConfig *config){ AddHistoryOutput("AVG_TEMPERATURE", "AvgTemp", ScreenOutputFormat::SCIENTIFIC, "HEAT", "Total average temperature on all surfaces defined in MARKER_MONITORING", HistoryFieldType::COEFFICIENT); AddHistoryOutput("CFL_NUMBER", "CFL number", ScreenOutputFormat::SCIENTIFIC, "CFL_NUMBER", "Current value of the CFL number"); + AddHistoryOutput("COMBO", "ComboObj", ScreenOutputFormat::SCIENTIFIC, "COMBO", "Combined obj. function value.", HistoryFieldType::COEFFICIENT); } diff --git a/SU2_CFD/src/output/CMultizoneOutput.cpp b/SU2_CFD/src/output/CMultizoneOutput.cpp index 2a73c74fa26..8bfaf30c60f 100644 --- a/SU2_CFD/src/output/CMultizoneOutput.cpp +++ b/SU2_CFD/src/output/CMultizoneOutput.cpp @@ -78,60 +78,55 @@ CMultizoneOutput::CMultizoneOutput(const CConfig* driver_config, const CConfig* } -void CMultizoneOutput::LoadMultizoneHistoryData(COutput **output, CConfig **config) { +void CMultizoneOutput::LoadMultizoneHistoryData(const COutput* const* output) { - unsigned short iZone, iField, nField; - string name, header; + string nameMultizone, zoneIndex; + su2double comboValue = 0; - for (iZone = 0; iZone < nZone; iZone++){ - - map ZoneHistoryFields = output[iZone]->GetHistoryFields(); - vector ZoneHistoryNames = output[iZone]->GetHistoryOutput_List(); - - nField = ZoneHistoryNames.size(); - - - /*-- For all the variables per solver --*/ - for (iField = 0; iField < nField; iField++){ - - if (ZoneHistoryNames[iField] != "TIME_ITER" && ZoneHistoryNames[iField] != "OUTER_ITER"){ - - name = ZoneHistoryNames[iField]+ "[" + PrintingToolbox::to_string(iZone) + "]"; - - SetHistoryOutputValue(name, ZoneHistoryFields[ZoneHistoryNames[iField]].value); + for (unsigned short iZone = 0; iZone < nZone; iZone++) { + zoneIndex = "[" + PrintingToolbox::to_string(iZone) + "]"; + /*--- For all the variables per solver ---*/ + for (const auto& item : output[iZone]->GetHistoryFields()) { + const auto& name = item.first; + if (name != "TIME_ITER" && name != "OUTER_ITER") { + nameMultizone = name + zoneIndex; + SetHistoryOutputValue(nameMultizone, item.second.value); + } + if (name == "COMBO") { + comboValue += item.second.value; } } } + SetHistoryOutputValue("COMBO", comboValue); } -void CMultizoneOutput::SetMultizoneHistoryOutputFields(COutput **output, CConfig **config) { +void CMultizoneOutput::SetMultizoneHistoryOutputFields(const COutput* const* output) { - unsigned short iZone, iField, nField; - string name, header, group; + string name, header, group, zoneIndex; /*--- Set the fields ---*/ - for (iZone = 0; iZone < nZone; iZone++){ - - map ZoneHistoryFields = output[iZone]->GetHistoryFields(); - vector ZoneHistoryNames = output[iZone]->GetHistoryOutput_List(); + for (unsigned short iZone = 0; iZone < nZone; iZone++) { - nField = ZoneHistoryNames.size(); + const auto& ZoneHistoryFields = output[iZone]->GetHistoryFields(); + zoneIndex = "[" + PrintingToolbox::to_string(iZone) + "]"; + /*--- For all the variables per solver ---*/ + for (const auto& nameSinglezone : output[iZone]->GetHistoryOutput_List()) { - /*-- For all the variables per solver --*/ - for (iField = 0; iField < nField; iField++){ + if (nameSinglezone != "TIME_ITER" && nameSinglezone != "OUTER_ITER") { - if (ZoneHistoryNames[iField] != "TIME_ITER" && ZoneHistoryNames[iField] != "OUTER_ITER"){ + const auto& field = ZoneHistoryFields.at(nameSinglezone); - name = ZoneHistoryNames[iField]+ "[" + PrintingToolbox::to_string(iZone) + "]"; - header = ZoneHistoryFields[ZoneHistoryNames[iField]].fieldName + "[" + PrintingToolbox::to_string(iZone) + "]"; - group = ZoneHistoryFields[ZoneHistoryNames[iField]].outputGroup + "[" + PrintingToolbox::to_string(iZone) + "]"; + name = nameSinglezone + zoneIndex; + header = field.fieldName + zoneIndex; + group = field.outputGroup + zoneIndex; - AddHistoryOutput(name, header, ZoneHistoryFields[ZoneHistoryNames[iField]].screenFormat, group, "", ZoneHistoryFields[ZoneHistoryNames[iField]].fieldType ); + AddHistoryOutput(name, header, field.screenFormat, group, "", field.fieldType ); } } } + AddHistoryOutput("COMBO", "ComboObj", ScreenOutputFormat::SCIENTIFIC, "COMBO", "Combined obj. function value.", HistoryFieldType::COEFFICIENT); } bool CMultizoneOutput::WriteScreen_Header(const CConfig *config) { diff --git a/SU2_CFD/src/output/CNEMOCompOutput.cpp b/SU2_CFD/src/output/CNEMOCompOutput.cpp index aff5de8d985..62da7f9a266 100644 --- a/SU2_CFD/src/output/CNEMOCompOutput.cpp +++ b/SU2_CFD/src/output/CNEMOCompOutput.cpp @@ -165,13 +165,15 @@ void CNEMOCompOutput::SetHistoryOutputFields(CConfig *config){ for (unsigned short iMarker_Monitoring = 0; iMarker_Monitoring < config->GetnMarker_Monitoring(); iMarker_Monitoring++){ Marker_Monitoring.push_back(config->GetMarker_Monitoring_TagBound(iMarker_Monitoring)); } - /// BEGIN_GROUP: AEROELASTIC, DESCRIPTION: Aeroelastic plunge, pitch - /// DESCRIPTION: Aeroelastic plunge - AddHistoryOutputPerSurface("PLUNGE", "plunge", ScreenOutputFormat::FIXED, "AEROELASTIC", Marker_Monitoring, HistoryFieldType::COEFFICIENT); - /// DESCRIPTION: Aeroelastic pitch - AddHistoryOutputPerSurface("PITCH", "pitch", ScreenOutputFormat::FIXED, "AEROELASTIC", Marker_Monitoring, HistoryFieldType::COEFFICIENT); - /// END_GROUP + if (config->GetAeroelastic_Simulation()) { + /// BEGIN_GROUP: AEROELASTIC, DESCRIPTION: Aeroelastic plunge, pitch + /// DESCRIPTION: Aeroelastic plunge + AddHistoryOutputPerSurface("PLUNGE", "plunge", ScreenOutputFormat::FIXED, "AEROELASTIC", Marker_Monitoring, HistoryFieldType::COEFFICIENT); + /// DESCRIPTION: Aeroelastic pitch + AddHistoryOutputPerSurface("PITCH", "pitch", ScreenOutputFormat::FIXED, "AEROELASTIC", Marker_Monitoring, HistoryFieldType::COEFFICIENT); + /// END_GROUP + } /// DESCRIPTION: Linear solver iterations AddHistoryOutput("LINSOL_ITER", "Linear_Solver_Iterations", ScreenOutputFormat::INTEGER, "LINSOL", "Number of iterations of the linear solver."); @@ -179,17 +181,6 @@ void CNEMOCompOutput::SetHistoryOutputFields(CConfig *config){ AddHistoryOutputFields_ScalarLinsol(config); - /// BEGIN_GROUP: ENGINE_OUTPUT, DESCRIPTION: Engine output - /// DESCRIPTION: Aero CD drag - AddHistoryOutput("AEROCDRAG", "AeroCDrag", ScreenOutputFormat::SCIENTIFIC, "ENGINE_OUTPUT", "Aero CD drag", HistoryFieldType::COEFFICIENT); - /// DESCRIPTION: Solid CD drag - AddHistoryOutput("SOLIDCDRAG", "SolidCDrag", ScreenOutputFormat::SCIENTIFIC, "ENGINE_OUTPUT", "Solid CD drag ", HistoryFieldType::COEFFICIENT); - /// DESCRIPTION: Radial distortion - AddHistoryOutput("RADIAL_DISTORTION", "Radial_Distortion", ScreenOutputFormat::SCIENTIFIC, "ENGINE_OUTPUT", "Radial distortion ", HistoryFieldType::COEFFICIENT); - /// DESCRIPTION: Circumferential distortion - AddHistoryOutput("CIRCUMFERENTIAL_DISTORTION", "Circumferential_Distortion", ScreenOutputFormat::SCIENTIFIC, "ENGINE_OUTPUT", "Circumferential distortion", HistoryFieldType::COEFFICIENT); - /// END_GROUP - /// BEGIN_GROUP: ROTATING_FRAME, DESCRIPTION: Coefficients related to a rotating frame of reference. /// DESCRIPTION: Merit AddHistoryOutput("FIGURE_OF_MERIT", "CMerit", ScreenOutputFormat::SCIENTIFIC, "ROTATING_FRAME", "Merit", HistoryFieldType::COEFFICIENT); @@ -492,6 +483,10 @@ void CNEMOCompOutput::LoadHistoryData(CConfig *config, CGeometry *geometry, CSol Set_CpInverseDesign(NEMO_solver, geometry, config); + /*--- Keep this as last, since it uses the history values that were set. ---*/ + + SetCustomAndComboObjectives(FLOW_SOL, config, solver); + } bool CNEMOCompOutput::SetInit_Residuals(const CConfig *config){ diff --git a/SU2_CFD/src/output/COutput.cpp b/SU2_CFD/src/output/COutput.cpp index 5a9cb90300a..4b6ece44f5a 100644 --- a/SU2_CFD/src/output/COutput.cpp +++ b/SU2_CFD/src/output/COutput.cpp @@ -237,7 +237,7 @@ void COutput::SetMultizoneHistory_Output(COutput **output, CConfig **config, CCo LoadCommonHistoryData(driver_config); - LoadMultizoneHistoryData(output, config); + LoadMultizoneHistoryData(output); Convergence_Monitoring(driver_config, curOuterIter); @@ -262,6 +262,55 @@ void COutput::OutputScreenAndHistory(CConfig *config) { } } +void COutput::SetupCustomHistoryOutput(const std::string& expression, CustomHistoryOutput& output) const { + + std::vector symbols; + output.expression = mel::Parse(expression, symbols); + + auto ptrToSymbolValue = [&](const std::string& symbol) { + /*--- Decide if it should be per surface. ---*/ + const auto pos = symbol.find('['); + const su2double* ptr = nullptr; + if (pos == std::string::npos) { + const auto it = historyOutput_Map.find(symbol); + if (it != historyOutput_Map.end()) { + ptr = &(it->second.value); + } + } else { + const auto name = std::string(symbol, 0, pos); + const auto idx = std::stoi(std::string(symbol.begin()+pos+1, symbol.end()-1)); + const auto it = historyOutputPerSurface_Map.find(name); + if (it != historyOutputPerSurface_Map.end()) { + ptr = &(it->second[idx].value); + } + } + return ptr; + }; + + output.symbolValues.reserve(symbols.size()); + for (const auto& symbol : symbols) { + const auto* ptr = ptrToSymbolValue(symbol); + if (ptr == nullptr) { + SU2_MPI::Error(std::string("Invalid history output (") + symbol + std::string(") used in expression:\n") + + expression, CURRENT_FUNCTION); + } + output.symbolValues.push_back(ptr); + } + output.ready = true; +} + +void COutput::SetCustomAndComboObjectives(int idxSol, const CConfig *config, CSolver **solver) { + + if (config->GetKind_ObjFunc() == CUSTOM_OBJFUNC && !config->GetCustomObjFunc().empty()) { + if (!customObjFunc.ready) { + SetupCustomHistoryOutput(config->GetCustomObjFunc(), customObjFunc); + } + solver[idxSol]->SetTotal_Custom_ObjFunc(customObjFunc.eval()); + } + solver[idxSol]->Evaluate_ObjFunc(config, solver); + SetHistoryOutputValue("COMBO", solver[idxSol]->GetTotal_ComboObj()); +} + void COutput::AllocateDataSorters(CConfig *config, CGeometry *geometry){ /*---- Construct a data sorter object to partition and distribute @@ -1198,7 +1247,7 @@ void COutput::PreprocessMultizoneHistoryOutput(COutput **output, CConfig **confi /*--- Set the History output fields using a virtual function call to the child implementation ---*/ - SetMultizoneHistoryOutputFields(output, config); + SetMultizoneHistoryOutputFields(output); /*--- Postprocess the history fields. Creates new fields based on the ones set in the child classes ---*/ @@ -2040,50 +2089,60 @@ void COutput::LoadCommonHistoryData(CConfig *config){ } -void COutput::PrintHistoryFields(){ +void COutput::PrintHistoryFields() const { - if (rank == MASTER_NODE){ + if (rank != MASTER_NODE) return; - PrintingToolbox::CTablePrinter HistoryFieldTable(&std::cout); + PrintingToolbox::CTablePrinter HistoryFieldTable(&std::cout); - unsigned short NameSize = 0, GroupSize = 0, DescrSize = 0; + size_t NameSize = 0, GroupSize = 0, DescrSize = 0; - for (unsigned short iField = 0; iField < historyOutput_List.size(); iField++){ - - HistoryOutputField &Field = historyOutput_Map.at(historyOutput_List[iField]); + for (int perSurf = 0; perSurf < 2; ++perSurf) { + const auto& outputList = perSurf ? historyOutputPerSurface_List : historyOutput_List; - if (Field.description != ""){ - if (historyOutput_List[iField].size() > NameSize){ - NameSize = historyOutput_List[iField].size(); - } - if (Field.outputGroup.size() > GroupSize){ - GroupSize = Field.outputGroup.size(); - } - if (Field.description.size() > DescrSize){ - DescrSize = Field.description.size(); - } + for (const auto& outputName : outputList) { + const HistoryOutputField* Field = nullptr; + if (!perSurf) { + Field = &historyOutput_Map.at(outputName); + } else { + Field = &historyOutputPerSurface_Map.at(outputName)[0]; + } + if (perSurf || !Field->description.empty()) { + NameSize = std::max(NameSize, outputName.size()); + GroupSize = std::max(GroupSize, Field->outputGroup.size()); + DescrSize = std::max(DescrSize, Field->description.size()); } } + } - cout << "Available screen/history output fields for the current configuration in " << multiZoneHeaderString << ":" << endl; + cout << "Available screen/history output fields for the current configuration in " << multiZoneHeaderString << ":\n"; - HistoryFieldTable.AddColumn("Name", NameSize); - HistoryFieldTable.AddColumn("Group Name", GroupSize); - HistoryFieldTable.AddColumn("Type",5); - HistoryFieldTable.AddColumn("Description", DescrSize); - HistoryFieldTable.SetAlign(PrintingToolbox::CTablePrinter::LEFT); + HistoryFieldTable.AddColumn("Name", NameSize); + HistoryFieldTable.AddColumn("Group Name", GroupSize); + HistoryFieldTable.AddColumn("Type",5); + HistoryFieldTable.AddColumn("Description", DescrSize); + HistoryFieldTable.SetAlign(PrintingToolbox::CTablePrinter::LEFT); - HistoryFieldTable.PrintHeader(); + HistoryFieldTable.PrintHeader(); + string type; - for (unsigned short iField = 0; iField < historyOutput_List.size(); iField++){ + for (int perSurf = 0; perSurf < 2; ++perSurf) { + const auto& outputList = perSurf ? historyOutputPerSurface_List : historyOutput_List; + + for (const auto& outputName : outputList) { + const HistoryOutputField* Field = nullptr; + if (!perSurf) { + Field = &historyOutput_Map.at(outputName); + } else { + Field = &historyOutputPerSurface_Map.at(outputName)[0]; + } - HistoryOutputField &Field = historyOutput_Map.at(historyOutput_List[iField]); + if (!perSurf && Field->description.empty()) continue; - if (Field.fieldType == HistoryFieldType::DEFAULT - || Field.fieldType == HistoryFieldType::COEFFICIENT - || Field.fieldType == HistoryFieldType::RESIDUAL){ - string type; - switch (Field.fieldType) { + if (Field->fieldType == HistoryFieldType::DEFAULT || + Field->fieldType == HistoryFieldType::COEFFICIENT || + Field->fieldType == HistoryFieldType::RESIDUAL) { + switch (Field->fieldType) { case HistoryFieldType::COEFFICIENT: type = "C"; break; @@ -2094,58 +2153,55 @@ void COutput::PrintHistoryFields(){ type = "D"; break; } - - if (Field.description != "") - HistoryFieldTable << historyOutput_List[iField] << Field.outputGroup << type << Field.description; - + HistoryFieldTable << outputName << Field->outputGroup << type << Field->description; } } + } - HistoryFieldTable.PrintFooter(); - - cout << "Type legend: Default (D), Residual (R), Coefficient (C)" << endl; + HistoryFieldTable.PrintFooter(); - cout << "Generated screen/history fields (only first field of every group is shown):" << endl; + cout << "Type legend: Default (D), Residual (R), Coefficient (C)\n"; + cout << "Generated screen/history fields (only first field of every group is shown):\n"; - PrintingToolbox::CTablePrinter ModifierTable(&std::cout); + PrintingToolbox::CTablePrinter ModifierTable(&std::cout); - ModifierTable.AddColumn("Name", NameSize); - ModifierTable.AddColumn("Group Name", GroupSize); - ModifierTable.AddColumn("Type",5); - ModifierTable.AddColumn("Description", DescrSize); - ModifierTable.SetAlign(PrintingToolbox::CTablePrinter::LEFT); - ModifierTable.PrintHeader(); + ModifierTable.AddColumn("Name", NameSize); + ModifierTable.AddColumn("Group Name", GroupSize); + ModifierTable.AddColumn("Type",5); + ModifierTable.AddColumn("Description", DescrSize); + ModifierTable.SetAlign(PrintingToolbox::CTablePrinter::LEFT); + ModifierTable.PrintHeader(); - std::map GroupVisited; + std::map GroupVisited; - for (unsigned short iField = 0; iField < historyOutput_List.size(); iField++){ + for (unsigned short iField = 0; iField < historyOutput_List.size(); iField++){ - HistoryOutputField &Field = historyOutput_Map.at(historyOutput_List[iField]); + const auto& Field = historyOutput_Map.at(historyOutput_List[iField]); - if ((Field.fieldType == HistoryFieldType::AUTO_COEFFICIENT || - Field.fieldType == HistoryFieldType::AUTO_RESIDUAL) && (GroupVisited.count(Field.outputGroup) == 0)){ - string type; - switch (Field.fieldType) { - case HistoryFieldType::AUTO_COEFFICIENT: - type = "AC"; - break; - case HistoryFieldType::AUTO_RESIDUAL: - type = "AR"; - break; - default: - type = "AD"; - break; - } + if ((Field.fieldType == HistoryFieldType::AUTO_COEFFICIENT || + Field.fieldType == HistoryFieldType::AUTO_RESIDUAL) && + (GroupVisited.count(Field.outputGroup) == 0)){ + switch (Field.fieldType) { + case HistoryFieldType::AUTO_COEFFICIENT: + type = "AC"; + break; + case HistoryFieldType::AUTO_RESIDUAL: + type = "AR"; + break; + default: + type = "AD"; + break; + } - if (Field.description != "") - ModifierTable << historyOutput_List[iField] << Field.outputGroup << type << Field.description; + if (Field.description != "") + ModifierTable << historyOutput_List[iField] << Field.outputGroup << type << Field.description; - GroupVisited[Field.outputGroup] = true; - } + GroupVisited[Field.outputGroup] = true; } - ModifierTable.PrintFooter(); - } + + ModifierTable.PrintFooter(); + } void COutput::PrintVolumeFields(){ diff --git a/SU2_CFD/src/output/output_structure_legacy.cpp b/SU2_CFD/src/output/output_structure_legacy.cpp index eddca685855..b82b368a48d 100644 --- a/SU2_CFD/src/output/output_structure_legacy.cpp +++ b/SU2_CFD/src/output/output_structure_legacy.cpp @@ -672,7 +672,7 @@ void COutputLegacy::SetConvHistory_Body(ofstream *ConvHist_file, break; default: - break; + break; } /*--- Output a file with the forces breakdown. ---*/ @@ -704,11 +704,11 @@ void COutputLegacy::SetConvHistory_Body(ofstream *ConvHist_file, /*-- Compute the total objective if a "combo" objective is used ---*/ if (output_comboObj) { - solver_container[val_iZone][val_iInst][FinestMesh][FLOW_SOL]->SetTotal_ComboObj(0.0); switch (config[val_iZone]->GetKind_Solver()) { case MAIN_SOLVER::EULER: case MAIN_SOLVER::NAVIER_STOKES: case MAIN_SOLVER::RANS: case MAIN_SOLVER::INC_EULER: case MAIN_SOLVER::INC_NAVIER_STOKES: case MAIN_SOLVER::INC_RANS: - solver_container[val_iZone][val_iInst][FinestMesh][FLOW_SOL]->Evaluate_ObjFunc(config[val_iZone]); + solver_container[val_iZone][val_iInst][FinestMesh][FLOW_SOL]->Evaluate_ObjFunc(config[val_iZone], + solver_container[val_iZone][val_iInst][FinestMesh]); break; default: break; @@ -944,7 +944,6 @@ void COutputLegacy::SetConvHistory_Body(ofstream *ConvHist_file, Total_CFz = solver_container[val_iZone][val_iInst][FinestMesh][FLOW_SOL]->GetTotal_CFz(); Total_ComboObj = solver_container[val_iZone][val_iInst][FinestMesh][FLOW_SOL]->GetTotal_ComboObj(); Total_AoA = config[val_iZone]->GetAoA() - config[val_iZone]->GetAoA_Offset(); - Total_Custom_ObjFunc = solver_container[val_iZone][val_iInst][FinestMesh][FLOW_SOL]->GetTotal_Custom_ObjFunc(); if (thermal) { Total_Heat = solver_container[val_iZone][val_iInst][FinestMesh][FLOW_SOL]->GetTotal_HeatFlux(); @@ -1652,7 +1651,7 @@ void COutputLegacy::SetConvHistory_Body(ofstream *ConvHist_file, cout << endl << "-------------------------------------------------------------------------" << endl; break; default: - break; + break; } } else { @@ -1842,19 +1841,9 @@ void COutputLegacy::SetConvHistory_Body(ofstream *ConvHist_file, if (nDim == 3) cout << " Res[Displx]" << " Res[Disply]" << " Res[Displz]" << " VMS(Max)"<< endl; } else if (nonlinear_analysis) { - switch (config[val_iZone]->GetResidual_Criteria_FEM()) { - case RESFEM_RELATIVE: - cout << " Res[UTOL]" << " Res[RTOL]" << " Res[ETOL]" << " VMS(Max)"<< endl; - break; - case RESFEM_ABSOLUTE: - cout << " Res[UTOL-A]" << " Res[RTOL-A]" << " Res[ETOL-A]" << " VMS(Max)"<< endl; - break; - default: - cout << " Res[UTOL]" << " Res[RTOL]" << " Res[ETOL]" << " VMS(Max)"<< endl; - break; - } - } - break; + cout << " Res[UTOL]" << " Res[RTOL]" << " Res[ETOL]" << " VMS(Max)"<< endl; + } + break; case MAIN_SOLVER::ADJ_EULER : case MAIN_SOLVER::ADJ_NAVIER_STOKES : case MAIN_SOLVER::DISC_ADJ_EULER: case MAIN_SOLVER::DISC_ADJ_NAVIER_STOKES: @@ -1976,7 +1965,7 @@ void COutputLegacy::SetConvHistory_Body(ofstream *ConvHist_file, break; default: - break; + break; } } } @@ -2853,7 +2842,7 @@ void COutputLegacy::SpecialOutput_ForcesBreakdown(CSolver *****solver, CGeometry } break; default: - break; + break; } diff --git a/SU2_CFD/src/solvers/CEulerSolver.cpp b/SU2_CFD/src/solvers/CEulerSolver.cpp index 94987c245c6..fdc3b116592 100644 --- a/SU2_CFD/src/solvers/CEulerSolver.cpp +++ b/SU2_CFD/src/solvers/CEulerSolver.cpp @@ -4217,7 +4217,7 @@ void CEulerSolver::UpdateCustomBoundaryConditions(CGeometry **geometry_container } } -void CEulerSolver::Evaluate_ObjFunc(const CConfig *config) { +void CEulerSolver::Evaluate_ObjFunc(const CConfig *config, CSolver**) { unsigned short iMarker_Monitoring, Kind_ObjFunc; su2double Weight_ObjFunc; diff --git a/SU2_CFD/src/solvers/CFEASolver.cpp b/SU2_CFD/src/solvers/CFEASolver.cpp index 940b8995a28..7ee4109d861 100644 --- a/SU2_CFD/src/solvers/CFEASolver.cpp +++ b/SU2_CFD/src/solvers/CFEASolver.cpp @@ -1786,6 +1786,17 @@ void CFEASolver::Postprocessing(CGeometry *geometry, CConfig *config, CNumerics const bool penalty = ((kindObjFunc == REFERENCE_GEOMETRY) || (kindObjFunc == REFERENCE_NODE)) && ((config->GetDV_FEA() == YOUNG_MODULUS) || (config->GetDV_FEA() == DENSITY_VAL)); + auto computeAllFunctions = [&]() { + /*--- Compute stresses for monitoring and output. ---*/ + Compute_NodalStress(geometry, numerics, config); + + /*--- Compute functions for monitoring and output. ---*/ + Compute_OFRefNode(geometry, config); + Compute_OFCompliance(geometry, config); + if (config->GetRefGeom()) Compute_OFRefGeom(geometry, config); + if (config->GetTopology_Optimization()) Compute_OFVolFrac(geometry, config); + }; + if (of_comp_mode) { if (penalty) Stiffness_Penalty(geometry, numerics, config); @@ -1798,20 +1809,17 @@ void CFEASolver::Postprocessing(CGeometry *geometry, CConfig *config, CNumerics case STRESS_PENALTY: Compute_NodalStress(geometry, numerics, config); break; + case CUSTOM_OBJFUNC: + /*--- No easy way to know, so compute everything. ---*/ + computeAllFunctions(); + break; } return; } if (!config->GetDiscrete_Adjoint()) { - /*--- Compute stresses for monitoring and output. ---*/ - Compute_NodalStress(geometry, numerics, config); - - /*--- Compute functions for monitoring and output. ---*/ if (penalty) Stiffness_Penalty(geometry, numerics, config); - Compute_OFRefNode(geometry, config); - Compute_OFCompliance(geometry, config); - if (config->GetRefGeom()) Compute_OFRefGeom(geometry, config); - if (config->GetTopology_Optimization()) Compute_OFVolFrac(geometry, config); + computeAllFunctions(); } /*--- Residuals do not have to be computed while recording. ---*/ diff --git a/SU2_CFD/src/solvers/CNSSolver.cpp b/SU2_CFD/src/solvers/CNSSolver.cpp index 757525f3f0a..fe4cc078b2b 100644 --- a/SU2_CFD/src/solvers/CNSSolver.cpp +++ b/SU2_CFD/src/solvers/CNSSolver.cpp @@ -265,14 +265,14 @@ void CNSSolver::Buffet_Monitoring(const CGeometry *geometry, const CConfig *conf } -void CNSSolver::Evaluate_ObjFunc(const CConfig *config) { +void CNSSolver::Evaluate_ObjFunc(const CConfig *config, CSolver**) { unsigned short iMarker_Monitoring, Kind_ObjFunc; su2double Weight_ObjFunc; /*--- Evaluate objective functions common to Euler and NS solvers ---*/ - CEulerSolver::Evaluate_ObjFunc(config); + CEulerSolver::Evaluate_ObjFunc(config, nullptr); /*--- Evaluate objective functions specific to NS solver ---*/ diff --git a/TestCases/disc_adj_fsi/Airfoil_2d/config.cfg b/TestCases/disc_adj_fsi/Airfoil_2d/config.cfg index 818f359cdac..6b58ea8e026 100755 --- a/TestCases/disc_adj_fsi/Airfoil_2d/config.cfg +++ b/TestCases/disc_adj_fsi/Airfoil_2d/config.cfg @@ -11,8 +11,8 @@ OUTPUT_WRT_FREQ= 5 MESH_FILENAME= mesh.su2 -OBJECTIVE_FUNCTION= REFERENCE_NODE +OBJECTIVE_FUNCTION= CUSTOM_OBJFUNC -SCREEN_OUTPUT= OUTER_ITER, AVG_BGS_RES[0], SENS_E[1] +SCREEN_OUTPUT= OUTER_ITER, AVG_BGS_RES[0], AVG_BGS_RES[1], LINSOL_RESIDUAL[0], SENS_E[1], SENS_NU[1] %WRT_ZONE_CONV=YES diff --git a/TestCases/disc_adj_fsi/Airfoil_2d/configFEA.cfg b/TestCases/disc_adj_fsi/Airfoil_2d/configFEA.cfg index b69b6d08132..fab6a9064f7 100755 --- a/TestCases/disc_adj_fsi/Airfoil_2d/configFEA.cfg +++ b/TestCases/disc_adj_fsi/Airfoil_2d/configFEA.cfg @@ -7,6 +7,7 @@ REFERENCE_NODE= 234 REFERENCE_NODE_DISPLACEMENT= (0.0, 0.0) REFERENCE_NODE_PENALTY= 1.0 DESIGN_VARIABLE_FEA= YOUNG_MODULUS +CUSTOM_OBJFUNC= '1e2 * (1e3 * REFERENCE_NODE + TOPOL_COMPLIANCE)' % % Solid properties ----------------------------------------------------- % MATERIAL_MODEL= NEO_HOOKEAN diff --git a/TestCases/disc_adj_fsi/Airfoil_2d/configFlow.cfg b/TestCases/disc_adj_fsi/Airfoil_2d/configFlow.cfg index 2dbad80c7b7..16b9836e62d 100755 --- a/TestCases/disc_adj_fsi/Airfoil_2d/configFlow.cfg +++ b/TestCases/disc_adj_fsi/Airfoil_2d/configFlow.cfg @@ -4,6 +4,7 @@ KIND_TURB_MODEL= NONE % % Optimization --------------------------------------------------------- % GRAD_OBJFUNC_FILENAME= of_grad.dat +CUSTOM_OBJFUNC= '1e5 * DRAG' % % Compressible free-stream conditions ---------------------------------- % MACH_NUMBER= 0.8 @@ -40,7 +41,7 @@ MARKER_DESIGNING= ( leading_edge, pressure_side, suction_side ) % Common numerics settings --------------------------------------------- % REF_DIMENSIONALIZATION= DIMENSIONAL NUM_METHOD_GRAD= GREEN_GAUSS -CFL_NUMBER= 15.0 +CFL_NUMBER= 500.0 % % Flow numerics -------------------------------------------------------- % CONV_NUM_METHOD_FLOW= JST @@ -48,20 +49,15 @@ JST_SENSOR_COEFF= ( 0.5, 0.02 ) TIME_DISCRE_FLOW= EULER_IMPLICIT % % Linear solvers ------------------------------------------------------- % -LINEAR_SOLVER= BCGSTAB +LINEAR_SOLVER= FGMRES LINEAR_SOLVER_PREC= ILU LINEAR_SOLVER_ERROR= 1E-3 -LINEAR_SOLVER_ITER= 1000 -DISCADJ_LIN_SOLVER= BCGSTAB +LINEAR_SOLVER_ITER= 20 +LINEAR_SOLVER_SMOOTHER_RELAXATION= 0.7 +DISCADJ_LIN_SOLVER= SMOOTHER DISCADJ_LIN_PREC= ILU -% Multigrid -MGLEVEL= 2 -MGCYCLE= V_CYCLE -MG_PRE_SMOOTH= ( 1, 2, 3, 3 ) -MG_POST_SMOOTH= ( 0, 0, 0, 0 ) -MG_CORRECTION_SMOOTH= ( 0, 0, 0, 0 ) -MG_DAMP_RESTRICTION= 0.75 -MG_DAMP_PROLONGATION= 0.75 +NEWTON_KRYLOV= YES +QUASI_NEWTON_NUM_SAMPLES= 999 % DEFORM_LINEAR_SOLVER= CONJUGATE_GRADIENT DEFORM_LINEAR_SOLVER_PREC= ILU diff --git a/TestCases/parallel_regression.py b/TestCases/parallel_regression.py index df48667e672..aa6f831f1f4 100644 --- a/TestCases/parallel_regression.py +++ b/TestCases/parallel_regression.py @@ -211,6 +211,17 @@ def main(): flatplate.tol = 0.00001 test_list.append(flatplate) + # Custom objective function + flatplate_udobj = TestCase('flatplate_udobj') + flatplate_udobj.cfg_dir = "user_defined_functions" + flatplate_udobj.cfg_file = "lam_flatplate.cfg" + flatplate_udobj.test_iter = 20 + flatplate_udobj.test_vals = [-6.653802, -1.18143, -0.794887, 0.000611, -3.6850e-04, 7.3568e-04, -1.1042e-03, 5.9669e+02, 2.9980e+02, 2.9689e+02, 1.7147] + flatplate_udobj.su2_exec = "mpirun -n 2 SU2_CFD" + flatplate_udobj.timeout = 1600 + flatplate_udobj.tol = 0.00001 + test_list.append(flatplate_udobj) + # Laminar cylinder (steady) cylinder = TestCase('cylinder') cylinder.cfg_dir = "navierstokes/cylinder" diff --git a/TestCases/parallel_regression_AD.py b/TestCases/parallel_regression_AD.py index 7ad1dd98c8e..f03674f33ab 100644 --- a/TestCases/parallel_regression_AD.py +++ b/TestCases/parallel_regression_AD.py @@ -313,7 +313,7 @@ def main(): discadj_fsi2.cfg_dir = "disc_adj_fsi/Airfoil_2d" discadj_fsi2.cfg_file = "config.cfg" discadj_fsi2.test_iter = 8 - discadj_fsi2.test_vals = [-5.318452, -2.4380e-13] + discadj_fsi2.test_vals = [-3.47949, 0.122883, -1.303589, 7.5407e-09, 2.3244] discadj_fsi2.su2_exec = "mpirun -n 2 SU2_CFD_AD" discadj_fsi2.timeout = 1600 discadj_fsi2.tol = 1e-16 diff --git a/TestCases/user_defined_functions/lam_flatplate.cfg b/TestCases/user_defined_functions/lam_flatplate.cfg new file mode 100644 index 00000000000..12ba2d44dbe --- /dev/null +++ b/TestCases/user_defined_functions/lam_flatplate.cfg @@ -0,0 +1,101 @@ +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% % +% SU2 configuration file % +% Case description: Test custom objective function. % +% Author: P. Gomes % +% Date: 5th Jan 2022 % +% File Version 7.2.1 "Blackbird" % +% % +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% +SOLVER= NAVIER_STOKES +KIND_TURB_MODEL= NONE +RESTART_SOL= NO +% +% "COMBO" is the name and group of the output for the objective function +% (regardless of definition). +SCREEN_OUTPUT= INNER_ITER, RMS_DENSITY, RMS_ENERGY, LINSOL_RESIDUAL, FORCE_Z,\ + SURFACE_MASSFLOW, SURFACE_TOTAL_TEMPERATURE, COMBO +HISTORY_OUTPUT = ITER, AERO_COEFF, FLOW_COEFF, FLOW_COEFF_SURF, COMBO +OBJECTIVE_FUNCTION= CUSTOM_OBJFUNC +% Here we define how the custom objective is computed from other outputs. For +% example, force in the z direction (computed for all MARKER_MONITORING and part +% of AERO_COEFF) plus the absolute value of massflow across the second surface +% ([1]) in MARKER_ANALYZE, scaled by a factor of 1000. It is also possible to +% use "per surface" values from MARKER_MONITORING (use the dry-run mode to see +% the names of available outputs, e.g. SU2_CFD -d lam_flatplate.cfg). +% For multizone problems the CUSTOM_OBJFUNC should be defined for each zone +% individually (with the outputs of that zone), the total for the problem is +% the sum over zones, see disc_adj_fsi/Airfoil_2d. +CUSTOM_OBJFUNC= '1e3 * (FORCE_Z + fabs(SURFACE_MASSFLOW[1]))' + +% -------------------- COMPRESSIBLE FREE-STREAM DEFINITION --------------------% +% +MACH_NUMBER= 0.1 +INIT_OPTION= TD_CONDITIONS +FREESTREAM_OPTION= TEMPERATURE_FS +FREESTREAM_TEMPERATURE= 297.62 +REYNOLDS_NUMBER= 600 +REYNOLDS_LENGTH= 0.02 + +% ---------------------- REFERENCE VALUE DEFINITION ---------------------------% +% +REF_ORIGIN_MOMENT_X = 0.00 +REF_ORIGIN_MOMENT_Y = 0.00 +REF_ORIGIN_MOMENT_Z = 0.00 +REF_LENGTH= 0.02 +REF_AREA= 0.02 +% +FLUID_MODEL= IDEAL_GAS +GAMMA_VALUE= 1.4 +GAS_CONSTANT= 287.87 +VISCOSITY_MODEL= CONSTANT_VISCOSITY +MU_CONSTANT= 0.001 + +% -------------------- BOUNDARY CONDITION DEFINITION --------------------------% +% +MARKER_HEATFLUX= ( y_minus, 0.0 ) +% +MARKER_SYM= ( y_plus ) +MARKER_PERIODIC= ( x_minus, x_plus, 0,0,0, 0,0,0, 0.01,0,0 ) +% +MARKER_INLET= ( z_minus, 300.0, 100000.0, 0.0, 0.0, 1.0 ) +MARKER_OUTLET= ( z_plus, 99000.0 ) +% +MARKER_PLOTTING= ( y_minus ) +MARKER_MONITORING= ( y_minus ) +MARKER_ANALYZE= ( z_minus, z_plus ) + +% ------------- COMMON PARAMETERS DEFINING THE NUMERICAL METHOD ---------------% +% +NUM_METHOD_GRAD= GREEN_GAUSS +CFL_NUMBER= 1e4 +CFL_ADAPT= NO +TIME_DISCRE_FLOW= EULER_IMPLICIT + +% ------------------------ LINEAR SOLVER DEFINITION ---------------------------% +% +LINEAR_SOLVER= FGMRES +LINEAR_SOLVER_PREC= ILU +LINEAR_SOLVER_ERROR= 0.2 +LINEAR_SOLVER_ITER= 5 + +% -------------------- FLOW NUMERICAL METHOD DEFINITION -----------------------% +% +CONV_NUM_METHOD_FLOW= ROE +USE_VECTORIZATION= YES +MUSCL_FLOW= YES +SLOPE_LIMITER_FLOW= NONE + +% --------------------------- CONVERGENCE PARAMETERS --------------------------% +% +CONV_RESIDUAL_MINVAL= -11 +CONV_STARTITER= 0 +INNER_ITER= 1000 + +% ------------------------- INPUT/OUTPUT INFORMATION --------------------------% +% +MESH_FORMAT= BOX +MESH_BOX_LENGTH= (0.01, 0.01, 0.1) +MESH_BOX_SIZE= (9, 17, 65) + diff --git a/config_template.cfg b/config_template.cfg index 7499277e610..cff12f4fe92 100644 --- a/config_template.cfg +++ b/config_template.cfg @@ -1032,11 +1032,11 @@ MAX_DELTA_TIME= 1E6 % Runge-Kutta alpha coefficients RK_ALPHA_COEFF= ( 0.66667, 0.66667, 1.000000 ) % -% Objective function in gradient evaluation (DRAG, LIFT, SIDEFORCE, MOMENT_X, +% Objective function in gradient evaluation (DRAG, LIFT, SIDEFORCE, MOMENT_X, % MOMENT_Y, MOMENT_Z, EFFICIENCY, BUFFET, % EQUIVALENT_AREA, NEARFIELD_PRESSURE, % FORCE_X, FORCE_Y, FORCE_Z, THRUST, -% TORQUE, TOTAL_HEATFLUX, +% TORQUE, TOTAL_HEATFLUX, CUSTOM_OBJFUNC % MAXIMUM_HEATFLUX, INVERSE_DESIGN_PRESSURE, % INVERSE_DESIGN_HEATFLUX, SURFACE_TOTAL_PRESSURE, % SURFACE_MASSFLOW, SURFACE_STATIC_PRESSURE, SURFACE_MACH) @@ -1045,6 +1045,11 @@ OBJECTIVE_FUNCTION= DRAG % % List of weighting values when using more than one OBJECTIVE_FUNCTION. Separate by commas and match with MARKER_MONITORING. OBJECTIVE_WEIGHT = 1.0 +% +% Expression used when "OBJECTIVE_FUNCTION= CUSTOM_OBJFUNC", any history/screen output can be used together with common +% math functions (sqrt, cos, exp, etc.). This can be used for constraint aggregation (as below) or to compute something +% SU2 does not, see TestCases/user_defined_functions/. +CUSTOM_OBJFUNC= 'DRAG + 10 * pow(fmax(0.4-LIFT, 0), 2)' % ----------- SLOPE LIMITER AND DISSIPATION SENSOR DEFINITION -----------------% % diff --git a/externals/mel b/externals/mel new file mode 160000 index 00000000000..2484cd3258e --- /dev/null +++ b/externals/mel @@ -0,0 +1 @@ +Subproject commit 2484cd3258ef800a10e361016cb341834ee7930b diff --git a/meson.build b/meson.build index 22b6a7e3fcf..5a9e8b1c922 100644 --- a/meson.build +++ b/meson.build @@ -198,6 +198,9 @@ if get_option('enable-librom') endif +mel_dep = declare_dependency(include_directories: 'externals/mel') +su2_deps += mel_dep + extra_deps = get_option('extra-deps').split(',') foreach dep : extra_deps if dep != '' diff --git a/meson_scripts/init.py b/meson_scripts/init.py index 1d52a55b0b4..81a1f6de6a5 100755 --- a/meson_scripts/init.py +++ b/meson_scripts/init.py @@ -56,6 +56,8 @@ def init_submodules(method = 'auto'): github_repo_ninja = 'https://github.com/ninja-build/ninja' sha_version_mpp = '5ff579f43781cae07411e5ab46291c9971536be6' github_repo_mpp = 'https://github.com/mutationpp/Mutationpp' + sha_version_mel = '2484cd3258ef800a10e361016cb341834ee7930b' + github_repo_mel = 'https://github.com/pcarruscag/MEL' medi_name = 'MeDiPack' codi_name = 'CoDiPack' @@ -63,12 +65,14 @@ def init_submodules(method = 'auto'): meson_name = 'meson' ninja_name= 'ninja' mpp_name= 'Mutationpp' + mel_name = 'MEL' base_path = cur_dir + os.path.sep + 'externals' + os.path.sep alt_name_medi = base_path + 'medi' alt_name_codi = base_path + 'codi' alt_name_opdi = base_path + 'opdi' alt_name_meson = base_path + 'meson' alt_name_ninja = base_path + 'ninja' + alt_name_mel = base_path + 'mel' alt_name_mpp = cur_dir + os.path.sep + 'subprojects' + os.path.sep + 'Mutationpp' if method == 'auto': @@ -90,6 +94,7 @@ def init_submodules(method = 'auto'): submodule_status(alt_name_meson, sha_version_meson) submodule_status(alt_name_ninja, sha_version_ninja) submodule_status(alt_name_mpp, sha_version_mpp) + submodule_status(alt_name_mel, sha_version_mel) # Otherwise download the zip file from git else: download_module(codi_name, alt_name_codi, github_repo_codi, sha_version_codi) @@ -98,6 +103,7 @@ def init_submodules(method = 'auto'): download_module(meson_name, alt_name_meson, github_repo_meson, sha_version_meson) download_module(ninja_name, alt_name_ninja, github_repo_ninja, sha_version_ninja) download_module(mpp_name, alt_name_mpp, github_repo_mpp, sha_version_mpp) + download_module(mel_name, alt_name_mel, github_repo_mel, sha_version_mel) def is_git_directory(path = '.'):