Skip to content

Commit 6995c81

Browse files
committed
implement "Function" type of output and add regression/docs
1 parent 30e7b3a commit 6995c81

7 files changed

Lines changed: 62 additions & 18 deletions

File tree

SU2_CFD/include/output/CFlowOutput.hpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -240,7 +240,12 @@ class CFlowOutput : public CFVMOutput{
240240

241241
for (const auto& var : output.varSymbols) {
242242
output.varIndices.push_back(IndexOfVariable(idx, var));
243-
if (output.varIndices.back() != CustomOutput::NOT_A_VARIABLE) continue;
243+
244+
if (output.type == OperationType::FUNCTION && output.varIndices.back() != CustomOutput::NOT_A_VARIABLE) {
245+
SU2_MPI::Error("Custom outputs of type 'Function' cannot reference solver variables.", CURRENT_FUNCTION);
246+
}
247+
/*--- Symbol is a valid solver variable. ---*/
248+
if (output.varIndices.back() < CustomOutput::NOT_A_VARIABLE) continue;
244249

245250
/*--- An index above NOT_A_VARIABLE is not valid with current solver settings. ---*/
246251
if (output.varIndices.back() > CustomOutput::NOT_A_VARIABLE) {

SU2_CFD/include/output/COutput.hpp

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -187,7 +187,7 @@ class COutput {
187187
CustomHistoryOutput customObjFunc; /*!< \brief User-defined expression for a custom objective. */
188188

189189
/*! \brief Type of operation for custom outputs. */
190-
enum class OperationType { MACRO, AREA_AVG, AREA_INT, MASSFLOW_AVG, MASSFLOW_INT };
190+
enum class OperationType { MACRO, FUNCTION, AREA_AVG, AREA_INT, MASSFLOW_AVG, MASSFLOW_INT };
191191

192192
/*! \brief Struct to hold a parsed custom output function. */
193193
struct CustomOutput {
@@ -228,17 +228,17 @@ class COutput {
228228

229229
std::vector<CustomOutput> customOutputs; /*!< \brief User-defined outputs. */
230230

231-
/*----------------------------- Volume output ----------------------------*/
231+
/*----------------------------- Volume output ----------------------------*/
232232

233-
CParallelDataSorter* volumeDataSorter; //!< Volume data sorter
234-
CParallelDataSorter* surfaceDataSorter; //!< Surface data sorter
233+
CParallelDataSorter* volumeDataSorter; //!< Volume data sorter
234+
CParallelDataSorter* surfaceDataSorter; //!< Surface data sorter
235235

236-
vector<string> volumeFieldNames; //!< Vector containing the volume field names
237-
unsigned short nVolumeFields; //!< \brief Number of fields in the volume output */
236+
vector<string> volumeFieldNames; //!< Vector containing the volume field names
237+
unsigned short nVolumeFields; //!< Number of fields in the volume output
238238

239-
string volumeFilename, //!< Volume output filename
240-
surfaceFilename, //!< Surface output filename
241-
restartFilename; //!< Restart output filename
239+
string volumeFilename, //!< Volume output filename
240+
surfaceFilename, //!< Surface output filename
241+
restartFilename; //!< Restart output filename
242242

243243
/** \brief Structure to store information for a volume output field.
244244
*

SU2_CFD/src/output/CFlowOutput.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -772,6 +772,15 @@ void CFlowOutput::SetCustomOutputs(const CSolver *solver, const CGeometry *geome
772772
}
773773
}
774774

775+
if (output.type == OperationType::FUNCTION) {
776+
auto Functor = [&](unsigned long i) {
777+
/*--- Functions only reference other history outputs. ---*/
778+
return *output.otherOutputs[i - CustomOutput::NOT_A_VARIABLE];
779+
};
780+
SetHistoryOutputValue(output.name, output.eval(Functor));
781+
continue;
782+
}
783+
775784
/*--- Surface integral of the expression. ---*/
776785

777786
std::array<su2double, 2> integral = {0.0, 0.0};

SU2_CFD/src/output/COutput.cpp

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2181,6 +2181,7 @@ void COutput::SetCustomOutputs(const CConfig* config) {
21812181

21822182
const std::map<std::string, OperationType> opMap = {
21832183
{"Macro", OperationType::MACRO},
2184+
{"Function", OperationType::FUNCTION},
21842185
{"AreaAvg", OperationType::AREA_AVG},
21852186
{"AreaInt", OperationType::AREA_INT},
21862187
{"MassFlowAvg", OperationType::MASSFLOW_AVG},
@@ -2260,9 +2261,14 @@ void COutput::SetCustomOutputs(const CConfig* config) {
22602261
output.type = type;
22612262
output.func = std::move(func);
22622263
output.expression = mel::Parse<passivedouble>(output.func, output.varSymbols);
2263-
#ifndef NDEBUG
2264+
#ifndef NDEBUG
22642265
mel::Print(output.expression, output.varSymbols, std::cout);
2265-
#endif
2266+
#endif
2267+
2268+
if (type == OperationType::FUNCTION) {
2269+
AddHistoryOutput(output.name, output.name, ScreenOutputFormat::SCIENTIFIC, "CUSTOM", "Custom output");
2270+
break;
2271+
}
22662272

22672273
/*--- Find the marker names. ---*/
22682274
while (it != last && (*it == ' ' || *it == '}' || *it == '[')) ++it;

TestCases/parallel_regression.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -232,7 +232,7 @@ def main():
232232
flatplate_udobj.cfg_dir = "user_defined_functions"
233233
flatplate_udobj.cfg_file = "lam_flatplate.cfg"
234234
flatplate_udobj.test_iter = 20
235-
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]
235+
flatplate_udobj.test_vals = [-6.653803, -1.181430, -0.794886, 0.000611, -3.6850e-04, 7.3568e-04, -1.1042e-03, 5.9669e+02, 2.9980e+02, 2.9689e+02, 2.1492e+01, 5.6399e-01, 2.2787]
236236
flatplate_udobj.su2_exec = "mpirun -n 2 SU2_CFD"
237237
flatplate_udobj.timeout = 1600
238238
flatplate_udobj.tol = 0.00001

TestCases/user_defined_functions/lam_flatplate.cfg

Lines changed: 26 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
22
% %
33
% SU2 configuration file %
4-
% Case description: Test custom objective function. %
4+
% Case description: Test custom outputs and objective function. %
55
% Author: P. Gomes %
66
% Date: 5th Jan 2022 %
77
% File Version 7.3.1 "Blackbird" %
@@ -12,11 +12,32 @@ SOLVER= NAVIER_STOKES
1212
KIND_TURB_MODEL= NONE
1313
RESTART_SOL= NO
1414
%
15+
% User defined expressions of solver variables and other history outputs.
16+
% The syntax to define a custom output is 'name : type{expression}[markers]'.
17+
% NOTE: To obtain the list of available solver variables write an invalid
18+
% expression (e.g. 'x : AreaAvg{INVALID}[]') and run SU2.
19+
% Different outputs need to be separated by ";". The available types are:
20+
% - Macro: Introduces a new field that can only be used in other expressions,
21+
% it is not an output by itself (note the "$" symbol to reference macros).
22+
% - Function: Introduces a new scalar output that is a function of other scalar
23+
% outputs, it cannot reference fields (e.g. velocity).
24+
% - AreaAvg and AreaInt: Computes an area average or integral of a field (the
25+
% expression) over the list of markers.
26+
% - MassFlowAvg and MassFlowInt: Computes a mass flow average or integral.
27+
% NOTE: Each custom output can only use one type, e.g. it is not possible to
28+
% write 'p_drop : AreaAvg{PRESSURE}[inlet] - AreaAvg{PRESSURE}[outlet]'. This
29+
% would need to be separated into two AreaAvg outputs and one Function to
30+
% compute their difference.
31+
CUSTOM_OUTPUTS= 'velocity : Macro{sqrt(pow(VELOCITY_X, 2) + pow(VELOCITY_Y, 2) + pow(VELOCITY_Z, 2))};\
32+
avg_vel : AreaAvg{$velocity}[z_minus, z_plus];\
33+
var_vel : AreaAvg{pow($velocity - avg_vel, 2)}[z_minus, z_plus];\
34+
dev_vel : Function{sqrt(var_vel) / avg_vel}'
35+
%
1536
% "COMBO" is the name and group of the output for the objective function
16-
% (regardless of definition).
37+
% (regardless of definition). "CUSTOM" is the group for all custom outpus.
1738
SCREEN_OUTPUT= INNER_ITER, RMS_DENSITY, RMS_ENERGY, LINSOL_RESIDUAL, FORCE_Z,\
18-
SURFACE_MASSFLOW, SURFACE_TOTAL_TEMPERATURE, COMBO
19-
HISTORY_OUTPUT = ITER, AERO_COEFF, FLOW_COEFF, FLOW_COEFF_SURF, COMBO
39+
SURFACE_MASSFLOW, SURFACE_TOTAL_TEMPERATURE, avg_vel, dev_vel, COMBO
40+
HISTORY_OUTPUT = ITER, AERO_COEFF, FLOW_COEFF, FLOW_COEFF_SURF, CUSTOM, COMBO
2041
OBJECTIVE_FUNCTION= CUSTOM_OBJFUNC
2142
% Here we define how the custom objective is computed from other outputs. For
2243
% example, force in the z direction (computed for all MARKER_MONITORING and part
@@ -27,7 +48,7 @@ OBJECTIVE_FUNCTION= CUSTOM_OBJFUNC
2748
% For multizone problems the CUSTOM_OBJFUNC should be defined for each zone
2849
% individually (with the outputs of that zone), the total for the problem is
2950
% the sum over zones, see disc_adj_fsi/Airfoil_2d.
30-
CUSTOM_OBJFUNC= '1e3 * (FORCE_Z + fabs(SURFACE_MASSFLOW[1]))'
51+
CUSTOM_OBJFUNC= '1e3 * (FORCE_Z + fabs(SURFACE_MASSFLOW[1])) + dev_vel'
3152

3253
% -------------------- COMPRESSIBLE FREE-STREAM DEFINITION --------------------%
3354
%

config_template.cfg

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1650,6 +1650,9 @@ SCREEN_OUTPUT= (INNER_ITER, RMS_DENSITY, RMS_MOMENTUM-X, RMS_MOMENTUM-Y, RMS_ENE
16501650
% History output groups (use 'SU2_CFD -d <config_file>' to view list of available fields)
16511651
HISTORY_OUTPUT= (ITER, RMS_RES)
16521652
%
1653+
% User defined functions available on screen and history output. See TestCases/user_defined_functions/.
1654+
CUSTOM_OUTPUTS= ''
1655+
%
16531656
% Volume output fields/groups (use 'SU2_CFD -d <config_file>' to view list of available fields)
16541657
VOLUME_OUTPUT= (COORDINATES, SOLUTION, PRIMITIVE)
16551658
%

0 commit comments

Comments
 (0)