Skip to content

Commit 1fc88ac

Browse files
authored
Merge pull request #2404 from Vaish-W/coupled_thermoelasticity
[WIP] Coupled solver for thermoelasticity
2 parents f4cda52 + 3c83bbe commit 1fc88ac

File tree

5 files changed

+79
-0
lines changed

5 files changed

+79
-0
lines changed

SU2_CFD/include/solvers/CFEASolver.hpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,22 @@ class CFEASolver : public CFEASolverBase {
100100
bool initial_calc = true; /*!< \brief Becomes false after first call to Preprocessing. */
101101
bool body_forces = false; /*!< \brief Whether any body force is active. */
102102

103+
/*!
104+
* \brief Pointer to the heat solver for coupled simulations.
105+
*
106+
* This member stores a pointer to the heat solver, which handles
107+
* the solution of the heat equation in weakly coupled simulations.
108+
* It is initialized during the preprocessing step if the configuration
109+
* enables the weak coupling of heat and elasticity solvers. This solver
110+
* provides temperature information to the finite element elasticity solver
111+
* and contributes to the coupled residuals.
112+
*
113+
* The `heat_solver` pointer remains `nullptr` when the heat solver is not enabled
114+
* in the configuration. Memory for the heat solver is dynamically allocated
115+
* during initialization and released in the destructor to avoid memory leaks.
116+
*/
117+
CSolver* heat_solver = nullptr;
118+
103119
/*!
104120
* \brief The highest level in the variable hierarchy this solver can safely use,
105121
* CVariable is the common denominator between the FEA and Mesh deformation variables.

SU2_CFD/src/iteration/CFEAIteration.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,13 @@ void CFEAIteration::Iterate(COutput* output, CIntegration**** integration, CGeom
4848
CIntegration* feaIntegration = integration[val_iZone][val_iInst][FEA_SOL];
4949
CSolver* feaSolver = solver[val_iZone][val_iInst][MESH_0][FEA_SOL];
5050

51+
/*--- Add heat solver integration step ---*/
52+
if (config[val_iZone]->GetWeakly_Coupled_Heat()) {
53+
config[val_iZone]->SetGlobalParam(MAIN_SOLVER::HEAT_EQUATION, RUNTIME_HEAT_SYS);
54+
integration[val_iZone][val_iInst][HEAT_SOL]->SingleGrid_Iteration(
55+
geometry, solver, numerics, config, RUNTIME_HEAT_SYS, val_iZone, val_iInst);
56+
}
57+
5158
/*--- FEA equations ---*/
5259
config[val_iZone]->SetGlobalParam(MAIN_SOLVER::FEM_ELASTICITY, RUNTIME_FEA_SYS);
5360

SU2_CFD/src/output/CElasticityOutput.cpp

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,7 @@ CElasticityOutput::CElasticityOutput(CConfig *config, unsigned short nDim) : COu
106106
void CElasticityOutput::LoadHistoryData(CConfig *config, CGeometry *geometry, CSolver **solver) {
107107

108108
CSolver* fea_solver = solver[FEA_SOL];
109+
CSolver* heat_solver = solver[HEAT_SOL];
109110

110111
/*--- Residuals: ---*/
111112
/*--- Linear analysis: RMS of the displacements in the nDim coordinates ---*/
@@ -152,6 +153,15 @@ void CElasticityOutput::LoadHistoryData(CConfig *config, CGeometry *geometry, CS
152153
/*--- Keep this as last, since it uses the history values that were set. ---*/
153154
SetCustomAndComboObjectives(FEA_SOL, config, solver);
154155

156+
/*--- Add heat solver data if available ---*/
157+
if (heat_solver) {
158+
SetHistoryOutputValue("RMS_TEMPERATURE", log10(heat_solver->GetRes_RMS(0)));
159+
SetHistoryOutputValue("MAX_TEMPERATURE", log10(heat_solver->GetRes_Max(0)));
160+
SetHistoryOutputValue("AVG_TEMPERATURE", heat_solver->GetTotal_AvgTemperature());
161+
SetHistoryOutputValue("TOTAL_HEATFLUX", heat_solver->GetTotal_HeatFlux());
162+
SetHistoryOutputValue("MAXIMUM_HEATFLUX", heat_solver->GetTotal_MaxHeatFlux());
163+
}
164+
155165
}
156166

157167
void CElasticityOutput::SetHistoryOutputFields(CConfig *config) {
@@ -189,6 +199,14 @@ void CElasticityOutput::SetHistoryOutputFields(CConfig *config) {
189199
}
190200
AddHistoryOutput("COMBO", "ComboObj", ScreenOutputFormat::SCIENTIFIC, "COMBO", "Combined obj. function value.", HistoryFieldType::COEFFICIENT);
191201

202+
if (config->GetWeakly_Coupled_Heat()) {
203+
AddHistoryOutput("RMS_TEMPERATURE", "rms[T]", ScreenOutputFormat::FIXED, "RMS_RES", "Root mean square residual of the temperature", HistoryFieldType::RESIDUAL);
204+
AddHistoryOutput("MAX_TEMPERATURE", "max[T]", ScreenOutputFormat::FIXED, "MAX_RES", "Maximum residual of the temperature", HistoryFieldType::RESIDUAL);
205+
AddHistoryOutput("AVG_TEMPERATURE", "avg[T]", ScreenOutputFormat::SCIENTIFIC, "HEAT", "Average temperature on all surfaces", HistoryFieldType::COEFFICIENT);
206+
AddHistoryOutput("TOTAL_HEATFLUX", "HF", ScreenOutputFormat::SCIENTIFIC, "HEAT", "Total heat flux on all surfaces", HistoryFieldType::COEFFICIENT);
207+
AddHistoryOutput("MAXIMUM_HEATFLUX", "MaxHF", ScreenOutputFormat::SCIENTIFIC, "HEAT", "Maximum heat flux on all surfaces", HistoryFieldType::COEFFICIENT);
208+
}
209+
192210
}
193211

194212
void CElasticityOutput::LoadVolumeData(CConfig *config, CGeometry *geometry, CSolver **solver, unsigned long iPoint){
@@ -228,6 +246,14 @@ void CElasticityOutput::LoadVolumeData(CConfig *config, CGeometry *geometry, CSo
228246
if (config->GetTopology_Optimization()) {
229247
SetVolumeOutputValue("TOPOL_DENSITY", iPoint, Node_Struc->GetAuxVar(iPoint));
230248
}
249+
250+
CSolver* heat_solver = solver[HEAT_SOL];
251+
if (heat_solver) {
252+
const auto Node_Heat = heat_solver->GetNodes();
253+
SetVolumeOutputValue("TEMPERATURE", iPoint, Node_Heat->GetSolution(iPoint, 0));
254+
SetVolumeOutputValue("RES_TEMPERATURE", iPoint, heat_solver->LinSysRes(iPoint, 0));
255+
}
256+
231257
}
232258

233259
void CElasticityOutput::SetVolumeOutputFields(CConfig *config){
@@ -266,6 +292,12 @@ void CElasticityOutput::SetVolumeOutputFields(CConfig *config){
266292
if (config->GetTopology_Optimization()) {
267293
AddVolumeOutput("TOPOL_DENSITY", "Topology_Density", "TOPOLOGY", "filtered topology density");
268294
}
295+
296+
if (config->GetWeakly_Coupled_Heat()) {
297+
AddVolumeOutput("TEMPERATURE", "Temperature", "SOLUTION", "Temperature");
298+
AddVolumeOutput("RES_TEMPERATURE", "Residual_Temperature", "RESIDUAL", "Residual of the temperature");
299+
}
300+
269301
}
270302

271303
bool CElasticityOutput::SetInitResiduals(const CConfig *config){

SU2_CFD/src/solvers/CFEASolver.cpp

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
#include "../../include/numerics/elasticity/CFEAElasticity.hpp"
3131
#include "../../../Common/include/toolboxes/printing_toolbox.hpp"
3232
#include "../../../Common/include/toolboxes/geometry_toolbox.hpp"
33+
#include "../../include/solvers/CHeatSolver.hpp"
3334
#include <algorithm>
3435

3536
using namespace GeometryToolbox;
@@ -563,6 +564,10 @@ void CFEASolver::Preprocessing(CGeometry *geometry, CSolver **solver_container,
563564
const bool disc_adj_fem = (config->GetKind_Solver() == MAIN_SOLVER::DISC_ADJ_FEM);
564565
const bool topology_mode = config->GetTopology_Optimization();
565566

567+
if (config->GetWeakly_Coupled_Heat()) {
568+
heat_solver = solver_container[HEAT_SOL];
569+
}
570+
566571
/*
567572
* For topology optimization we apply a filter on the design density field to avoid
568573
* numerical issues (checkerboards), ensure mesh independence, and impose a length scale.
@@ -687,6 +692,10 @@ void CFEASolver::Compute_StiffMatrix(CGeometry *geometry, CNumerics **numerics,
687692
su2double val_Sol = nodes->GetSolution(indexNode[iNode],iDim) + val_Coord;
688693
element->SetRef_Coord(iNode, iDim, val_Coord);
689694
element->SetCurr_Coord(iNode, iDim, val_Sol);
695+
}
696+
if (heat_solver) {
697+
const su2double temperature = heat_solver->GetNodes()->GetSolution(indexNode[iNode], 0);
698+
element->SetTemperature(iNode, temperature);
690699
}
691700
}
692701

@@ -795,6 +804,10 @@ void CFEASolver::Compute_StiffMatrix_NodalStressRes(CGeometry *geometry, CNumeri
795804
de_elem->SetRef_Coord(iNode, iDim, val_Coord);
796805
}
797806
}
807+
if (heat_solver) {
808+
const su2double temperature = heat_solver->GetNodes()->GetSolution(indexNode[iNode], 0);
809+
fea_elem->SetTemperature(iNode, temperature);
810+
}
798811
}
799812

800813
/*--- In topology mode determine the penalty to apply to the stiffness. ---*/
@@ -1093,6 +1106,10 @@ void CFEASolver::Compute_NodalStressRes(CGeometry *geometry, CNumerics **numeric
10931106
element->SetCurr_Coord(iNode, iDim, val_Sol);
10941107
element->SetRef_Coord(iNode, iDim, val_Coord);
10951108
}
1109+
if (heat_solver) {
1110+
const su2double temperature = heat_solver->GetNodes()->GetSolution(indexNode[iNode], 0);
1111+
element->SetTemperature(iNode, temperature);
1112+
}
10961113
}
10971114

10981115
/*--- In topology mode determine the penalty to apply to the stiffness ---*/
@@ -1209,6 +1226,10 @@ void CFEASolver::Compute_NodalStress(CGeometry *geometry, CNumerics **numerics,
12091226
element->SetCurr_Coord(iNode, iDim, val_Sol);
12101227
element->SetRef_Coord(iNode, iDim, val_Coord);
12111228
}
1229+
if (heat_solver) {
1230+
const su2double temperature = heat_solver->GetNodes()->GetSolution(indexNode[iNode], 0);
1231+
element->SetTemperature(iNode, temperature);
1232+
}
12121233
}
12131234

12141235
/*--- In topology mode determine the penalty to apply to the stiffness ---*/

SU2_CFD/src/solvers/CSolverFactory.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,9 @@ CSolver** CSolverFactory::CreateSolverContainer(MAIN_SOLVER kindMainSolver, CCon
173173
break;
174174
case MAIN_SOLVER::FEM_ELASTICITY:
175175
solver[FEA_SOL] = CreateSubSolver(SUB_SOLVER_TYPE::FEA, solver, geometry, config, iMGLevel);
176+
if (config->GetWeakly_Coupled_Heat()) {
177+
solver[HEAT_SOL] = CreateSubSolver(SUB_SOLVER_TYPE::HEAT, solver, geometry, config, iMGLevel);
178+
}
176179
break;
177180
case MAIN_SOLVER::DISC_ADJ_FEM:
178181
solver[FEA_SOL] = CreateSubSolver(SUB_SOLVER_TYPE::FEA, solver, geometry, config, iMGLevel);

0 commit comments

Comments
 (0)