Skip to content

Commit 2db8e75

Browse files
committed
py wrapper heat solver example, cleanup discadj fluid iteration, some fixes for unsteady adjoints
1 parent 2bb4550 commit 2db8e75

11 files changed

Lines changed: 431 additions & 143 deletions

File tree

SU2_CFD/include/drivers/CDriverBase.hpp

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -473,6 +473,25 @@ class CDriverBase {
473473
"MarkerSolutionTimeN of " + solver->GetSolverName(), false);
474474
}
475475

476+
/*!
477+
* \brief Get a read/write view of the solution at time N-1 on all mesh nodes of a solver.
478+
*/
479+
inline CPyWrapperMatrixView SolutionTimeN1(unsigned short iSolver) {
480+
auto* solver = GetSolverAndCheckMarker(iSolver);
481+
return CPyWrapperMatrixView(
482+
solver->GetNodes()->GetSolution_time_n1(), "SolutionTimeN1 of " + solver->GetSolverName(), false);
483+
}
484+
485+
/*!
486+
* \brief Get a read/write view of the solution at time N-1 on the mesh nodes of a marker.
487+
*/
488+
inline CPyWrapperMarkerMatrixView MarkerSolutionTimeN1(unsigned short iSolver, unsigned short iMarker) {
489+
auto* solver = GetSolverAndCheckMarker(iSolver, iMarker);
490+
return CPyWrapperMarkerMatrixView(
491+
solver->GetNodes()->GetSolution_time_n1(), main_geometry->vertex[iMarker], main_geometry->GetnVertex(iMarker),
492+
"MarkerSolutionTimeN1 of " + solver->GetSolverName(), false);
493+
}
494+
476495
/*!
477496
* \brief Get the flow solver primitive variable names with their associated indices.
478497
* These correspond to the column indices in the matrix returned by Primitives.

SU2_CFD/include/variables/CVariable.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -500,6 +500,7 @@ class CVariable {
500500
* \return Pointer to the solution (at time n-1) vector.
501501
*/
502502
inline su2double *GetSolution_time_n1(unsigned long iPoint) { return Solution_time_n1[iPoint]; }
503+
inline MatrixType& GetSolution_time_n1() { return Solution_time_n1; }
503504

504505
/*!
505506
* \brief Set the value of the old residual.

SU2_CFD/src/drivers/CDiscAdjSinglezoneDriver.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,10 @@ CDiscAdjSinglezoneDriver::~CDiscAdjSinglezoneDriver() {
129129

130130
void CDiscAdjSinglezoneDriver::Preprocess(unsigned long TimeIter) {
131131

132+
/*--- Set the current time iteration in the config and also in the driver
133+
* because the python interface doesn't offer an explicit way of doing it. ---*/
134+
135+
this->TimeIter = TimeIter;
132136
config_container[ZONE_0]->SetTimeIter(TimeIter);
133137

134138
/*--- Preprocess the adjoint iteration ---*/

SU2_CFD/src/drivers/CSinglezoneDriver.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,8 +110,10 @@ void CSinglezoneDriver::StartSolver() {
110110

111111
void CSinglezoneDriver::Preprocess(unsigned long TimeIter) {
112112

113-
/*--- Set the current time iteration in the config ---*/
113+
/*--- Set the current time iteration in the config and also in the driver
114+
* because the python interface doesn't offer an explicit way of doing it. ---*/
114115

116+
this->TimeIter = TimeIter;
115117
config_container[ZONE_0]->SetTimeIter(TimeIter);
116118

117119
/*--- Store the current physical time in the config container, as

SU2_CFD/src/iteration/CDiscAdjFluidIteration.cpp

Lines changed: 82 additions & 84 deletions
Large diffs are not rendered by default.

SU2_CFD/src/iteration/CDiscAdjHeatIteration.cpp

Lines changed: 38 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -45,78 +45,66 @@ void CDiscAdjHeatIteration::Preprocess(COutput* output, CIntegration**** integra
4545
if (config[val_iZone]->GetTime_Marching() != TIME_MARCHING::STEADY) {
4646
const int Direct_Iter = static_cast<int>(config[val_iZone]->GetUnst_AdjointIter()) - static_cast<int>(TimeIter) - 2 + dual_time;
4747

48-
/*--- For dual-time stepping we want to load the already converged solution at timestep n ---*/
48+
/*--- For dual-time stepping we want to load the already converged solution at previous timesteps.
49+
* In general we only load one file and shift the previously loaded solutions, on the first we
50+
* load one or two more (depending on dual time order). ---*/
4951

50-
if (TimeIter == 0) {
51-
if (dual_time_2nd) {
52-
/*--- Load solution at timestep n-2 ---*/
53-
54-
LoadUnsteady_Solution(geometry, solver, config, val_iZone, val_iInst, Direct_Iter - 2);
55-
56-
/*--- Push solution back to correct array ---*/
52+
if (dual_time_2nd) {
53+
LoadUnsteady_Solution(geometry, solver, config, val_iZone, val_iInst, Direct_Iter - 2);
54+
} else if (dual_time_1st) {
55+
LoadUnsteady_Solution(geometry, solver, config, val_iZone, val_iInst, Direct_Iter - 1);
56+
}
5757

58+
if (TimeIter == 0) {
59+
/*--- Push solution back one or two levels, ---*/
60+
if (dual_time) {
5861
for (auto iMesh = 0u; iMesh <= config[val_iZone]->GetnMGLevels(); iMesh++) {
5962
solvers[iMesh][HEAT_SOL]->GetNodes()->Set_Solution_time_n();
60-
solvers[iMesh][HEAT_SOL]->GetNodes()->Set_Solution_time_n1();
63+
if (dual_time_2nd) solvers[iMesh][HEAT_SOL]->GetNodes()->Set_Solution_time_n1();
6164
}
6265
}
63-
if (dual_time) {
64-
/*--- Load solution at timestep n-1 ---*/
6566

67+
/*--- If required load another time step. ---*/
68+
if (dual_time_2nd) {
6669
LoadUnsteady_Solution(geometry, solver, config, val_iZone, val_iInst, Direct_Iter - 1);
6770

68-
/*--- Push solution back to correct array ---*/
69-
7071
for (auto iMesh = 0u; iMesh <= config[val_iZone]->GetnMGLevels(); iMesh++) {
7172
solvers[iMesh][HEAT_SOL]->GetNodes()->Set_Solution_time_n();
7273
}
7374
}
7475

75-
/*--- Load solution timestep n ---*/
76-
76+
/*--- Load current solution. ---*/
7777
LoadUnsteady_Solution(geometry, solver, config, val_iZone, val_iInst, Direct_Iter);
7878
}
7979
if ((TimeIter > 0) && dual_time) {
80-
/*--- Load solution timestep n - 2 ---*/
81-
82-
LoadUnsteady_Solution(geometry, solver, config, val_iZone, val_iInst, Direct_Iter - 2);
83-
8480
/*--- Temporarily store the loaded solution in the Solution_Old array ---*/
85-
8681
for (auto iMesh = 0u; iMesh <= config[val_iZone]->GetnMGLevels(); iMesh++)
8782
solvers[iMesh][HEAT_SOL]->Set_OldSolution();
8883

89-
/*--- Set Solution at timestep n to solution at n-1 ---*/
90-
84+
/*--- Move timestep n to current solution. ---*/
9185
for (auto iMesh = 0u; iMesh <= config[val_iZone]->GetnMGLevels(); iMesh++) {
9286
for (auto iPoint = 0ul; iPoint < geometry[val_iZone][val_iInst][iMesh]->GetnPoint(); iPoint++) {
9387
solvers[iMesh][HEAT_SOL]->GetNodes()->SetSolution(
9488
iPoint, solvers[iMesh][HEAT_SOL]->GetNodes()->GetSolution_time_n(iPoint));
9589
}
9690
}
97-
if (dual_time_1st) {
98-
/*--- Set Solution at timestep n-1 to the previously loaded solution ---*/
99-
for (auto iMesh = 0u; iMesh <= config[val_iZone]->GetnMGLevels(); iMesh++) {
100-
for (auto iPoint = 0ul; iPoint < geometry[val_iZone][val_iInst][iMesh]->GetnPoint(); iPoint++) {
101-
solvers[iMesh][HEAT_SOL]->GetNodes()->Set_Solution_time_n(
102-
iPoint, solvers[iMesh][HEAT_SOL]->GetNodes()->GetSolution_time_n1(iPoint));
103-
}
104-
}
105-
}
91+
92+
/*--- If required also move timestep n-1 to timestep n. ---*/
10693
if (dual_time_2nd) {
107-
/*--- Set Solution at timestep n-1 to solution at n-2 ---*/
10894
for (auto iMesh = 0u; iMesh <= config[val_iZone]->GetnMGLevels(); iMesh++) {
10995
for (auto iPoint = 0ul; iPoint < geometry[val_iZone][val_iInst][iMesh]->GetnPoint(); iPoint++) {
11096
solvers[iMesh][HEAT_SOL]->GetNodes()->Set_Solution_time_n(
11197
iPoint, solvers[iMesh][HEAT_SOL]->GetNodes()->GetSolution_time_n1(iPoint));
11298
}
11399
}
114-
/*--- Set Solution at timestep n-2 to the previously loaded solution ---*/
115-
for (auto iMesh = 0u; iMesh <= config[val_iZone]->GetnMGLevels(); iMesh++) {
116-
for (auto iPoint = 0ul; iPoint < geometry[val_iZone][val_iInst][iMesh]->GetnPoint(); iPoint++) {
117-
solvers[iMesh][HEAT_SOL]->GetNodes()->Set_Solution_time_n1(
118-
iPoint, solvers[iMesh][HEAT_SOL]->GetNodes()->GetSolution_Old(iPoint));
119-
}
100+
}
101+
102+
/*--- Finally, place the loaded solution in the correct place (n or n-1 depending on order). ---*/
103+
for (auto iMesh = 0u; iMesh <= config[val_iZone]->GetnMGLevels(); iMesh++) {
104+
for (auto iPoint = 0ul; iPoint < geometry[val_iZone][val_iInst][iMesh]->GetnPoint(); iPoint++) {
105+
const auto sol = solvers[iMesh][HEAT_SOL]->GetNodes()->GetSolution_Old(iPoint);
106+
if (dual_time_2nd) solvers[iMesh][HEAT_SOL]->GetNodes()->Set_Solution_time_n1(iPoint, sol);
107+
else solvers[iMesh][HEAT_SOL]->GetNodes()->Set_Solution_time_n(iPoint, sol);
120108
}
121109
}
122110
}
@@ -140,23 +128,23 @@ void CDiscAdjHeatIteration::Preprocess(COutput* output, CIntegration**** integra
140128
void CDiscAdjHeatIteration::LoadUnsteady_Solution(CGeometry**** geometry, CSolver***** solver, CConfig** config,
141129
unsigned short val_iZone, unsigned short val_iInst,
142130
int val_DirectIter) {
131+
auto solvers = solver[val_iZone][val_iInst];
132+
auto geometries = geometry[val_iZone][val_iInst];
143133

144134
if (val_DirectIter >= 0) {
145135
if (rank == MASTER_NODE)
146136
cout << " Loading heat solution from direct iteration " << val_DirectIter << " for zone " << val_iZone << "." << endl;
147137

148-
solver[val_iZone][val_iInst][MESH_0][HEAT_SOL]->LoadRestart(
149-
geometry[val_iZone][val_iInst], solver[val_iZone][val_iInst], config[val_iZone], val_DirectIter, false);
138+
solvers[MESH_0][HEAT_SOL]->LoadRestart(geometries, solvers, config[val_iZone], val_DirectIter, false);
150139
}
151140
else {
152141
/*--- If there is no solution file we set the freestream condition ---*/
153142
if (rank == MASTER_NODE)
154143
cout << " Setting freestream conditions at direct iteration " << val_DirectIter << " for zone " << val_iZone << "." << endl;
155144

156145
for (auto iMesh = 0u; iMesh <= config[val_iZone]->GetnMGLevels(); iMesh++) {
157-
solver[val_iZone][val_iInst][iMesh][HEAT_SOL]->SetFreeStream_Solution(config[val_iZone]);
158-
solver[val_iZone][val_iInst][iMesh][HEAT_SOL]->Postprocessing(
159-
geometry[val_iZone][val_iInst][iMesh], solver[val_iZone][val_iInst][iMesh], config[val_iZone], iMesh);
146+
solvers[iMesh][HEAT_SOL]->SetFreeStream_Solution(config[val_iZone]);
147+
solvers[iMesh][HEAT_SOL]->Postprocessing(geometries[iMesh], solvers[iMesh], config[val_iZone], iMesh);
160148
}
161149
}
162150
}
@@ -177,26 +165,28 @@ void CDiscAdjHeatIteration::InitializeAdjoint(CSolver***** solver, CGeometry****
177165

178166
void CDiscAdjHeatIteration::RegisterInput(CSolver***** solver, CGeometry**** geometry, CConfig** config,
179167
unsigned short iZone, unsigned short iInst, RECORDING kind_recording) {
168+
auto solvers0 = solver[iZone][iInst][MESH_0];
169+
auto geometry0 = geometry[iZone][iInst][MESH_0];
180170

181171
if (kind_recording == RECORDING::SOLUTION_VARIABLES || kind_recording == RECORDING::SOLUTION_AND_MESH) {
182172
/*--- Register flow and turbulent variables as input ---*/
183173

184-
solver[iZone][iInst][MESH_0][ADJHEAT_SOL]->RegisterSolution(geometry[iZone][iInst][MESH_0], config[iZone]);
174+
solvers0[ADJHEAT_SOL]->RegisterSolution(geometry0, config[iZone]);
185175

186-
solver[iZone][iInst][MESH_0][ADJHEAT_SOL]->RegisterVariables(geometry[iZone][iInst][MESH_0], config[iZone]);
176+
solvers0[ADJHEAT_SOL]->RegisterVariables(geometry0, config[iZone]);
187177
}
188178
else if (kind_recording == RECORDING::MESH_COORDS) {
189179
/*--- Register node coordinates as input ---*/
190180

191-
geometry[iZone][iInst][MESH_0]->RegisterCoordinates();
181+
geometry0->RegisterCoordinates();
192182
}
193183
else if (kind_recording == RECORDING::MESH_DEFORM) {
194184
/*--- Register the variables of the mesh deformation ---*/
195185
/*--- Undeformed mesh coordinates ---*/
196-
solver[iZone][iInst][MESH_0][ADJMESH_SOL]->RegisterSolution(geometry[iZone][iInst][MESH_0], config[iZone]);
186+
solvers0[ADJMESH_SOL]->RegisterSolution(geometry0, config[iZone]);
197187

198188
/*--- Boundary displacements ---*/
199-
solver[iZone][iInst][MESH_0][ADJMESH_SOL]->RegisterVariables(geometry[iZone][iInst][MESH_0], config[iZone]);
189+
solvers0[ADJMESH_SOL]->RegisterVariables(geometry0, config[iZone]);
200190
}
201191
}
202192

SU2_CFD/src/output/CAdjElasticityOutput.cpp

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -244,19 +244,19 @@ void CAdjElasticityOutput::SetVolumeOutputFields(CConfig *config){
244244

245245
/*--- Sensitivities with respect to initial conditions. ---*/
246246

247-
AddVolumeOutput("SENS_DISP-X", "SensInitialDisp_x", "SENSITIVITY_T0", "sensitivity to the initial x displacement");
248-
AddVolumeOutput("SENS_DISP-Y", "SensInitialDisp_y", "SENSITIVITY_T0", "sensitivity to the initial y displacement");
247+
AddVolumeOutput("SENS_DISP-X", "SensitivityDispN_x", "SENSITIVITY_N", "sensitivity to the previous x displacement");
248+
AddVolumeOutput("SENS_DISP-Y", "SensitivityDispN_y", "SENSITIVITY_N", "sensitivity to the previous y displacement");
249249
if (nDim == 3)
250-
AddVolumeOutput("SENS_DISP-Z", "SensInitialDisp_z", "SENSITIVITY_T0", "sensitivity to the initial z displacement");
250+
AddVolumeOutput("SENS_DISP-Z", "SensitivityDispN_z", "SENSITIVITY_N", "sensitivity to the previous z displacement");
251251

252-
AddVolumeOutput("SENS_VEL-X", "SensInitialVel_x", "SENSITIVITY_T0", "sensitivity to the initial x velocity");
253-
AddVolumeOutput("SENS_VEL-Y", "SensInitialVel_y", "SENSITIVITY_T0", "sensitivity to the initial y velocity");
252+
AddVolumeOutput("SENS_VEL-X", "SensitivityVelN_x", "SENSITIVITY_N", "sensitivity to the previous x velocity");
253+
AddVolumeOutput("SENS_VEL-Y", "SensitivityVelN_y", "SENSITIVITY_N", "sensitivity to the previous y velocity");
254254
if (nDim == 3)
255-
AddVolumeOutput("SENS_VEL-Z", "SensInitialVel_z", "SENSITIVITY_T0", "sensitivity to the initial z velocity");
255+
AddVolumeOutput("SENS_VEL-Z", "SensitivityVelN_z", "SENSITIVITY_N", "sensitivity to the previous z velocity");
256256

257-
AddVolumeOutput("SENS_ACCEL-X", "SensInitialAccel_x", "SENSITIVITY_T0", "sensitivity to the initial x acceleration");
258-
AddVolumeOutput("SENS_ACCEL-Y", "SensInitialAccel_y", "SENSITIVITY_T0", "sensitivity to the initial y acceleration");
257+
AddVolumeOutput("SENS_ACCEL-X", "SensitivityAccelN_x", "SENSITIVITY_N", "sensitivity to the previous x acceleration");
258+
AddVolumeOutput("SENS_ACCEL-Y", "SensitivityAccelN_y", "SENSITIVITY_N", "sensitivity to the previous y acceleration");
259259
if (nDim == 3)
260-
AddVolumeOutput("SENS_ACCEL-Z", "SensInitialAccel_z", "SENSITIVITY_T0", "sensitivity to the initial z acceleration");
260+
AddVolumeOutput("SENS_ACCEL-Z", "SensitivityAccelN_z", "SENSITIVITY_N", "sensitivity to the previous z acceleration");
261261

262262
}

SU2_CFD/src/output/CAdjHeatOutput.cpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,14 @@ void CAdjHeatOutput::SetVolumeOutputFields(CConfig *config){
176176
AddVolumeOutput("SENSITIVITY", "Surface_Sensitivity", "SENSITIVITY", "sensitivity in normal direction");
177177
/// END_GROUP
178178

179+
if (!config->GetTime_Domain()) return;
180+
181+
/*--- Sensitivities with respect to initial conditions. ---*/
182+
183+
AddVolumeOutput("SENS_TEMP_N", "SensitivityTempN", "SENSITIVITY_N", "sensitivity to the previous temperature");
184+
if (config->GetTime_Marching() == TIME_MARCHING::DT_STEPPING_2ND) {
185+
AddVolumeOutput("SENS_TEMP_N1", "SensitivityTempN1", "SENSITIVITY_N", "sensitivity to the previous-1 temperature");
186+
}
179187
}
180188

181189
void CAdjHeatOutput::LoadVolumeData(CConfig *config, CGeometry *geometry, CSolver **solver, unsigned long iPoint){
@@ -199,6 +207,13 @@ void CAdjHeatOutput::LoadVolumeData(CConfig *config, CGeometry *geometry, CSolve
199207
if (nDim == 3)
200208
SetVolumeOutputValue("SENSITIVITY-Z", iPoint, Node_AdjHeat->GetSensitivity(iPoint, 2));
201209

210+
if (!config->GetTime_Domain()) return;
211+
212+
SetVolumeOutputValue("SENS_TEMP_N", iPoint, Node_AdjHeat->GetSolution_time_n(iPoint, 0));
213+
if (config->GetTime_Marching() == TIME_MARCHING::DT_STEPPING_2ND) {
214+
SetVolumeOutputValue("SENS_TEMP_N1", iPoint, Node_AdjHeat->GetSolution_time_n1(iPoint, 0));
215+
}
216+
202217
}
203218

204219
void CAdjHeatOutput::LoadSurfaceData(CConfig *config, CGeometry *geometry, CSolver **solver, unsigned long iPoint, unsigned short iMarker, unsigned long iVertex){

TestCases/parallel_regression_AD.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -421,6 +421,19 @@ def main():
421421
test_list.append(pywrapper_Unst_FEA_AD)
422422
pass_list.append(pywrapper_Unst_FEA_AD.run_test())
423423

424+
# Heat solver unsteady AD
425+
pywrapper_Unst_Heat_AD = TestCase('pywrapper_Unst_Heat_AD')
426+
pywrapper_Unst_Heat_AD.cfg_dir = "py_wrapper/custom_heat_flux"
427+
pywrapper_Unst_Heat_AD.cfg_file = "run_ad.cfg"
428+
pywrapper_Unst_Heat_AD.test_iter = 100
429+
pywrapper_Unst_Heat_AD.test_vals = [0.776365, 0.776430, 1.000003]
430+
pywrapper_Unst_Heat_AD.command = TestCase.Command("mpirun -n 2", "python", "run_ad.py")
431+
pywrapper_Unst_Heat_AD.timeout = 1600
432+
pywrapper_Unst_Heat_AD.tol = 0.00001
433+
pywrapper_Unst_Heat_AD.new_output = False
434+
test_list.append(pywrapper_Unst_Heat_AD)
435+
pass_list.append(pywrapper_Unst_Heat_AD.run_test())
436+
424437
# Flow AD Mesh Displacement Sensitivity
425438
pywrapper_CFD_AD_MeshDisp = TestCase('pywrapper_CFD_AD_MeshDisp')
426439
pywrapper_CFD_AD_MeshDisp.cfg_dir = "py_wrapper/disc_adj_flow/mesh_disp_sens"

0 commit comments

Comments
 (0)