Skip to content

Commit c5e97f8

Browse files
authored
Multizone py wrapper example (FSI) (#2111)
* checkpoint naming and update some functions * add FSI example with additional custom load via the python wrapper * remove mesh files * fix segfault * add some arm64 values * disable polar naca on arm64
1 parent b00b87b commit c5e97f8

20 files changed

+386
-104
lines changed

SU2_CFD/include/drivers/CDriverBase.hpp

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ class CDriverBase {
5454
UsedTime; /*!< \brief Elapsed time between Start and Stop point of the timer. */
5555

5656
unsigned long TimeIter;
57-
unsigned short selected_iZone = ZONE_0; /*!< \brief Selected zone for the driver. Defaults to ZONE_0 */
57+
unsigned short selected_zone = ZONE_0; /*!< \brief Selected zone for the driver. Defaults to ZONE_0 */
5858
unsigned short iMesh, /*!< \brief Iterator on mesh levels. */
5959
iZone, /*!< \brief Iterator on zones. */
6060
nZone, /*!< \brief Total number of zones in the problem. */
@@ -227,7 +227,7 @@ class CDriverBase {
227227
SU2_MPI::Error("Initial coordinates are only available with DEFORM_MESH= YES", CURRENT_FUNCTION);
228228
}
229229
auto* coords =
230-
const_cast<su2activematrix*>(solver_container[selected_iZone][INST_0][MESH_0][MESH_SOL]->GetNodes()->GetMesh_Coord());
230+
const_cast<su2activematrix*>(solver_container[selected_zone][INST_0][MESH_0][MESH_SOL]->GetNodes()->GetMesh_Coord());
231231
return CPyWrapperMatrixView(*coords, "InitialCoordinates", true);
232232
}
233233

@@ -241,7 +241,7 @@ class CDriverBase {
241241
if (iMarker >= GetNumberMarkers()) SU2_MPI::Error("Marker index exceeds size.", CURRENT_FUNCTION);
242242

243243
auto* coords =
244-
const_cast<su2activematrix*>(solver_container[selected_iZone][INST_0][MESH_0][MESH_SOL]->GetNodes()->GetMesh_Coord());
244+
const_cast<su2activematrix*>(solver_container[selected_zone][INST_0][MESH_0][MESH_SOL]->GetNodes()->GetMesh_Coord());
245245
return CPyWrapperMarkerMatrixView(*coords, main_geometry->vertex[iMarker], main_geometry->GetnVertex(iMarker),
246246
"MarkerInitialCoordinates", true);
247247
}
@@ -550,16 +550,21 @@ class CDriverBase {
550550
}
551551

552552
/*!
553-
* \brief Selects zone to be used for Driver operation
553+
* \brief Selects zone to be used for python driver operations.
554554
* \param[in] iZone - Zone identifier.
555555
*/
556556
inline void SelectZone(unsigned short iZone) {
557557
if (iZone >= nZone) SU2_MPI::Error("Zone index out of range", CURRENT_FUNCTION);
558-
selected_iZone = iZone;
559-
main_geometry = geometry_container[selected_iZone][INST_0][MESH_0];
560-
main_config = config_container[selected_iZone];
558+
selected_zone = iZone;
559+
main_geometry = geometry_container[selected_zone][INST_0][MESH_0];
560+
main_config = config_container[selected_zone];
561561
}
562562

563+
/*!
564+
* \brief Returns the index of the zone selected for python driver operations.
565+
*/
566+
inline unsigned short SelectedZone() const { return selected_zone; }
567+
563568
/*!
564569
* \brief Get the wall normal heat flux at a vertex on a specified marker of the flow or heat solver.
565570
* \note This can be the output of a heat or flow solver in a CHT setting.
@@ -707,7 +712,7 @@ class CDriverBase {
707712
if (iMarker < std::numeric_limits<unsigned short>::max() && iMarker > GetNumberMarkers()) {
708713
SU2_MPI::Error("Marker index exceeds size.", CURRENT_FUNCTION);
709714
}
710-
auto* solver = solver_container[selected_iZone][INST_0][MESH_0][iSolver];
715+
auto* solver = solver_container[selected_zone][INST_0][MESH_0][iSolver];
711716
if (solver == nullptr) SU2_MPI::Error("The selected solver does not exist.", CURRENT_FUNCTION);
712717
return solver;
713718
}

SU2_CFD/include/drivers/CMultizoneDriver.hpp

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -122,18 +122,34 @@ class CMultizoneDriver : public CDriver {
122122
/*!
123123
* \brief Destructor of the class.
124124
*/
125-
~CMultizoneDriver(void) override;
125+
~CMultizoneDriver() override;
126126

127127
/*!
128128
* \brief [Overload] Launch the computation for multizone problems.
129129
*/
130130
void StartSolver() override;
131131

132132
/*!
133-
* \brief Preprocess the multizone iteration
133+
* \brief Preprocess the multizone iteration.
134134
*/
135135
void Preprocess(unsigned long TimeIter) override;
136136

137+
/*!
138+
* \brief Solves one time iteration.
139+
*/
140+
void Run() override {
141+
switch (driver_config->GetKind_MZSolver()){
142+
case ENUM_MULTIZONE::MZ_BLOCK_GAUSS_SEIDEL: RunGaussSeidel(); break; // Block Gauss-Seidel iteration
143+
case ENUM_MULTIZONE::MZ_BLOCK_JACOBI: RunJacobi(); break; // Block-Jacobi iteration
144+
}
145+
}
146+
147+
/*!
148+
* \brief Placeholder for post processing operations to make the interface
149+
* of this driver identical to CSinglezoneDriver.
150+
*/
151+
void Postprocess() {}
152+
137153
/*!
138154
* \brief Update the dual-time solution within multiple zones.
139155
*/

SU2_CFD/include/interfaces/fsi/CFlowTractionInterface.hpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,8 +43,11 @@ class CFlowTractionInterface : public CInterface {
4343
/*!
4444
* \brief Sets the dimensional factor for pressure and the consistent_interpolation flag.
4545
* \param[in] flow_config - Definition of the fluid (donor) problem.
46+
* \param[in] struct_config - Definition of the structural (target) problem.
47+
* \param[in] geometry - FEA geometry.
48+
* \param[in] solution - FEA solver.
4649
*/
47-
void Preprocess(const CConfig *flow_config);
50+
void Preprocess(const CConfig *flow_config, const CConfig *struct_config, CGeometry *geometry, CSolver *solution);
4851

4952
/*!
5053
* \brief Computes vertex areas (FEA side) for when tractions need to be integrated.

SU2_CFD/include/variables/CFEABoundVariable.hpp

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -149,11 +149,6 @@ class CFEABoundVariable final : public CFEAVariable {
149149
return FlowTraction_n(iPoint,iVar);
150150
}
151151

152-
/*!
153-
* \brief Clear the flow traction residual
154-
*/
155-
void Clear_FlowTraction() override;
156-
157152
/*!
158153
* \brief Register the flow tractions as input variable.
159154
*/

SU2_CFD/include/variables/CVariable.hpp

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1508,11 +1508,6 @@ class CVariable {
15081508
*/
15091509
inline virtual su2double Get_FlowTraction_n(unsigned long iPoint, unsigned long iVar) const { return 0.0; }
15101510

1511-
/*!
1512-
* \brief A virtual member.
1513-
*/
1514-
inline virtual void Clear_FlowTraction() {}
1515-
15161511
/*!
15171512
* \brief A virtual member.
15181513
*/

SU2_CFD/src/drivers/CDriverBase.cpp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -391,14 +391,14 @@ vector<passivedouble> CDriverBase::GetMarkerVertexNormals(unsigned short iMarker
391391
}
392392

393393
void CDriverBase::CommunicateMeshDisplacements() {
394-
solver_container[selected_iZone][INST_0][MESH_0][MESH_SOL]->InitiateComms(main_geometry, main_config, MESH_DISPLACEMENTS);
395-
solver_container[selected_iZone][INST_0][MESH_0][MESH_SOL]->CompleteComms(main_geometry, main_config, MESH_DISPLACEMENTS);
394+
solver_container[selected_zone][INST_0][MESH_0][MESH_SOL]->InitiateComms(main_geometry, main_config, MESH_DISPLACEMENTS);
395+
solver_container[selected_zone][INST_0][MESH_0][MESH_SOL]->CompleteComms(main_geometry, main_config, MESH_DISPLACEMENTS);
396396
}
397397

398398
map<string, unsigned short> CDriverBase::GetSolverIndices() const {
399399
map<string, unsigned short> indexMap;
400400
for (auto iSol = 0u; iSol < MAX_SOLS; iSol++) {
401-
const auto* solver = solver_container[selected_iZone][INST_0][MESH_0][iSol];
401+
const auto* solver = solver_container[selected_zone][INST_0][MESH_0][iSol];
402402
if (solver != nullptr) {
403403
if (solver->GetSolverName().empty()) SU2_MPI::Error("Solver name was not defined.", CURRENT_FUNCTION);
404404
indexMap[solver->GetSolverName()] = iSol;
@@ -408,7 +408,7 @@ map<string, unsigned short> CDriverBase::GetSolverIndices() const {
408408
}
409409

410410
std::map<string, unsigned short> CDriverBase::GetFEASolutionIndices() const {
411-
if (solver_container[selected_iZone][INST_0][MESH_0][FEA_SOL] == nullptr) {
411+
if (solver_container[selected_zone][INST_0][MESH_0][FEA_SOL] == nullptr) {
412412
SU2_MPI::Error("The FEA solver does not exist.", CURRENT_FUNCTION);
413413
}
414414
const auto nDim = main_geometry->GetnDim();
@@ -429,7 +429,7 @@ std::map<string, unsigned short> CDriverBase::GetFEASolutionIndices() const {
429429
}
430430

431431
map<string, unsigned short> CDriverBase::GetPrimitiveIndices() const {
432-
if (solver_container[selected_iZone][INST_0][MESH_0][FLOW_SOL] == nullptr) {
432+
if (solver_container[selected_zone][INST_0][MESH_0][FLOW_SOL] == nullptr) {
433433
SU2_MPI::Error("The flow solver does not exist.", CURRENT_FUNCTION);
434434
}
435435
return PrimitiveNameToIndexMap(CPrimitiveIndices<unsigned short>(

SU2_CFD/src/drivers/CMultizoneDriver.cpp

Lines changed: 19 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -182,10 +182,7 @@ void CMultizoneDriver::StartSolver() {
182182

183183
/*--- Run a block iteration of the multizone problem. ---*/
184184

185-
switch (driver_config->GetKind_MZSolver()){
186-
case ENUM_MULTIZONE::MZ_BLOCK_GAUSS_SEIDEL: RunGaussSeidel(); break; // Block Gauss-Seidel iteration
187-
case ENUM_MULTIZONE::MZ_BLOCK_JACOBI: RunJacobi(); break; // Block-Jacobi iteration
188-
}
185+
Run();
189186

190187
/*--- Update the solution for dual time stepping strategy ---*/
191188

@@ -646,11 +643,11 @@ void CMultizoneDriver::SetTurboPerformance() {
646643
}
647644
}
648645

649-
bool CMultizoneDriver::Monitor(unsigned long TimeIter){
646+
bool CMultizoneDriver::Monitor(unsigned long TimeIter) {
650647

651648
/*--- Check whether the inner solver has converged --- */
652649

653-
if (driver_config->GetTime_Domain() == NO){
650+
if (driver_config->GetTime_Domain() == NO) {
654651

655652
const auto OuterIter = driver_config->GetOuterIter();
656653
const auto nOuterIter = driver_config->GetnOuter_Iter();
@@ -670,29 +667,27 @@ bool CMultizoneDriver::Monitor(unsigned long TimeIter){
670667
}
671668
// i.e. unsteady simulation
672669

673-
/*--- Check whether the outer time integration has reached the final time ---*/
674-
const auto TimeConvergence = GetTimeConvergence();
670+
/*--- Check whether the outer time integration has reached the final time. ---*/
671+
const auto TimeConvergence = GetTimeConvergence();
675672

676-
const auto nTimeIter = driver_config->GetnTime_Iter();
677-
const auto MaxTime = driver_config->GetMax_Time();
678-
const auto CurTime = driver_output->GetHistoryFieldValue("CUR_TIME");
673+
const auto nTimeIter = driver_config->GetnTime_Iter();
674+
const auto MaxTime = driver_config->GetMax_Time();
675+
const auto CurTime = driver_output->GetHistoryFieldValue("CUR_TIME");
679676

680-
const bool FinalTimeReached = (CurTime >= MaxTime);
681-
const bool MaxIterationsReached = (TimeIter+1 >= nTimeIter);
677+
const bool FinalTimeReached = (CurTime >= MaxTime);
678+
const bool MaxIterationsReached = (TimeIter+1 >= nTimeIter);
682679

683-
if ((TimeConvergence || FinalTimeReached || MaxIterationsReached) && (rank == MASTER_NODE)){
684-
cout << "\n----------------------------- Solver Exit -------------------------------";
685-
if (TimeConvergence) cout << "\nAll windowed time-averaged convergence criteria are fullfilled." << endl;
686-
if (FinalTimeReached) cout << "\nMaximum time reached (MAX_TIME = " << MaxTime << "s)." << endl;
687-
else cout << "\nMaximum number of time iterations reached (TIME_ITER = " << nTimeIter << ")." << endl;
688-
cout << "-------------------------------------------------------------------------" << endl;
689-
}
690-
691-
return (FinalTimeReached || MaxIterationsReached);
692-
680+
if ((TimeConvergence || FinalTimeReached || MaxIterationsReached) && (rank == MASTER_NODE)){
681+
cout << "\n----------------------------- Solver Exit -------------------------------";
682+
if (TimeConvergence) cout << "\nAll windowed time-averaged convergence criteria are fullfilled." << endl;
683+
if (FinalTimeReached) cout << "\nMaximum time reached (MAX_TIME = " << MaxTime << "s)." << endl;
684+
else cout << "\nMaximum number of time iterations reached (TIME_ITER = " << nTimeIter << ")." << endl;
685+
cout << "-------------------------------------------------------------------------" << endl;
686+
}
693687

694-
if (rank == MASTER_NODE) SetTurboPerformance();
688+
if (rank == MASTER_NODE && driver_config->GetBoolTurbomachinery()) SetTurboPerformance();
695689

690+
return (FinalTimeReached || MaxIterationsReached);
696691
}
697692

698693
bool CMultizoneDriver::GetTimeConvergence() const{

SU2_CFD/src/drivers/CSinglezoneDriver.cpp

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -92,12 +92,6 @@ void CSinglezoneDriver::StartSolver() {
9292

9393
Output(TimeIter);
9494

95-
/*--- Save iteration solution for libROM ---*/
96-
if (config_container[MESH_0]->GetSave_libROM()) {
97-
solver_container[ZONE_0][INST_0][MESH_0][FLOW_SOL]->SavelibROM(geometry_container[ZONE_0][INST_0][MESH_0],
98-
config_container[ZONE_0], StopCalc);
99-
}
100-
10195
/*--- If the convergence criteria has been met, terminate the simulation. ---*/
10296

10397
if (StopCalc) break;
@@ -208,7 +202,14 @@ void CSinglezoneDriver::Output(unsigned long TimeIter) {
208202
solver_container[ZONE_0][INST_0][MESH_0],
209203
TimeIter, StopCalc);
210204

211-
if (wrote_files){
205+
/*--- Save iteration solution for libROM ---*/
206+
if (config_container[MESH_0]->GetSave_libROM()) {
207+
solver_container[ZONE_0][INST_0][MESH_0][FLOW_SOL]->SavelibROM(geometry_container[ZONE_0][INST_0][MESH_0],
208+
config_container[ZONE_0], StopCalc);
209+
wrote_files = true;
210+
}
211+
212+
if (wrote_files) {
212213

213214
StopTime = SU2_MPI::Wtime();
214215

SU2_CFD/src/interfaces/fsi/CDiscAdjFlowTractionInterface.cpp

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -40,11 +40,7 @@ void CDiscAdjFlowTractionInterface::GetPhysical_Constants(CSolver *flow_solution
4040
CGeometry *flow_geometry, CGeometry *struct_geometry,
4141
const CConfig *flow_config, const CConfig *struct_config){
4242

43-
/*--- We have to clear the traction before applying it, because we are "adding" to node and not "setting" ---*/
44-
45-
struct_solution->GetNodes()->Clear_FlowTraction();
46-
47-
Preprocess(flow_config);
43+
Preprocess(flow_config, struct_config, struct_geometry, struct_solution);
4844

4945
if (!conservative) ComputeVertexAreas(struct_config, struct_geometry, struct_solution);
5046

SU2_CFD/src/interfaces/fsi/CFlowTractionInterface.cpp

Lines changed: 22 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
#include "../../../../Common/include/geometry/CGeometry.hpp"
3232
#include "../../../include/solvers/CSolver.hpp"
3333
#include "../../../../Common/include/toolboxes/geometry_toolbox.hpp"
34+
#include "../../../Common/include/interface_interpolation/CInterpolator.hpp"
3435
#include <unordered_set>
3536

3637
CFlowTractionInterface::CFlowTractionInterface(unsigned short val_nVar, unsigned short val_nConst,
@@ -39,7 +40,26 @@ CFlowTractionInterface::CFlowTractionInterface(unsigned short val_nVar, unsigned
3940
conservative(conservative_) {
4041
}
4142

42-
void CFlowTractionInterface::Preprocess(const CConfig *flow_config) {
43+
void CFlowTractionInterface::Preprocess(const CConfig *flow_config, const CConfig *struct_config,
44+
CGeometry *struct_geometry, CSolver *struct_solution) {
45+
46+
/*--- Clear the tractions only on the markers involved in interface, fluid tractions
47+
* on other markers can be specified via e.g. the python wrapper. ---*/
48+
49+
for (auto iMarkerInt = 0u; iMarkerInt < struct_config->GetMarker_n_ZoneInterface()/2; iMarkerInt++) {
50+
const auto markDonor = flow_config->FindInterfaceMarker(iMarkerInt);
51+
const auto markTarget = struct_config->FindInterfaceMarker(iMarkerInt);
52+
53+
if(!CInterpolator::CheckInterfaceBoundary(markDonor, markTarget)) continue;
54+
if (markTarget < 0) continue;
55+
56+
for (auto iVertex = 0ul; iVertex < struct_geometry->GetnVertex(markTarget); iVertex++) {
57+
const auto iPoint = struct_geometry->vertex[markTarget][iVertex]->GetNode();
58+
if (!struct_geometry->nodes->GetDomain(iPoint)) continue;
59+
su2double zeros[3] = {};
60+
struct_solution->GetNodes()->Set_FlowTraction(iPoint, zeros);
61+
}
62+
}
4363

4464
/*--- Compute the constant factor to dimensionalize pressure and shear stress. ---*/
4565
const su2double *Velocity_ND, *Velocity_Real;
@@ -121,11 +141,7 @@ void CFlowTractionInterface::GetPhysical_Constants(CSolver *flow_solution, CSolv
121141
CGeometry *flow_geometry, CGeometry *struct_geometry,
122142
const CConfig *flow_config, const CConfig *struct_config) {
123143

124-
/*--- We have to clear the traction before applying it, because we are "adding" to node and not "setting" ---*/
125-
126-
struct_solution->GetNodes()->Clear_FlowTraction();
127-
128-
Preprocess(flow_config);
144+
Preprocess(flow_config, struct_config, struct_geometry, struct_solution);
129145

130146
if (!conservative) ComputeVertexAreas(struct_config, struct_geometry, struct_solution);
131147

0 commit comments

Comments
 (0)