Skip to content

Commit 527f42b

Browse files
authored
Merge pull request #1986 from su2code/py_wrapper_outputs
Expose all history outputs via the python wrapper
2 parents 3f68501 + 6647e7b commit 527f42b

7 files changed

Lines changed: 128 additions & 214 deletions

File tree

SU2_CFD/include/drivers/CDriver.hpp

Lines changed: 56 additions & 98 deletions
Original file line numberDiff line numberDiff line change
@@ -356,6 +356,58 @@ class CDriver : public CDriverBase {
356356
*/
357357
void Print_DirectResidual(RECORDING kind_recording);
358358

359+
/*!
360+
* \brief Set the solution of all solvers (adjoint or primal) in a zone.
361+
* \param[in] iZone - Index of the zone.
362+
* \param[in] adjoint - True to consider adjoint solvers instead of primal.
363+
* \param[in] solution - Solution object with interface (iPoint,iVar).
364+
* \tparam Old - If true set "old solutions" instead.
365+
*/
366+
template <class Container, bool Old = false>
367+
void SetAllSolutions(unsigned short iZone, bool adjoint, const Container& solution) {
368+
const auto nPoint = geometry_container[iZone][INST_0][MESH_0]->GetnPoint();
369+
for (auto iSol = 0u, offset = 0u; iSol < MAX_SOLS; ++iSol) {
370+
auto solver = solver_container[iZone][INST_0][MESH_0][iSol];
371+
if (!(solver && (solver->GetAdjoint() == adjoint))) continue;
372+
for (auto iPoint = 0ul; iPoint < nPoint; ++iPoint)
373+
for (auto iVar = 0ul; iVar < solver->GetnVar(); ++iVar)
374+
if (!Old) {
375+
solver->GetNodes()->SetSolution(iPoint, iVar, solution(iPoint, offset + iVar));
376+
} else {
377+
solver->GetNodes()->SetSolution_Old(iPoint, iVar, solution(iPoint, offset + iVar));
378+
}
379+
offset += solver->GetnVar();
380+
}
381+
}
382+
383+
/*!
384+
* \brief Set the "old solution" of all solvers (adjoint or primal) in a zone.
385+
*/
386+
template <class Container>
387+
void SetAllSolutionsOld(unsigned short iZone, bool adjoint, const Container& solution) {
388+
SetAllSolutions<Container, true>(iZone, adjoint, solution);
389+
}
390+
391+
/*!
392+
* \brief Get the solution of all solvers (adjoint or primal) in a zone.
393+
* \param[in] iZone - Index of the zone.
394+
* \param[in] adjoint - True to consider adjoint solvers instead of primal.
395+
* \param[out] solution - Solution object with interface (iPoint,iVar).
396+
*/
397+
template <class Container>
398+
void GetAllSolutions(unsigned short iZone, bool adjoint, Container& solution) const {
399+
const auto nPoint = geometry_container[iZone][INST_0][MESH_0]->GetnPoint();
400+
for (auto iSol = 0u, offset = 0u; iSol < MAX_SOLS; ++iSol) {
401+
auto solver = solver_container[iZone][INST_0][MESH_0][iSol];
402+
if (!(solver && (solver->GetAdjoint() == adjoint))) continue;
403+
const auto& sol = solver->GetNodes()->GetSolution();
404+
for (auto iPoint = 0ul; iPoint < nPoint; ++iPoint)
405+
for (auto iVar = 0ul; iVar < solver->GetnVar(); ++iVar)
406+
solution(iPoint, offset + iVar) = SU2_TYPE::GetValue(sol(iPoint, iVar));
407+
offset += solver->GetnVar();
408+
}
409+
}
410+
359411
public:
360412
/*!
361413
* \brief Launch the computation for all zones and all physics.
@@ -413,56 +465,14 @@ class CDriver : public CDriverBase {
413465
void BoundaryConditionsUpdate();
414466

415467
/*!
416-
* \brief Get the total drag.
417-
* \return Total drag.
418-
*/
419-
passivedouble Get_Drag() const;
420-
421-
/*!
422-
* \brief Get the total lift.
423-
* \return Total lift.
424-
*/
425-
passivedouble Get_Lift() const;
426-
427-
/*!
428-
* \brief Get the total x moment.
429-
* \return Total x moment.
430-
*/
431-
passivedouble Get_Mx() const;
432-
433-
/*!
434-
* \brief Get the total y moment.
435-
* \return Total y moment.
436-
*/
437-
passivedouble Get_My() const;
438-
439-
/*!
440-
* \brief Get the total z moment.
441-
* \return Total z moment.
442-
*/
443-
passivedouble Get_Mz() const;
444-
445-
/*!
446-
* \brief Get the total drag coefficient.
447-
* \return Total drag coefficient.
448-
*/
449-
passivedouble Get_DragCoeff() const;
450-
451-
/*!
452-
* \brief Get the total lift coefficient.
453-
* \return Total lift coefficient.
454-
*/
455-
passivedouble Get_LiftCoeff() const;
456-
457-
/*!
458-
* \brief Get the number of external iterations.
459-
* \return Number of external iterations.
468+
* \brief Get the number of time iterations.
469+
* \return Number of time iterations.
460470
*/
461471
unsigned long GetNumberTimeIter() const;
462472

463473
/*!
464-
* \brief Get the current external iteration.
465-
* \return Current external iteration.
474+
* \brief Get the current time iteration.
475+
* \return Current time iteration.
466476
*/
467477
unsigned long GetTimeIter() const;
468478

@@ -518,58 +528,6 @@ class CDriver : public CDriverBase {
518528
}
519529
return nVar;
520530
}
521-
522-
/*!
523-
* \brief Set the solution of all solvers (adjoint or primal) in a zone.
524-
* \param[in] iZone - Index of the zone.
525-
* \param[in] adjoint - True to consider adjoint solvers instead of primal.
526-
* \param[in] solution - Solution object with interface (iPoint,iVar).
527-
* \tparam Old - If true set "old solutions" instead.
528-
*/
529-
template <class Container, bool Old = false>
530-
void SetAllSolutions(unsigned short iZone, bool adjoint, const Container& solution) {
531-
const auto nPoint = geometry_container[iZone][INST_0][MESH_0]->GetnPoint();
532-
for (auto iSol = 0u, offset = 0u; iSol < MAX_SOLS; ++iSol) {
533-
auto solver = solver_container[iZone][INST_0][MESH_0][iSol];
534-
if (!(solver && (solver->GetAdjoint() == adjoint))) continue;
535-
for (auto iPoint = 0ul; iPoint < nPoint; ++iPoint)
536-
for (auto iVar = 0ul; iVar < solver->GetnVar(); ++iVar)
537-
if (!Old) {
538-
solver->GetNodes()->SetSolution(iPoint, iVar, solution(iPoint, offset + iVar));
539-
} else {
540-
solver->GetNodes()->SetSolution_Old(iPoint, iVar, solution(iPoint, offset + iVar));
541-
}
542-
offset += solver->GetnVar();
543-
}
544-
}
545-
546-
/*!
547-
* \brief Set the "old solution" of all solvers (adjoint or primal) in a zone.
548-
*/
549-
template <class Container>
550-
void SetAllSolutionsOld(unsigned short iZone, bool adjoint, const Container& solution) {
551-
SetAllSolutions<Container, true>(iZone, adjoint, solution);
552-
}
553-
554-
/*!
555-
* \brief Get the solution of all solvers (adjoint or primal) in a zone.
556-
* \param[in] iZone - Index of the zone.
557-
* \param[in] adjoint - True to consider adjoint solvers instead of primal.
558-
* \param[out] solution - Solution object with interface (iPoint,iVar).
559-
*/
560-
template <class Container>
561-
void GetAllSolutions(unsigned short iZone, bool adjoint, Container& solution) const {
562-
const auto nPoint = geometry_container[iZone][INST_0][MESH_0]->GetnPoint();
563-
for (auto iSol = 0u, offset = 0u; iSol < MAX_SOLS; ++iSol) {
564-
auto solver = solver_container[iZone][INST_0][MESH_0][iSol];
565-
if (!(solver && (solver->GetAdjoint() == adjoint))) continue;
566-
const auto& sol = solver->GetNodes()->GetSolution();
567-
for (auto iPoint = 0ul; iPoint < nPoint; ++iPoint)
568-
for (auto iVar = 0ul; iVar < solver->GetnVar(); ++iVar)
569-
solution(iPoint, offset + iVar) = SU2_TYPE::GetValue(sol(iPoint, iVar));
570-
offset += solver->GetnVar();
571-
}
572-
}
573531
};
574532

575533
/*!

SU2_CFD/include/drivers/CDriverBase.hpp

Lines changed: 50 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -107,11 +107,6 @@ class CDriverBase {
107107
*/
108108
virtual void Update(){}
109109

110-
/*!
111-
* \brief A virtual member.
112-
*/
113-
virtual void Update_Legacy(){}
114-
115110
/*!
116111
* \brief A virtual member.
117112
*/
@@ -125,6 +120,56 @@ class CDriverBase {
125120
/// \addtogroup PySU2
126121
/// @{
127122

123+
/*!
124+
* \brief Get the list of available outputs.
125+
* \return List of output names.
126+
*/
127+
inline vector<string> GetOutputNames() const { return output_container[MESH_0]->GetHistoryOutputList(); }
128+
129+
/*!
130+
* \brief Get the value of one of the available history outputs.
131+
* \return Value of the output.
132+
*/
133+
inline passivedouble GetOutputValue(const std::string& output_name) const {
134+
return SU2_TYPE::GetValue(output_container[MESH_0]->GetHistoryFieldValue(output_name));
135+
}
136+
137+
/*!
138+
* \brief Get the list of available surface outputs on **both** MARKER_MONITORING and MARKER_ANALYZE.
139+
* \return List of surface output names.
140+
*/
141+
inline vector<string> GetMarkerOutputNames() const {
142+
return output_container[MESH_0]->GetHistoryOutputPerSurfaceList();
143+
}
144+
145+
/*!
146+
* \brief Get the value of one of the available surface outputs at a given MARKER_MONITORING.
147+
* \return Value of the output.
148+
*/
149+
inline passivedouble GetMarkerMonitoringOutputValue(const std::string& output_name,
150+
const std::string& marker_monitoring) const {
151+
for (auto iMarker = 0u; iMarker < main_config->GetnMarker_Monitoring(); ++iMarker) {
152+
if (marker_monitoring == main_config->GetMarker_Monitoring_TagBound(iMarker))
153+
return SU2_TYPE::GetValue(output_container[MESH_0]->GetHistoryFieldValuePerSurface(output_name, iMarker));
154+
}
155+
SU2_MPI::Error(marker_monitoring + " is not in MARKER_MONITORING.", CURRENT_FUNCTION);
156+
return 0;
157+
}
158+
159+
/*!
160+
* \brief Get the value of one of the available surface outputs at a given MARKER_ANALYZE.
161+
* \return Value of the output.
162+
*/
163+
inline passivedouble GetMarkerAnalyzeOutputValue(const std::string& output_name,
164+
const std::string& marker_analyze) const {
165+
for (auto iMarker = 0u; iMarker < main_config->GetnMarker_Analyze(); ++iMarker) {
166+
if (marker_analyze == main_config->GetMarker_Analyze_TagBound(iMarker))
167+
return SU2_TYPE::GetValue(output_container[MESH_0]->GetHistoryFieldValuePerSurface(output_name, iMarker));
168+
}
169+
SU2_MPI::Error(marker_analyze + " is not in MARKER_ANALYZE.", CURRENT_FUNCTION);
170+
return 0;
171+
}
172+
128173
/*!
129174
* \brief Get the number of design variables.
130175
* \return Number of design variables.

SU2_CFD/include/output/COutput.hpp

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -446,8 +446,11 @@ class COutput {
446446
* \param[in] field - Name of the field
447447
* \return Value of the field
448448
*/
449-
su2double GetHistoryFieldValue(const string& field) const {
450-
return historyOutput_Map.at(field).value;
449+
su2double GetHistoryFieldValue(const string& name) const {
450+
auto it = historyOutput_Map.find(name);
451+
if (it != historyOutput_Map.end()) return it->second.value;
452+
SU2_MPI::Error("Cannot find output field with name " + name, CURRENT_FUNCTION);
453+
return 0;
451454
}
452455

453456
/*!
@@ -456,8 +459,11 @@ class COutput {
456459
* \param[in] iMarker - Index of the surface marker
457460
* \return Value of the field
458461
*/
459-
su2double GetHistoryFieldValuePerSurface(const string& field, unsigned short iMarker) const {
460-
return historyOutputPerSurface_Map.at(field)[iMarker].value;
462+
su2double GetHistoryFieldValuePerSurface(const string& name, unsigned short iMarker) const {
463+
auto it = historyOutputPerSurface_Map.find(name);
464+
if (it != historyOutputPerSurface_Map.end()) return it->second[iMarker].value;
465+
SU2_MPI::Error("Cannot find output field with name " + name, CURRENT_FUNCTION);
466+
return 0;
461467
}
462468

463469
/*!
@@ -634,7 +640,7 @@ class COutput {
634640
if (it != historyOutput_Map.end()){
635641
it->second.value = value;
636642
} else {
637-
SU2_MPI::Error(string("Cannot find output field with name ") + name, CURRENT_FUNCTION);
643+
SU2_MPI::Error("Cannot find output field with name " + name, CURRENT_FUNCTION);
638644
}
639645
}
640646

@@ -718,7 +724,6 @@ class COutput {
718724
volumeOutput_List.push_back(name);
719725
}
720726

721-
722727
/*!
723728
* \brief Set the value of a volume output field
724729
* \param[in] name - Name of the field.

SU2_CFD/src/output/CFlowOutput.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1368,6 +1368,8 @@ void CFlowOutput::LoadSurfaceData(CConfig *config, CGeometry *geometry, CSolver
13681368
void CFlowOutput::AddAerodynamicCoefficients(const CConfig* config) {
13691369

13701370
/// BEGIN_GROUP: AERO_COEFF, DESCRIPTION: Sum of the aerodynamic coefficients and forces on all surfaces (markers) set with MARKER_MONITORING.
1371+
/// DESCRIPTION: Reference force for aerodynamic coefficients
1372+
AddHistoryOutput("REFERENCE_FORCE", "RefForce", ScreenOutputFormat::FIXED, "AERO_COEFF", "Reference force used to compute aerodynamic coefficients", HistoryFieldType::COEFFICIENT);
13711373
/// DESCRIPTION: Drag coefficient
13721374
AddHistoryOutput("DRAG", "CD", ScreenOutputFormat::FIXED, "AERO_COEFF", "Total drag coefficient on all surfaces set with MARKER_MONITORING", HistoryFieldType::COEFFICIENT);
13731375
/// DESCRIPTION: Lift coefficient
@@ -1425,6 +1427,7 @@ void CFlowOutput::AddAerodynamicCoefficients(const CConfig* config) {
14251427

14261428
void CFlowOutput::SetAerodynamicCoefficients(const CConfig* config, const CSolver* flow_solver){
14271429

1430+
SetHistoryOutputValue("REFERENCE_FORCE", flow_solver->GetAeroCoeffsReferenceForce());
14281431
SetHistoryOutputValue("DRAG", flow_solver->GetTotal_CD());
14291432
SetHistoryOutputValue("LIFT", flow_solver->GetTotal_CL());
14301433
if (nDim == 3)

0 commit comments

Comments
 (0)