Skip to content

Commit d71a04d

Browse files
authored
Merge pull request #2736 from su2code/pedro/adjoint_thermoelastic
Adjoint thermo elasticity
2 parents 8204b8b + 8aec5df commit d71a04d

19 files changed

Lines changed: 214 additions & 64 deletions

SU2_CFD/include/iteration/CDiscAdjFEAIteration.hpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,9 @@ class CDiscAdjFEAIteration final : public CIteration {
4242
private:
4343
unsigned short CurrentRecording; /*!< \brief Stores the current status of the recording. */
4444

45+
/*!< \brief Used for thermo elastic problems to avoid duplicating code. */
46+
CIteration* DiscAdjHeatIteration = nullptr;
47+
4548
/*!
4649
* \brief load solution for dynamic problems
4750
* \param[in] geometry - Geometrical definition of the problem.
@@ -64,7 +67,7 @@ class CDiscAdjFEAIteration final : public CIteration {
6467
/*!
6568
* \brief Destructor of the class.
6669
*/
67-
~CDiscAdjFEAIteration(void) override;
70+
~CDiscAdjFEAIteration() override;
6871

6972
/*!
7073
* \brief Preprocessing to prepare for an iteration of the physics.

SU2_CFD/include/output/CAdjElasticityOutput.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
*/
3737
class CAdjElasticityOutput final : public COutput {
3838
private:
39+
bool coupled_heat; //!< Boolean indicating a thermoelastic analysis
3940
unsigned short nVar_FEM; //!< Number of FEM variables
4041

4142
public:

SU2_CFD/include/output/CAdjHeatOutput.hpp

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,14 +46,24 @@ class CAdjHeatOutput final: public COutput {
4646
/*!
4747
* \brief Destructor of the class.
4848
*/
49-
~CAdjHeatOutput(void) override;
49+
~CAdjHeatOutput() override;
50+
51+
/*!
52+
* \brief Set the history output field values in another output instance.
53+
*/
54+
static void LoadHistoryDataImpl(CConfig *config, CGeometry *geometry, CSolver **solver, COutput* output);
5055

5156
/*!
5257
* \brief Load the history output field values
5358
* \param[in] config - Definition of the particular problem.
5459
*/
5560
void LoadHistoryData(CConfig *config, CGeometry *geometry, CSolver **solver) override;
5661

62+
/*!
63+
* \brief Set the available history output fields in another output instance.
64+
*/
65+
static void SetHistoryOutputFieldsImpl(CConfig *config, COutput* output);
66+
5767
/*!
5868
* \brief Set the available history output fields
5969
* \param[in] config - Definition of the particular problem.

SU2_CFD/include/output/CElasticityOutput.hpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,6 @@
3737
class CElasticityOutput final: public COutput {
3838
protected:
3939

40-
unsigned short nVar_FEM; //!< Number of FEM variables
4140
bool linear_analysis, //!< Boolean indicating a linear analysis
4241
nonlinear_analysis, //!< Boolean indicating a nonlinear analysis
4342
coupled_heat, //!< Boolean indicating a thermoelastic analysis

SU2_CFD/include/output/COutput.hpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ class CFileWriter;
5656
class CParallelDataSorter;
5757
class CConfig;
5858
class CHeatOutput;
59+
class CAdjHeatOutput;
5960

6061
using namespace std;
6162

@@ -67,6 +68,7 @@ using namespace std;
6768
class COutput {
6869
protected:
6970
friend class CHeatOutput;
71+
friend class CAdjHeatOutput;
7072

7173
/*----------------------------- General ----------------------------*/
7274

SU2_CFD/include/solvers/CFEASolver.hpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -550,7 +550,7 @@ class CFEASolver : public CFEASolverBase {
550550
* \param[in] config - Definition of the problem.
551551
* \param[in] solver - Container vector with all the solutions.
552552
*/
553-
void Evaluate_ObjFunc(const CConfig *config, CSolver**) final {
553+
void Evaluate_ObjFunc(const CConfig *config, CSolver** solver) final {
554554
Total_ComboObj = 0.0;
555555
switch (config->GetKind_ObjFunc()) {
556556
case REFERENCE_GEOMETRY:
@@ -575,6 +575,10 @@ class CFEASolver : public CFEASolverBase {
575575
Total_ComboObj = Total_Custom_ObjFunc;
576576
break;
577577
}
578+
if (config->GetWeakly_Coupled_Heat()) {
579+
solver[HEAT_SOL]->Evaluate_ObjFunc(config, solver);
580+
Total_ComboObj += solver[HEAT_SOL]->GetTotal_ComboObj();
581+
}
578582
}
579583

580584
/*!

SU2_CFD/src/drivers/CDriver.cpp

Lines changed: 12 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2769,9 +2769,10 @@ void CDriver::PrintDirectResidual(RECORDING kind_recording) {
27692769

27702770
/*--- Helper lambda func to return lenghty [iVar][iZone] string. ---*/
27712771
auto iVar_iZone2string = [&](unsigned short ivar, unsigned short izone) {
2772-
if (multizone)
2772+
if (multizone) {
27732773
return "[" + std::to_string(ivar) + "][" + std::to_string(izone) + "]";
2774-
return "[" + std::to_string(ivar) + "]";
2774+
}
2775+
return "[" + std::to_string(ivar) + "]";
27752776
};
27762777

27772778
/*--- Print residuals in the first iteration ---*/
@@ -2827,37 +2828,33 @@ void CDriver::PrintDirectResidual(RECORDING kind_recording) {
28272828
if (!addVals) RMSTable.AddColumn("rms_Rad" + iVar_iZone2string(0, iZone), fieldWidth);
28282829
else RMSTable << log10(solvers[RAD_SOL]->GetRes_RMS(0));
28292830
}
2830-
2831-
}
2832-
else if (configs->GetStructuralProblem()) {
2833-
2831+
} else if (configs->GetStructuralProblem()) {
28342832
if (configs->GetGeometricConditions() == STRUCT_DEFORMATION::LARGE){
28352833
if (!addVals) {
28362834
RMSTable.AddColumn("UTOL-A", fieldWidth);
28372835
RMSTable.AddColumn("RTOL-A", fieldWidth);
28382836
RMSTable.AddColumn("ETOL-A", fieldWidth);
2839-
}
2840-
else {
2837+
} else {
28412838
RMSTable << log10(solvers[FEA_SOL]->GetRes_FEM(0))
28422839
<< log10(solvers[FEA_SOL]->GetRes_FEM(1))
28432840
<< log10(solvers[FEA_SOL]->GetRes_FEM(2));
28442841
}
2845-
}
2846-
else{
2842+
} else {
28472843
if (!addVals) {
28482844
RMSTable.AddColumn("log10[RMS Ux]", fieldWidth);
28492845
RMSTable.AddColumn("log10[RMS Uy]", fieldWidth);
28502846
if (nDim == 3) RMSTable.AddColumn("log10[RMS Uz]", fieldWidth);
2851-
}
2852-
else {
2847+
} else {
28532848
RMSTable << log10(solvers[FEA_SOL]->GetRes_FEM(0))
28542849
<< log10(solvers[FEA_SOL]->GetRes_FEM(1));
28552850
if (nDim == 3) RMSTable << log10(solvers[FEA_SOL]->GetRes_FEM(2));
28562851
}
28572852
}
2858-
2859-
}
2860-
else if (configs->GetHeatProblem()) {
2853+
if (configs->GetWeakly_Coupled_Heat()){
2854+
if (!addVals) RMSTable.AddColumn("rms_Heat", fieldWidth);
2855+
else RMSTable << log10(solvers[HEAT_SOL]->GetRes_RMS(0));
2856+
}
2857+
} else if (configs->GetHeatProblem()) {
28612858

28622859
if (!addVals) RMSTable.AddColumn("rms_Heat" + iVar_iZone2string(0, iZone), fieldWidth);
28632860
else RMSTable << log10(solvers[HEAT_SOL]->GetRes_RMS(0));

SU2_CFD/src/iteration/CDiscAdjFEAIteration.cpp

Lines changed: 43 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -26,13 +26,20 @@
2626
*/
2727

2828
#include "../../include/iteration/CDiscAdjFEAIteration.hpp"
29+
#include "../../include/iteration/CDiscAdjHeatIteration.hpp"
2930
#include "../../include/iteration/CFEAIteration.hpp"
3031
#include "../../include/solvers/CFEASolver.hpp"
3132
#include "../../include/output/COutput.hpp"
3233

33-
CDiscAdjFEAIteration::CDiscAdjFEAIteration(const CConfig *config) : CIteration(config), CurrentRecording(NONE) {}
34+
CDiscAdjFEAIteration::CDiscAdjFEAIteration(const CConfig *config) : CIteration(config), CurrentRecording(NONE) {
35+
if (config->GetWeakly_Coupled_Heat()) {
36+
DiscAdjHeatIteration = new CDiscAdjHeatIteration(config);
37+
}
38+
}
3439

35-
CDiscAdjFEAIteration::~CDiscAdjFEAIteration() {}
40+
CDiscAdjFEAIteration::~CDiscAdjFEAIteration() {
41+
delete DiscAdjHeatIteration;
42+
}
3643

3744
void CDiscAdjFEAIteration::Preprocess(COutput* output, CIntegration**** integration, CGeometry**** geometry,
3845
CSolver***** solver, CNumerics****** numerics, CConfig** config,
@@ -90,6 +97,10 @@ void CDiscAdjFEAIteration::Preprocess(COutput* output, CIntegration**** integrat
9097

9198
solvers0[ADJFEA_SOL]->Preprocessing(geometry0, solvers0, config[iZone], MESH_0, 0, RUNTIME_ADJFEA_SYS, false);
9299

100+
if (DiscAdjHeatIteration) {
101+
DiscAdjHeatIteration->Preprocess(output, integration, geometry, solver, numerics, config, surface_movement,
102+
grid_movement, FFDBox, iZone, iInst);
103+
}
93104
}
94105

95106
void CDiscAdjFEAIteration::LoadDynamic_Solution(CGeometry**** geometry, CSolver***** solver, CConfig** config,
@@ -115,23 +126,23 @@ void CDiscAdjFEAIteration::IterateDiscAdj(CGeometry**** geometry, CSolver***** s
115126
unsigned short iZone, unsigned short iInst, bool CrossTerm) {
116127

117128
/*--- Extract the adjoints of the conservative input variables and store them for the next iteration ---*/
118-
119-
solver[iZone][iInst][MESH_0][ADJFEA_SOL]->ExtractAdjoint_Solution(geometry[iZone][iInst][MESH_0], config[iZone],
120-
CrossTerm);
121-
122-
solver[iZone][iInst][MESH_0][ADJFEA_SOL]->ExtractAdjoint_Variables(geometry[iZone][iInst][MESH_0], config[iZone]);
129+
for (const auto iSol : {ADJFEA_SOL, ADJHEAT_SOL}) {
130+
if (auto* sol = solver[iZone][iInst][MESH_0][iSol]; sol != nullptr) {
131+
sol->ExtractAdjoint_Solution(geometry[iZone][iInst][MESH_0], config[iZone], CrossTerm);
132+
sol->ExtractAdjoint_Variables(geometry[iZone][iInst][MESH_0], config[iZone]);
133+
}
134+
}
123135
}
124136

125137
void CDiscAdjFEAIteration::RegisterInput(CSolver***** solver, CGeometry**** geometry, CConfig** config,
126138
unsigned short iZone, unsigned short iInst, RECORDING kind_recording) {
127139
if (kind_recording != RECORDING::MESH_COORDS) {
128-
/*--- Register structural displacements as input ---*/
129-
130-
solver[iZone][iInst][MESH_0][ADJFEA_SOL]->RegisterSolution(geometry[iZone][iInst][MESH_0], config[iZone]);
131-
132-
/*--- Register variables as input ---*/
133-
134-
solver[iZone][iInst][MESH_0][ADJFEA_SOL]->RegisterVariables(geometry[iZone][iInst][MESH_0], config[iZone]);
140+
for (const auto iSol : {ADJFEA_SOL, ADJHEAT_SOL}) {
141+
if (auto* sol = solver[iZone][iInst][MESH_0][iSol]; sol != nullptr) {
142+
sol->RegisterSolution(geometry[iZone][iInst][MESH_0], config[iZone]);
143+
sol->RegisterVariables(geometry[iZone][iInst][MESH_0], config[iZone]);
144+
}
145+
}
135146
} else {
136147
/*--- Register topology optimization densities (note direct solver) ---*/
137148

@@ -146,6 +157,10 @@ void CDiscAdjFEAIteration::RegisterInput(CSolver***** solver, CGeometry**** geom
146157
void CDiscAdjFEAIteration::SetDependencies(CSolver***** solver, CGeometry**** geometry, CNumerics****** numerics,
147158
CConfig** config, unsigned short iZone, unsigned short iInst,
148159
RECORDING kind_recording) {
160+
if (DiscAdjHeatIteration) {
161+
DiscAdjHeatIteration->SetDependencies(solver, geometry, numerics, config, iZone, iInst, kind_recording);
162+
}
163+
149164
auto dir_solver = solver[iZone][iInst][MESH_0][FEA_SOL];
150165
auto adj_solver = solver[iZone][iInst][MESH_0][ADJFEA_SOL];
151166
auto structural_geometry = geometry[iZone][iInst][MESH_0];
@@ -263,18 +278,25 @@ void CDiscAdjFEAIteration::SetDependencies(CSolver***** solver, CGeometry**** ge
263278

264279
void CDiscAdjFEAIteration::RegisterOutput(CSolver***** solver, CGeometry**** geometry, CConfig** config,
265280
unsigned short iZone, unsigned short iInst) {
266-
/*--- Register conservative variables as output of the iteration ---*/
267-
268-
solver[iZone][iInst][MESH_0][ADJFEA_SOL]->RegisterOutput(geometry[iZone][iInst][MESH_0], config[iZone]);
281+
/*--- Register solution variables as output of the iteration. ---*/
282+
for (const auto iSol : {ADJFEA_SOL, ADJHEAT_SOL}) {
283+
if (auto* sol = solver[iZone][iInst][MESH_0][iSol]; sol != nullptr) {
284+
sol->RegisterOutput(geometry[iZone][iInst][MESH_0], config[iZone]);
285+
}
286+
}
269287
}
270288

271289
void CDiscAdjFEAIteration::InitializeAdjoint(CSolver***** solver, CGeometry**** geometry, CConfig** config,
272290
unsigned short iZone, unsigned short iInst) {
273-
/*--- Initialize the adjoints the conservative variables ---*/
291+
/*--- Initialize the adjoints of the solution variables. ---*/
274292

275293
AD::ResizeAdjoints();
276294
AD::BeginUseAdjoints();
277-
solver[iZone][iInst][MESH_0][ADJFEA_SOL]->SetAdjoint_Output(geometry[iZone][iInst][MESH_0], config[iZone]);
295+
for (const auto iSol : {ADJFEA_SOL, ADJHEAT_SOL}) {
296+
if (auto* sol = solver[iZone][iInst][MESH_0][iSol]; sol != nullptr) {
297+
sol->SetAdjoint_Output(geometry[iZone][iInst][MESH_0], config[iZone]);
298+
}
299+
}
278300
AD::EndUseAdjoints();
279301
}
280302

@@ -285,8 +307,8 @@ bool CDiscAdjFEAIteration::Monitor(COutput* output, CIntegration**** integration
285307
/*--- Write the convergence history (only screen output) ---*/
286308

287309
output->SetHistoryOutput(geometry[iZone][INST_0][MESH_0], solver[iZone][INST_0][MESH_0], config[iZone],
288-
config[iZone]->GetTimeIter(), config[iZone]->GetOuterIter(),
289-
config[iZone]->GetInnerIter());
310+
config[iZone]->GetTimeIter(), config[iZone]->GetOuterIter(),
311+
config[iZone]->GetInnerIter());
290312

291313
return output->GetConvergence();
292314
}

SU2_CFD/src/output/CAdjElasticityOutput.cpp

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,13 +27,16 @@
2727

2828

2929
#include "../../include/output/CAdjElasticityOutput.hpp"
30+
#include "../../include/output/CAdjHeatOutput.hpp"
3031
#include <string>
3132

3233
#include "../../../Common/include/geometry/CGeometry.hpp"
3334
#include "../../include/solvers/CSolver.hpp"
3435

3536
CAdjElasticityOutput::CAdjElasticityOutput(CConfig *config, unsigned short nDim) : COutput(config, nDim, false) {
3637

38+
coupled_heat = config->GetWeakly_Coupled_Heat();
39+
3740
/*--- Initialize number of variables ---*/
3841
nVar_FEM = nDim;
3942

@@ -51,8 +54,10 @@ CAdjElasticityOutput::CAdjElasticityOutput(CConfig *config, unsigned short nDim)
5154
requestedScreenFields.emplace_back("INNER_ITER");
5255
requestedScreenFields.emplace_back("ADJOINT_DISP_X");
5356
requestedScreenFields.emplace_back("ADJOINT_DISP_Y");
57+
if (coupled_heat) requestedScreenFields.emplace_back("RMS_ADJ_TEMPERATURE");
5458
requestedScreenFields.emplace_back("SENS_E_0");
5559
requestedScreenFields.emplace_back("SENS_NU_0");
60+
if (coupled_heat) requestedScreenFields.emplace_back("SENS_GEO");
5661
nRequestedScreenFields = requestedScreenFields.size();
5762
}
5863

@@ -134,6 +139,12 @@ void CAdjElasticityOutput::SetHistoryOutputFields(CConfig *config){
134139
AddHistoryOutput("BGS_ADJ_DISP_Z", "bgs[A_Uz]", ScreenOutputFormat::FIXED, "BGS_RES", "BGS residual of the adjoint Z displacement.", HistoryFieldType::RESIDUAL);
135140
}
136141
}
142+
143+
if (coupled_heat) {
144+
CAdjHeatOutput::SetHistoryOutputFieldsImpl(config, this);
145+
AddHistoryOutput("LINSOL_ITER_HEAT", "LinSolIterHeat", ScreenOutputFormat::INTEGER, "LINSOL", "Number of iterations of the linear solver.");
146+
AddHistoryOutput("LINSOL_RESIDUAL_HEAT", "LinSolResHeat", ScreenOutputFormat::FIXED, "LINSOL", "Residual of the linear solver.");
147+
}
137148
}
138149

139150
inline void CAdjElasticityOutput::LoadHistoryData(CConfig *config, CGeometry *geometry, CSolver **solver) {
@@ -173,6 +184,13 @@ inline void CAdjElasticityOutput::LoadHistoryData(CConfig *config, CGeometry *ge
173184
}
174185
}
175186

187+
/*--- Add heat solver data if available. ---*/
188+
if (coupled_heat) {
189+
CAdjHeatOutput::LoadHistoryDataImpl(config, geometry, solver, this);
190+
SetHistoryOutputValue("LINSOL_ITER_HEAT", solver[ADJHEAT_SOL]->GetIterLinSolver());
191+
SetHistoryOutputValue("LINSOL_RESIDUAL_HEAT", log10(solver[ADJHEAT_SOL]->GetResLinSolver()));
192+
}
193+
176194
ComputeSimpleCustomOutputs(config);
177195
}
178196

@@ -191,6 +209,11 @@ void CAdjElasticityOutput::LoadVolumeData(CConfig *config, CGeometry *geometry,
191209
if (nVar_FEM == 3)
192210
SetVolumeOutputValue("ADJOINT-Z", iPoint, Node_Struc->GetSolution(iPoint, 2));
193211

212+
if (coupled_heat) {
213+
const auto* Node_Heat = solver[ADJHEAT_SOL]->GetNodes();
214+
SetVolumeOutputValue("ADJ_TEMPERATURE", iPoint, Node_Heat->GetSolution(iPoint, 0));
215+
}
216+
194217
SetVolumeOutputValue("SENSITIVITY-X", iPoint, Node_Struc->GetSensitivity(iPoint, 0));
195218
SetVolumeOutputValue("SENSITIVITY-Y", iPoint, Node_Struc->GetSensitivity(iPoint, 1));
196219
if (nDim == 3)
@@ -212,6 +235,14 @@ void CAdjElasticityOutput::LoadVolumeData(CConfig *config, CGeometry *geometry,
212235
SetVolumeOutputValue("SENS_ACCEL-Y", iPoint, Node_Struc->GetSolution_time_n(iPoint, 2 * nDim + 1));
213236
if (nDim == 3)
214237
SetVolumeOutputValue("SENS_ACCEL-Z", iPoint, Node_Struc->GetSolution_time_n(iPoint, 8));
238+
239+
if (coupled_heat) {
240+
const auto* Node_Heat = solver[ADJHEAT_SOL]->GetNodes();
241+
SetVolumeOutputValue("SENS_TEMP_N", iPoint, Node_Heat->GetSolution_time_n(iPoint, 0));
242+
if (config->GetTime_Marching() == TIME_MARCHING::DT_STEPPING_2ND) {
243+
SetVolumeOutputValue("SENS_TEMP_N1", iPoint, Node_Heat->GetSolution_time_n1(iPoint, 0));
244+
}
245+
}
215246
}
216247

217248
void CAdjElasticityOutput::SetVolumeOutputFields(CConfig *config){
@@ -232,6 +263,10 @@ void CAdjElasticityOutput::SetVolumeOutputFields(CConfig *config){
232263
AddVolumeOutput("ADJOINT-Z", "Adjoint_z", "SOLUTION", "adjoint of displacement in the z direction");
233264
/// END_GROUP
234265

266+
if (coupled_heat) {
267+
AddVolumeOutput("ADJ_TEMPERATURE", "Adjoint_Temperature", "SOLUTION", "Adjoint Temperature");
268+
}
269+
235270
/// BEGIN_GROUP: SENSITIVITY, DESCRIPTION: Geometrical sensitivities of the current objective function.
236271
/// DESCRIPTION: Sensitivity x-component.
237272
AddVolumeOutput("SENSITIVITY-X", "Sensitivity_x", "SENSITIVITY", "geometric sensitivity in the x direction");
@@ -261,4 +296,10 @@ void CAdjElasticityOutput::SetVolumeOutputFields(CConfig *config){
261296
if (nDim == 3)
262297
AddVolumeOutput("SENS_ACCEL-Z", "SensitivityAccelN_z", "SENSITIVITY_N", "sensitivity to the previous z acceleration");
263298

299+
if (coupled_heat) {
300+
AddVolumeOutput("SENS_TEMP_N", "SensitivityTempN", "SENSITIVITY_N", "sensitivity to the previous temperature");
301+
if (config->GetTime_Marching() == TIME_MARCHING::DT_STEPPING_2ND) {
302+
AddVolumeOutput("SENS_TEMP_N1", "SensitivityTempN1", "SENSITIVITY_N", "sensitivity to the previous-1 temperature");
303+
}
304+
}
264305
}

0 commit comments

Comments
 (0)