Skip to content

Commit 76d1ef2

Browse files
authored
Merge pull request #1587 from su2code/allow_groups_for_screen_output
Allow field groups in SCREEN_OUTPUT (e.g. RMS_RES like for HISTORY_OUTPUT)
2 parents c204683 + d8b83f3 commit 76d1ef2

File tree

4 files changed

+106
-104
lines changed

4 files changed

+106
-104
lines changed

QuickStart/inv_NACA0012.cfg

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -254,7 +254,7 @@ CONV_CAUCHY_ELEMS= 100
254254
% Epsilon to control the series convergence
255255
CONV_CAUCHY_EPS= 1E-6
256256
%
257-
SCREEN_OUTPUT=(INNER_ITER, WALL_TIME, RMS_DENSITY, LIFT, DRAG, CAUCHY_SENS_PRESS, CAUCHY_DRAG RMS_ADJ_DENSITY RMS_ADJ_ENERGY)
257+
SCREEN_OUTPUT=(INNER_ITER, WALL_TIME, RMS_RES, LIFT, DRAG, CAUCHY_SENS_PRESS, CAUCHY_DRAG RMS_ADJ_DENSITY RMS_ADJ_ENERGY)
258258

259259
% ------------------------- INPUT/OUTPUT INFORMATION --------------------------%
260260
% Mesh input file

SU2_CFD/include/output/COutput.hpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ class COutput {
9090

9191
string historyFilename; /*!< \brief The history filename*/
9292
ofstream histFile; /*!< \brief Output file stream for the history */
93-
93+
9494
bool cauchyTimeConverged; /*! \brief: Flag indicating that solver is already converged. Needed for writing restart files. */
9595

9696
/** \brief Enum to identify the screen output format. */
@@ -155,6 +155,10 @@ class COutput {
155155
/*! \brief Number of requested screen field names in the config file. */
156156
unsigned short nRequestedScreenFields;
157157

158+
/*! \brief Caches to avoid hashing the output maps to retrieve field values. */
159+
std::vector<const su2double*> requestedHistoryFieldCache;
160+
std::vector<const HistoryOutputField*> requestedScreenFieldCache;
161+
158162
PrintingToolbox::CTablePrinter* convergenceTable; //!< Convergence output table structure
159163
PrintingToolbox::CTablePrinter* multiZoneHeaderTable; //!< Multizone header output structure
160164
PrintingToolbox::CTablePrinter* historyFileTable; //!< Table structure for writing to history file

SU2_CFD/src/output/COutput.cpp

Lines changed: 99 additions & 100 deletions
Original file line numberDiff line numberDiff line change
@@ -912,20 +912,20 @@ void COutput::WriteToFile(CConfig *config, CGeometry *geometry, OUTPUT_TYPE form
912912
}
913913

914914
bool COutput::GetCauchyCorrectedTimeConvergence(const CConfig *config){
915-
if(!cauchyTimeConverged && TimeConvergence && config->GetTime_Marching() == TIME_MARCHING::DT_STEPPING_2ND){
916-
// Change flags for 2nd order Time stepping: In case of convergence, this iter and next iter gets written out. then solver stops
917-
cauchyTimeConverged = TimeConvergence;
918-
TimeConvergence = false;
919-
}
920-
else if(cauchyTimeConverged){
921-
TimeConvergence = cauchyTimeConverged;
922-
}
923-
return TimeConvergence;
915+
if(!cauchyTimeConverged && TimeConvergence && config->GetTime_Marching() == TIME_MARCHING::DT_STEPPING_2ND){
916+
// Change flags for 2nd order Time stepping: In case of convergence, this iter and next iter gets written out. then solver stops
917+
cauchyTimeConverged = TimeConvergence;
918+
TimeConvergence = false;
919+
}
920+
else if(cauchyTimeConverged){
921+
TimeConvergence = cauchyTimeConverged;
922+
}
923+
return TimeConvergence;
924924
}
925925

926926
bool COutput::SetResult_Files(CGeometry *geometry, CConfig *config, CSolver** solver_container,
927927
unsigned long iter, bool force_writing){
928-
928+
929929
bool isFileWrite=false;
930930
unsigned short nVolumeFiles = config->GetnVolumeOutputFiles();
931931
auto VolumeFiles = config->GetVolumeOutputFiles();
@@ -938,7 +938,7 @@ bool COutput::SetResult_Files(CGeometry *geometry, CConfig *config, CSolver** so
938938
/*--- Collect the volume data from the solvers.
939939
* If time-domain is enabled, we also load the data although we don't output it,
940940
* since we might want to do time-averaging. ---*/
941-
if (WriteVolume_Output(config, iter, force_writing || cauchyTimeConverged, iFile) || config->GetTime_Domain())
941+
if (WriteVolume_Output(config, iter, force_writing || cauchyTimeConverged, iFile) || config->GetTime_Domain())
942942
LoadDataIntoSorter(config, geometry, solver_container);
943943

944944
if (!(WriteVolume_Output(config, iter, force_writing || cauchyTimeConverged, iFile))) continue;
@@ -955,7 +955,7 @@ bool COutput::SetResult_Files(CGeometry *geometry, CConfig *config, CSolver** so
955955

956956
/*--- Loop through all requested output files and write
957957
* the partitioned and sorted data stored in the data sorters. ---*/
958-
958+
959959
WriteToFile(config, geometry, VolumeFiles[iFile]);
960960

961961
if (rank == MASTER_NODE && !isFileWrite){
@@ -1216,34 +1216,31 @@ void COutput::SetHistoryFile_Header(const CConfig *config) {
12161216

12171217
void COutput::SetHistoryFile_Output(const CConfig *config) {
12181218

1219-
unsigned short iField_Output = 0,
1220-
iReqField = 0,
1221-
iMarker = 0;
1222-
1223-
for (iField_Output = 0; iField_Output < historyOutput_List.size(); iField_Output++){
1224-
const string &fieldIdentifier = historyOutput_List[iField_Output];
1225-
const HistoryOutputField &field = historyOutput_Map.at(fieldIdentifier);
1226-
for (iReqField = 0; iReqField < nRequestedHistoryFields; iReqField++){
1227-
const string &requestedField = requestedHistoryFields[iReqField];
1228-
if (requestedField == field.outputGroup || (requestedField == fieldIdentifier)){
1229-
(*historyFileTable) << field.value;
1219+
if (requestedHistoryFieldCache.empty()) {
1220+
for (const auto& fieldIdentifier : historyOutput_List){
1221+
const auto& field = historyOutput_Map.at(fieldIdentifier);
1222+
for (const auto& requestedField : requestedHistoryFields) {
1223+
if ((requestedField == field.outputGroup) || (requestedField == fieldIdentifier)) {
1224+
requestedHistoryFieldCache.push_back(&field.value);
1225+
}
12301226
}
12311227
}
1232-
}
12331228

1234-
for (iField_Output = 0; iField_Output < historyOutputPerSurface_List.size(); iField_Output++){
1235-
const string &fieldIdentifier = historyOutputPerSurface_List[iField_Output];
1236-
for (iMarker = 0; iMarker < historyOutputPerSurface_Map[fieldIdentifier].size(); iMarker++){
1237-
const HistoryOutputField &field = historyOutputPerSurface_Map.at(fieldIdentifier)[iMarker];
1238-
for (iReqField = 0; iReqField < nRequestedHistoryFields; iReqField++){
1239-
const string &requestedField = requestedHistoryFields[iReqField];
1240-
if (requestedField == field.outputGroup || (requestedField == fieldIdentifier)){
1241-
(*historyFileTable) << field.value;
1229+
for (const auto& fieldIdentifier : historyOutputPerSurface_List) {
1230+
for (const auto& field : historyOutputPerSurface_Map.at(fieldIdentifier)) {
1231+
for (const auto& requestedField : requestedHistoryFields){
1232+
if ((requestedField == field.outputGroup) || (requestedField == fieldIdentifier)) {
1233+
requestedHistoryFieldCache.push_back(&field.value);
1234+
}
12421235
}
12431236
}
12441237
}
12451238
}
12461239

1240+
for (const auto* valPtr : requestedHistoryFieldCache) {
1241+
(*historyFileTable) << *valPtr;
1242+
}
1243+
12471244
/*--- Print the string to file and remove the last two characters (a separator and a space) ---*/
12481245

12491246
histFile.flush();
@@ -1258,49 +1255,41 @@ void COutput::SetScreen_Header(const CConfig *config) {
12581255

12591256
void COutput::SetScreen_Output(const CConfig *config) {
12601257

1261-
for (const auto& RequestedField : requestedScreenFields) {
1262-
const auto it1 = historyOutput_Map.find(RequestedField);
1263-
if (it1 != historyOutput_Map.end()) {
1264-
const auto& field = it1->second;
1265-
stringstream out;
1266-
switch (field.screenFormat) {
1267-
case ScreenOutputFormat::INTEGER:
1268-
PrintingToolbox::PrintScreenInteger(out, SU2_TYPE::Int(field.value), fieldWidth);
1269-
break;
1270-
case ScreenOutputFormat::FIXED:
1271-
PrintingToolbox::PrintScreenFixed(out, field.value, fieldWidth);
1272-
break;
1273-
case ScreenOutputFormat::SCIENTIFIC:
1274-
PrintingToolbox::PrintScreenScientific(out, field.value, fieldWidth);
1275-
break;
1276-
case ScreenOutputFormat::PERCENT:
1277-
PrintingToolbox::PrintScreenPercent(out, field.value, fieldWidth);
1278-
break;
1258+
if (requestedScreenFieldCache.empty()) {
1259+
for (const auto& RequestedField : requestedScreenFields) {
1260+
const auto it1 = historyOutput_Map.find(RequestedField);
1261+
if (it1 != historyOutput_Map.end()) {
1262+
requestedScreenFieldCache.push_back(&it1->second);
12791263
}
1280-
(*convergenceTable) << out.str();
1281-
}
1282-
const auto it2 = historyOutputPerSurface_Map.find(RequestedField);
1283-
if (it2 != historyOutputPerSurface_Map.end()) {
1284-
for (const auto& field : it2->second) {
1285-
stringstream out;
1286-
switch (field.screenFormat) {
1287-
case ScreenOutputFormat::INTEGER:
1288-
PrintingToolbox::PrintScreenInteger(out, SU2_TYPE::Int(field.value), fieldWidth);
1289-
break;
1290-
case ScreenOutputFormat::FIXED:
1291-
PrintingToolbox::PrintScreenFixed(out, field.value, fieldWidth);
1292-
break;
1293-
case ScreenOutputFormat::SCIENTIFIC:
1294-
PrintingToolbox::PrintScreenScientific(out, field.value, fieldWidth);
1295-
break;
1296-
case ScreenOutputFormat::PERCENT:
1297-
PrintingToolbox::PrintScreenPercent(out, field.value, fieldWidth);
1298-
break;
1264+
const auto it2 = historyOutputPerSurface_Map.find(RequestedField);
1265+
if (it2 != historyOutputPerSurface_Map.end()) {
1266+
for (size_t i = 0; i < it2->second.size(); ++i) {
1267+
requestedScreenFieldCache.push_back(&it2->second[i]);
12991268
}
1300-
(*convergenceTable) << out.str();
13011269
}
13021270
}
13031271
}
1272+
1273+
for (const auto* fieldPtr : requestedScreenFieldCache) {
1274+
const auto& field = *fieldPtr;
1275+
stringstream out;
1276+
switch (field.screenFormat) {
1277+
case ScreenOutputFormat::INTEGER:
1278+
PrintingToolbox::PrintScreenInteger(out, SU2_TYPE::Int(field.value), fieldWidth);
1279+
break;
1280+
case ScreenOutputFormat::FIXED:
1281+
PrintingToolbox::PrintScreenFixed(out, field.value, fieldWidth);
1282+
break;
1283+
case ScreenOutputFormat::SCIENTIFIC:
1284+
PrintingToolbox::PrintScreenScientific(out, field.value, fieldWidth);
1285+
break;
1286+
case ScreenOutputFormat::PERCENT:
1287+
PrintingToolbox::PrintScreenPercent(out, field.value, fieldWidth);
1288+
break;
1289+
}
1290+
(*convergenceTable) << out.str();
1291+
}
1292+
13041293
SetAdditionalScreenOutput(config);
13051294
}
13061295

@@ -1422,11 +1411,31 @@ void COutput::CheckHistoryOutput() {
14221411

14231412
/*--- Set screen convergence output header and remove unavailable fields ---*/
14241413

1414+
vector<string> requestWithExpandedGroups;
1415+
1416+
for (const auto& requestedField : requestedScreenFields) {
1417+
bool isGroup = false;
1418+
for (const auto& name : historyOutput_List) {
1419+
if (requestedField == historyOutput_Map.at(name).outputGroup) {
1420+
isGroup = true;
1421+
requestWithExpandedGroups.push_back(name);
1422+
}
1423+
}
1424+
for (const auto& name : historyOutputPerSurface_List) {
1425+
if (requestedField == historyOutputPerSurface_Map.at(name).front().outputGroup) {
1426+
isGroup = true;
1427+
requestWithExpandedGroups.push_back(name);
1428+
}
1429+
}
1430+
if (!isGroup) {
1431+
requestWithExpandedGroups.push_back(requestedField);
1432+
}
1433+
}
1434+
requestedScreenFields = std::move(requestWithExpandedGroups);
1435+
14251436
vector<string> FieldsToRemove;
1426-
vector<bool> FoundField(nRequestedHistoryFields, false);
14271437

1428-
for (unsigned short iReqField = 0; iReqField < nRequestedScreenFields; iReqField++) {
1429-
const auto& requestedField = requestedScreenFields[iReqField];
1438+
for (const auto& requestedField : requestedScreenFields) {
14301439
const auto it1 = historyOutput_Map.find(requestedField);
14311440
if (it1 != historyOutput_Map.end()) {
14321441
convergenceTable->AddColumn(it1->second.fieldName, fieldWidth);
@@ -1444,11 +1453,10 @@ void COutput::CheckHistoryOutput() {
14441453

14451454
/*--- Remove fields which are not defined --- */
14461455

1447-
for (unsigned short iReqField = 0; iReqField < FieldsToRemove.size(); iReqField++){
1456+
for (unsigned short iReqField = 0; iReqField < FieldsToRemove.size(); iReqField++) {
14481457
if (rank == MASTER_NODE) {
1449-
if (iReqField == 0){
1450-
cout << " Info: Ignoring the following screen output fields:" << endl;
1451-
cout << " ";
1458+
if (iReqField == 0) {
1459+
cout << " Info: Ignoring the following screen output fields:\n ";
14521460
}
14531461
cout << FieldsToRemove[iReqField];
14541462
if (iReqField != FieldsToRemove.size()-1) {
@@ -1475,32 +1483,24 @@ void COutput::CheckHistoryOutput() {
14751483
/*--- Remove unavailable fields from the history file output ---*/
14761484

14771485
FieldsToRemove.clear();
1478-
FoundField = vector<bool>(nRequestedHistoryFields, false);
1479-
for (unsigned short iField_Output = 0; iField_Output < historyOutput_List.size(); iField_Output++){
1480-
const string &fieldReference = historyOutput_List[iField_Output];
1481-
if (historyOutput_Map.count(fieldReference) > 0){
1482-
const HistoryOutputField &field = historyOutput_Map.at(fieldReference);
1483-
for (unsigned short iReqField = 0; iReqField < nRequestedHistoryFields; iReqField++){
1484-
const auto& requestedField = requestedHistoryFields[iReqField];
1485-
string fieldname_uppercase = field.fieldName;
1486-
transform(fieldname_uppercase.begin(), fieldname_uppercase.end(), fieldname_uppercase.begin(), ::toupper);
1486+
vector<bool> FoundField(nRequestedHistoryFields, false);
14871487

1488-
if ((requestedField == field.outputGroup) || (fieldReference==fieldname_uppercase)){
1489-
FoundField[iReqField] = true;
1490-
}
1488+
for (const auto& fieldReference : historyOutput_List) {
1489+
const auto &field = historyOutput_Map.at(fieldReference);
1490+
for (unsigned short iReqField = 0; iReqField < nRequestedHistoryFields; iReqField++) {
1491+
const auto& requestedField = requestedHistoryFields[iReqField];
1492+
if ((requestedField == field.outputGroup) || (requestedField == fieldReference)) {
1493+
FoundField[iReqField] = true;
14911494
}
14921495
}
14931496
}
14941497

1495-
for (unsigned short iField_Output = 0; iField_Output < historyOutputPerSurface_List.size(); iField_Output++){
1496-
const string &fieldReference = historyOutputPerSurface_List[iField_Output];
1497-
if (historyOutputPerSurface_Map.count(fieldReference) > 0) {
1498-
for (const auto &Field : historyOutputPerSurface_Map.at(fieldReference)) {
1499-
for (unsigned short iReqField = 0; iReqField < nRequestedHistoryFields; iReqField++){
1500-
const auto& requestedField = requestedHistoryFields[iReqField];
1501-
if (requestedField == Field.outputGroup){
1502-
FoundField[iReqField] = true;
1503-
}
1498+
for (const auto& fieldReference : historyOutputPerSurface_List) {
1499+
for (const auto& field : historyOutputPerSurface_Map.at(fieldReference)) {
1500+
for (unsigned short iReqField = 0; iReqField < nRequestedHistoryFields; iReqField++){
1501+
const auto& requestedField = requestedHistoryFields[iReqField];
1502+
if ((requestedField == field.outputGroup) || (requestedField == fieldReference)) {
1503+
FoundField[iReqField] = true;
15041504
}
15051505
}
15061506
}
@@ -1517,8 +1517,7 @@ void COutput::CheckHistoryOutput() {
15171517
for (unsigned short iReqField = 0; iReqField < FieldsToRemove.size(); iReqField++){
15181518
if (rank == MASTER_NODE) {
15191519
if (iReqField == 0){
1520-
cout << " Info: Ignoring the following history output groups:" << endl;
1521-
cout << " ";
1520+
cout << " Info: Ignoring the following history output groups:\n ";
15221521
}
15231522
cout << FieldsToRemove[iReqField];
15241523
if (iReqField != FieldsToRemove.size()-1){

TestCases/navierstokes/periodic2D/config.cfg

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -72,5 +72,4 @@ MESH_FORMAT= SU2
7272
MESH_FILENAME= sector.su2
7373
OUTPUT_WRT_FREQ= 9999
7474
%
75-
SCREEN_OUTPUT= ( INNER_ITER, RMS_DENSITY, RMS_MOMENTUM-X, RMS_MOMENTUM-Y,\
76-
RMS_ENERGY, LINSOL_RESIDUAL, SURFACE_PRESSURE_DROP )
75+
SCREEN_OUTPUT= ( INNER_ITER, RMS_RES, LINSOL_RESIDUAL, SURFACE_PRESSURE_DROP )

0 commit comments

Comments
 (0)