Skip to content

Commit 9b28e74

Browse files
committed
cleanup the time integration of fea material sensitivities
1 parent 9cd5350 commit 9b28e74

13 files changed

Lines changed: 125 additions & 231 deletions

File tree

Common/include/CConfig.hpp

Lines changed: 6 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -2108,17 +2108,11 @@ class CConfig {
21082108
su2double GetElasticyMod(unsigned short id_val) const { return ElasticityMod[id_val]; }
21092109

21102110
/*!
2111-
* \brief Decide whether to apply DE effects to the model.
2112-
* \return <code>TRUE</code> if the DE effects are to be applied, <code>FALSE</code> otherwise.
2113-
*/
2111+
* \brief Decide whether to apply DE effects to the model.
2112+
* \return <code>TRUE</code> if the DE effects are to be applied, <code>FALSE</code> otherwise.
2113+
*/
21142114
bool GetDE_Effects(void) const { return DE_Effects; }
21152115

2116-
/*!
2117-
* \brief Decide whether to predict the DE effects for the next time step.
2118-
* \return <code>TRUE</code> if the DE effects are to be applied, <code>FALSE</code> otherwise.
2119-
*/
2120-
bool GetDE_Predicted(void);
2121-
21222116
/*!
21232117
* \brief Get the number of different electric constants.
21242118
* \return Value of the DE modulus.
@@ -8749,22 +8743,10 @@ class CConfig {
87498743
unsigned short GetnIntCoeffs(void) const { return nIntCoeffs; }
87508744

87518745
/*!
8752-
* \brief Get the number of different values for the elasticity modulus.
8753-
* \return Number of different values for the elasticity modulus.
8754-
*/
8755-
unsigned short GetnElasticityMod(void) const { return nElasticityMod; }
8756-
8757-
/*!
8758-
* \brief Get the number of different values for the Poisson ratio.
8759-
* \return Number of different values for the Poisson ratio.
8760-
*/
8761-
unsigned short GetnPoissonRatio(void) const { return nPoissonRatio; }
8762-
8763-
/*!
8764-
* \brief Get the number of different values for the Material density.
8765-
* \return Number of different values for the Material density.
8746+
* \brief Get the number of different materials for the elasticity solver.
8747+
* \return Number of different materials.
87668748
*/
8767-
unsigned short GetnMaterialDensity(void) const { return nMaterialDensity; }
8749+
unsigned short GetnElasticityMat(void) const { return nElasticityMod; }
87688750

87698751
/*!
87708752
* \brief Get the integration coefficients for the Generalized Alpha - Newmark integration integration scheme.

Common/src/CConfig.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4648,6 +4648,11 @@ void CConfig::SetPostprocessing(SU2_COMPONENT val_software, unsigned short val_i
46484648
MaterialDensity = new su2double[1]; MaterialDensity[0] = 7854;
46494649
}
46504650

4651+
if (nElasticityMod != nPoissonRatio || nElasticityMod != nMaterialDensity) {
4652+
SU2_MPI::Error("ELASTICITY_MODULUS, POISSON_RATIO, and MATERIAL_DENSITY need to have the same number "
4653+
"of entries (the number of materials).", CURRENT_FUNCTION);
4654+
}
4655+
46514656
if (nElectric_Constant == 0) {
46524657
nElectric_Constant = 1;
46534658
Electric_Constant = new su2double[1]; Electric_Constant[0] = 0.0;

SU2_CFD/include/solvers/CDiscAdjFEASolver.hpp

Lines changed: 14 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,8 @@ class CDiscAdjFEASolver final : public CSolver {
5050
su2double* val = nullptr; /*!< \brief Value of the variable. */
5151
su2double* LocalSens = nullptr; /*!< \brief Local sensitivity (domain). */
5252
su2double* GlobalSens = nullptr; /*!< \brief Global sensitivity (mpi). */
53-
su2double* TotalSens = nullptr; /*!< \brief Total sensitivity (time domain). */
53+
su2double* OldSens = nullptr; /*!< \brief Previous global sensitivity, used to update the total. */
54+
su2double* TotalSens = nullptr; /*!< \brief Total sensitivity (integrated over time). */
5455

5556
su2double& operator[] (unsigned short i) { return val[i]; }
5657
const su2double& operator[] (unsigned short i) const { return val[i]; }
@@ -61,6 +62,7 @@ class CDiscAdjFEASolver final : public CSolver {
6162
val = new su2double[n]();
6263
LocalSens = new su2double[n]();
6364
GlobalSens = new su2double[n]();
65+
OldSens = new su2double[n]();
6466
TotalSens = new su2double[n]();
6567
}
6668

@@ -69,6 +71,7 @@ class CDiscAdjFEASolver final : public CSolver {
6971
delete [] val;
7072
delete [] LocalSens;
7173
delete [] GlobalSens;
74+
delete [] OldSens;
7275
delete [] TotalSens;
7376
}
7477

@@ -80,10 +83,19 @@ class CDiscAdjFEASolver final : public CSolver {
8083
for (auto i = 0u; i < size; ++i) LocalSens[i] = SU2_TYPE::GetDerivative(val[i]);
8184

8285
SU2_MPI::Allreduce(LocalSens, GlobalSens, size, MPI_DOUBLE, MPI_SUM, SU2_MPI::GetComm());
86+
87+
for (auto i = 0u; i < size; ++i) {
88+
/*--- Update the total by subtracting the old and adding the new value.
89+
* Then update the old value for the next call to this function. ---*/
90+
TotalSens[i] += GlobalSens[i] - OldSens[i];
91+
OldSens[i] = GlobalSens[i];
92+
}
8393
}
8494

8595
void UpdateTotal() {
86-
for (auto i = 0u; i < size; ++i) TotalSens[i] += GlobalSens[i];
96+
/*--- Clears the old values such that on the next time step the total is
97+
* incremented instead of updated. ---*/
98+
for (auto i = 0u; i < size; ++i) OldSens[i] = 0.0;
8799
}
88100

89101
~SensData() { clear(); }
@@ -213,42 +225,6 @@ class CDiscAdjFEASolver final : public CSolver {
213225
*/
214226
inline su2double GetTotal_Sens_DVFEA(unsigned short iDVFEA) const override { return DV.TotalSens[iDVFEA]; }
215227

216-
/*!
217-
* \brief A virtual member.
218-
* \return Value of the sensitivity coefficient for the Young Modulus E
219-
*/
220-
inline su2double GetGlobal_Sens_E(unsigned short iVal) const override { return E.GlobalSens[iVal]; }
221-
222-
/*!
223-
* \brief A virtual member.
224-
* \return Value of the Mach sensitivity for the Poisson's ratio Nu
225-
*/
226-
inline su2double GetGlobal_Sens_Nu(unsigned short iVal) const override { return Nu.GlobalSens[iVal]; }
227-
228-
/*!
229-
* \brief A virtual member.
230-
* \return Value of the sensitivity coefficient for the Electric Field in the region iEField
231-
*/
232-
inline su2double GetGlobal_Sens_EField(unsigned short iEField) const override { return EField.GlobalSens[iEField]; }
233-
234-
/*!
235-
* \brief A virtual member.
236-
* \return Value of the sensitivity coefficient for the FEA DV in the region iDVFEA
237-
*/
238-
inline su2double GetGlobal_Sens_DVFEA(unsigned short iDVFEA) const override { return DV.GlobalSens[iDVFEA]; }
239-
240-
/*!
241-
* \brief Get the total sensitivity for the structural density
242-
* \return Value of the structural density sensitivity
243-
*/
244-
inline su2double GetGlobal_Sens_Rho(unsigned short iVal) const override { return Rho.GlobalSens[iVal]; }
245-
246-
/*!
247-
* \brief Get the total sensitivity for the structural weight
248-
* \return Value of the structural weight sensitivity
249-
*/
250-
inline su2double GetGlobal_Sens_Rho_DL(unsigned short iVal) const override { return Rho_DL.GlobalSens[iVal]; }
251-
252228
/*!
253229
* \brief Get the value of the Young modulus from the adjoint solver
254230
* \return Value of the Young modulus from the adjoint solver

SU2_CFD/include/solvers/CSolver.hpp

Lines changed: 0 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -3201,42 +3201,6 @@ class CSolver {
32013201
*/
32023202
inline virtual su2double GetTotal_Sens_DVFEA(unsigned short iDVFEA) const { return 0.0; }
32033203

3204-
/*!
3205-
* \brief A virtual member.
3206-
* \return Value of the sensitivity coefficient for the Young Modulus E
3207-
*/
3208-
inline virtual su2double GetGlobal_Sens_E(unsigned short iVal) const { return 0.0; }
3209-
3210-
/*!
3211-
* \brief A virtual member.
3212-
* \return Value of the sensitivity coefficient for the Poisson's ratio Nu
3213-
*/
3214-
inline virtual su2double GetGlobal_Sens_Nu(unsigned short iVal) const { return 0.0; }
3215-
3216-
/*!
3217-
* \brief A virtual member.
3218-
* \return Value of the structural density sensitivity
3219-
*/
3220-
inline virtual su2double GetGlobal_Sens_Rho(unsigned short iVal) const { return 0.0; }
3221-
3222-
/*!
3223-
* \brief A virtual member.
3224-
* \return Value of the structural weight sensitivity
3225-
*/
3226-
inline virtual su2double GetGlobal_Sens_Rho_DL(unsigned short iVal) const { return 0.0; }
3227-
3228-
/*!
3229-
* \brief A virtual member.
3230-
* \return Value of the sensitivity coefficient for the Electric Field in the region iEField
3231-
*/
3232-
inline virtual su2double GetGlobal_Sens_EField(unsigned short iEField) const { return 0.0; }
3233-
3234-
/*!
3235-
* \brief A virtual member.
3236-
* \return Value of the sensitivity coefficient for the FEA DV in the region iDVFEA
3237-
*/
3238-
inline virtual su2double GetGlobal_Sens_DVFEA(unsigned short iDVFEA) const { return 0.0; }
3239-
32403204
/*!
32413205
* \brief A virtual member.
32423206
* \return Value of the Young modulus from the adjoint solver

SU2_CFD/src/iteration/CDiscAdjFEAIteration.cpp

Lines changed: 32 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -32,32 +32,6 @@
3232

3333
CDiscAdjFEAIteration::CDiscAdjFEAIteration(const CConfig *config) : CIteration(config), CurrentRecording(NONE) {
3434
fem_iteration = new CFEAIteration(config);
35-
36-
// TEMPORARY output only for standalone structural problems
37-
if (config->GetAdvanced_FEAElementBased() && (rank == MASTER_NODE)) {
38-
bool de_effects = config->GetDE_Effects();
39-
unsigned short iVar;
40-
41-
/*--- Header of the temporary output file ---*/
42-
ofstream myfile_res;
43-
myfile_res.open("Results_Reverse_Adjoint.txt");
44-
45-
myfile_res << "Obj_Func"
46-
<< " ";
47-
for (iVar = 0; iVar < config->GetnElasticityMod(); iVar++) myfile_res << "Sens_E_" << iVar << "\t";
48-
49-
for (iVar = 0; iVar < config->GetnPoissonRatio(); iVar++) myfile_res << "Sens_Nu_" << iVar << "\t";
50-
51-
if (config->GetTime_Domain()) {
52-
for (iVar = 0; iVar < config->GetnMaterialDensity(); iVar++) myfile_res << "Sens_Rho_" << iVar << "\t";
53-
}
54-
55-
if (de_effects) {
56-
for (iVar = 0; iVar < config->GetnElectric_Field(); iVar++) myfile_res << "Sens_EField_" << iVar << "\t";
57-
}
58-
59-
myfile_res << "\n";
60-
}
6135
}
6236

6337
CDiscAdjFEAIteration::~CDiscAdjFEAIteration() = default;
@@ -71,31 +45,49 @@ void CDiscAdjFEAIteration::Preprocess(COutput* output, CIntegration**** integrat
7145
auto dirNodes = solvers0[FEA_SOL]->GetNodes();
7246
auto adjNodes = solvers0[ADJFEA_SOL]->GetNodes();
7347

74-
/*--- For the dynamic adjoint, load direct solutions from restart files. ---*/
48+
auto StoreDirectSolution = [&]() {
49+
for (auto iPoint = 0ul; iPoint < geometry0->GetnPoint(); iPoint++) {
50+
adjNodes->SetSolution_Direct(iPoint, dirNodes->GetSolution(iPoint));
51+
}
52+
};
53+
54+
/*--- For the dynamic adjoint, load direct solutions from restart files.
55+
* For steady, store the direct solution to be able to reset it later. ---*/
7556

7657
if (config[iZone]->GetTime_Domain()) {
7758
const int TimeIter = config[iZone]->GetTimeIter();
7859
const int Direct_Iter = SU2_TYPE::Int(config[iZone]->GetUnst_AdjointIter()) - TimeIter - 1;
7960

80-
/*--- We want to load the already converged solution at timesteps n and n-1 ---*/
81-
82-
/*--- Load solution at timestep n-1 ---*/
61+
/*--- We need the already converged solution at timesteps n and n-1. On the first
62+
* adjoint time step we load both, then n-1 becomes "n" and we only load n-2. ---*/
8363

84-
LoadDynamic_Solution(geometry, solver, config, iZone, iInst, Direct_Iter - 1);
64+
if (TimeIter > 0) {
65+
/*--- Save n-1 to become n. ---*/
66+
for (auto iPoint = 0ul; iPoint < geometry0->GetnPoint(); iPoint++) {
67+
adjNodes->SetSolution_Direct(iPoint, dirNodes->GetSolution_time_n(iPoint));
68+
}
69+
}
8570

86-
/*--- Push solution back to correct array ---*/
71+
/*--- Load solution at timestep n-1 and push back to correct array. ---*/
8772

73+
LoadDynamic_Solution(geometry, solver, config, iZone, iInst, Direct_Iter - 1);
8874
dirNodes->Set_Solution_time_n();
8975

90-
/*--- Load solution timestep n ---*/
76+
/*--- Load or set solution at timestep n. ---*/
9177

92-
LoadDynamic_Solution(geometry, solver, config, iZone, iInst, Direct_Iter);
93-
}
94-
95-
/*--- Store FEA solution also in the adjoint solver in order to be able to reset it later. ---*/
78+
if (TimeIter == 0) {
79+
LoadDynamic_Solution(geometry, solver, config, iZone, iInst, Direct_Iter);
80+
StoreDirectSolution();
81+
} else {
82+
/*--- Set n-1 as n. ---*/
83+
for (auto iPoint = 0ul; iPoint < geometry0->GetnPoint(); iPoint++)
84+
for (auto iVar = 0u; iVar < solvers0[ADJFEA_SOL]->GetnVar(); iVar++)
85+
dirNodes->SetSolution(iPoint, iVar, adjNodes->GetSolution_Direct(iPoint)[iVar]);
86+
}
9687

97-
for (auto iPoint = 0ul; iPoint < geometry0->GetnPoint(); iPoint++) {
98-
adjNodes->SetSolution_Direct(iPoint, dirNodes->GetSolution(iPoint));
88+
} else {
89+
/*--- Steady. ---*/
90+
StoreDirectSolution();
9991
}
10092

10193
solvers0[ADJFEA_SOL]->Preprocessing(geometry0, solvers0, config[iZone], MESH_0, 0, RUNTIME_ADJFEA_SYS, false);
@@ -178,7 +170,7 @@ void CDiscAdjFEAIteration::SetDependencies(CSolver***** solver, CGeometry**** ge
178170
const int mat_knowles = MAT_KNOWLES+offset;
179171
const int de_term = DE_TERM+offset;
180172

181-
for (unsigned short iProp = 0; iProp < config[iZone]->GetnElasticityMod(); iProp++) {
173+
for (unsigned short iProp = 0; iProp < config[iZone]->GetnElasticityMat(); iProp++) {
182174
su2double E = adj_solver->GetVal_Young(iProp);
183175
su2double nu = adj_solver->GetVal_Poisson(iProp);
184176
su2double rho = adj_solver->GetVal_Rho(iProp);
@@ -302,45 +294,8 @@ void CDiscAdjFEAIteration::Postprocess(COutput* output, CIntegration**** integra
302294
CSolver***** solver, CNumerics****** numerics, CConfig** config,
303295
CSurfaceMovement** surface_movement, CVolumetricMovement*** grid_movement,
304296
CFreeFormDefBox*** FFDBox, unsigned short iZone, unsigned short iInst) {
305-
const bool dynamic = (config[iZone]->GetTime_Domain());
306297
auto solvers0 = solver[iZone][iInst][MESH_0];
307298

308-
// TEMPORARY output only for standalone structural problems
309-
if (config[iZone]->GetAdvanced_FEAElementBased() && (rank == MASTER_NODE)) {
310-
unsigned short iVar;
311-
312-
const bool de_effects = config[iZone]->GetDE_Effects();
313-
314-
/*--- Header of the temporary output file ---*/
315-
ofstream myfile_res;
316-
myfile_res.open("Results_Reverse_Adjoint.txt", ios::app);
317-
318-
myfile_res.precision(15);
319-
320-
myfile_res << config[iZone]->GetTimeIter() << "\t";
321-
322-
solvers0[FEA_SOL]->Evaluate_ObjFunc(config[iZone], solvers0);
323-
myfile_res << scientific << solvers0[FEA_SOL]->GetTotal_ComboObj() << "\t";
324-
325-
for (iVar = 0; iVar < config[iZone]->GetnElasticityMod(); iVar++)
326-
myfile_res << scientific << solvers0[ADJFEA_SOL]->GetTotal_Sens_E(iVar) << "\t";
327-
for (iVar = 0; iVar < config[iZone]->GetnPoissonRatio(); iVar++)
328-
myfile_res << scientific << solvers0[ADJFEA_SOL]->GetTotal_Sens_Nu(iVar) << "\t";
329-
if (dynamic) {
330-
for (iVar = 0; iVar < config[iZone]->GetnMaterialDensity(); iVar++)
331-
myfile_res << scientific << solvers0[ADJFEA_SOL]->GetTotal_Sens_Rho(iVar) << "\t";
332-
}
333-
if (de_effects) {
334-
for (iVar = 0; iVar < config[iZone]->GetnElectric_Field(); iVar++)
335-
myfile_res << scientific << solvers0[ADJFEA_SOL]->GetTotal_Sens_EField(iVar) << "\t";
336-
}
337-
for (iVar = 0; iVar < solvers0[ADJFEA_SOL]->GetnDVFEA(); iVar++) {
338-
myfile_res << scientific << solvers0[ADJFEA_SOL]->GetTotal_Sens_DVFEA(iVar) << "\t";
339-
}
340-
341-
myfile_res << "\n";
342-
}
343-
344299
// TEST: for implementation of python framework in standalone structural problems
345300
if (config[iZone]->GetAdvanced_FEAElementBased() && (rank == MASTER_NODE)) {
346301
/*--- Header of the temporary output file ---*/

SU2_CFD/src/numerics/elasticity/CFEAElasticity.cpp

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -38,23 +38,19 @@ CFEAElasticity::CFEAElasticity(unsigned short val_nDim, unsigned short val_nVar,
3838
bool body_forces = config->GetDeadLoad(); // Body forces (dead loads).
3939
bool pseudo_static = config->GetPseudoStatic();
4040

41-
unsigned short iVar, nProp;
41+
unsigned short iVar;
4242

4343
/*--- Initialize vector structures for multiple material definition ---*/
44-
nProp = config->GetnElasticityMod();
44+
const auto nProp = config->GetnElasticityMat();
4545

4646
E_i = new su2double[nProp];
4747
for (iVar = 0; iVar < nProp; iVar++)
4848
E_i[iVar] = config->GetElasticyMod(iVar);
4949

50-
nProp = config->GetnPoissonRatio();
51-
5250
Nu_i = new su2double[nProp];
5351
for (iVar = 0; iVar < nProp; iVar++)
5452
Nu_i[iVar] = config->GetPoissonRatio(iVar);
5553

56-
nProp = config->GetnMaterialDensity();
57-
5854
Rho_s_i = new su2double[nProp]; // For inertial effects
5955
Rho_s_DL_i = new su2double[nProp]; // For dead loads
6056

0 commit comments

Comments
 (0)