Skip to content

Commit 2fb25a5

Browse files
authored
Merge pull request #2399 from su2code/thermo_elastic
Add thermal expansion effects to FEA solver
2 parents dc6fd60 + f0808bd commit 2fb25a5

File tree

18 files changed

+163
-90
lines changed

18 files changed

+163
-90
lines changed

Common/include/CConfig.hpp

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1013,10 +1013,13 @@ class CConfig {
10131013
su2double *Int_Coeffs; /*!< \brief Time integration coefficients for structural method. */
10141014
unsigned short nElasticityMod, /*!< \brief Number of different values for the elasticity modulus. */
10151015
nPoissonRatio, /*!< \brief Number of different values for the Poisson ratio modulus. */
1016-
nMaterialDensity; /*!< \brief Number of different values for the Material density. */
1016+
nMaterialDensity, /*!< \brief Number of different values for the Material density. */
1017+
nMaterialThermalExpansion; /*!< \brief Number of different values for thermal expansion coefficient. */
10171018
su2double *ElasticityMod, /*!< \brief Value of the elasticity moduli. */
10181019
*PoissonRatio, /*!< \brief Value of the Poisson ratios. */
1019-
*MaterialDensity; /*!< \brief Value of the Material densities. */
1020+
*MaterialDensity, /*!< \brief Value of the Material densities. */
1021+
*MaterialThermalExpansion, /*!< \brief Value of the thermal expansion coefficients. */
1022+
MaterialReferenceTemperature; /*!< \brief Value of the reference temperature for thermal expansion. */
10201023
unsigned short nElectric_Field, /*!< \brief Number of different values for the electric field in the membrane. */
10211024
nDim_Electric_Field; /*!< \brief Dimensionality of the problem. */
10221025
unsigned short nDim_RefNode; /*!< \brief Dimensionality of the vector . */
@@ -2389,6 +2392,16 @@ class CConfig {
23892392
*/
23902393
su2double GetMaterialDensity(unsigned short id_val) const { return MaterialDensity[id_val]; }
23912394

2395+
/*!
2396+
* \brief Get the thermal expansion coefficient.
2397+
*/
2398+
su2double GetMaterialThermalExpansion(unsigned short id_val) const { return MaterialThermalExpansion[id_val]; }
2399+
2400+
/*!
2401+
* \brief Temperature at which there is no stress from thermal expansion.
2402+
*/
2403+
su2double GetMaterialReferenceTemperature() const { return MaterialReferenceTemperature; }
2404+
23922405
/*!
23932406
* \brief Compressibility/incompressibility of the solids analysed using the structural solver.
23942407
* \return Compressible or incompressible.

Common/include/geometry/elements/CElement.hpp

Lines changed: 34 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,8 @@ class CElement {
6767
su2activematrix NodalExtrap; /*!< \brief Coordinates of the nodal points for Gaussian extrapolation. */
6868
su2activematrix NodalStress; /*!< \brief Stress at the nodes. */
6969

70+
su2activevector NodalTemperature; /*!< \brief Temperature at the nodes. */
71+
7072
/*--- Stiffness and load matrices. ---*/
7173
std::vector<su2activematrix> Kab; /*!< \brief Structure for the constitutive component of the tangent matrix. */
7274
su2activematrix Mab; /*!< \brief Structure for the nodal components of the mass matrix. */
@@ -151,7 +153,7 @@ class CElement {
151153
* \param[in] iDim - Dimension.
152154
* \param[in] val_CoordRef - Value of the coordinate.
153155
*/
154-
inline void SetRef_Coord(unsigned short iNode, unsigned short iDim, su2double val_CoordRef) {
156+
inline void SetRef_Coord(unsigned short iNode, unsigned short iDim, const su2double& val_CoordRef) {
155157
RefCoord(iNode, iDim) = val_CoordRef;
156158
}
157159

@@ -161,10 +163,22 @@ class CElement {
161163
* \param[in] iDim - Dimension.
162164
* \param[in] val_CoordRef - Value of the coordinate.
163165
*/
164-
inline void SetCurr_Coord(unsigned short iNode, unsigned short iDim, su2double val_CoordCurr) {
166+
inline void SetCurr_Coord(unsigned short iNode, unsigned short iDim, const su2double& val_CoordCurr) {
165167
CurrentCoord(iNode, iDim) = val_CoordCurr;
166168
}
167169

170+
/*!
171+
* \brief Set the value of the temperature of a node.
172+
*/
173+
inline void SetTemperature(unsigned short iNode, const su2double& val_Temperature) {
174+
NodalTemperature[iNode] = val_Temperature;
175+
}
176+
177+
/*!
178+
* \brief Set the value of the temperature of all nodes.
179+
*/
180+
inline void SetTemperature(const su2double& val_Temperature) { NodalTemperature = val_Temperature; }
181+
168182
/*!
169183
* \brief Get the value of the coordinate of the nodes in the reference configuration.
170184
* \param[in] iNode - Index of node.
@@ -181,6 +195,17 @@ class CElement {
181195
*/
182196
inline su2double GetCurr_Coord(unsigned short iNode, unsigned short iDim) const { return CurrentCoord(iNode, iDim); }
183197

198+
/*!
199+
* \brief Get the value of the temperature at a Gaussian integration point.
200+
*/
201+
inline su2double GetTemperature(unsigned short iGauss) const {
202+
su2double Temperature = 0;
203+
for (auto iNode = 0u; iNode < nNodes; ++iNode) {
204+
Temperature += GetNi(iNode, iGauss) * NodalTemperature[iNode];
205+
}
206+
return Temperature;
207+
}
208+
184209
/*!
185210
* \brief Get the weight of the corresponding Gaussian Point.
186211
* \param[in] iGauss - index of the Gaussian point.
@@ -214,7 +239,9 @@ class CElement {
214239
* \param[in] nodeB - index of Node b.
215240
* \param[in] val_Ks_ab - value of the term that will constitute the diagonal of the stress contribution.
216241
*/
217-
inline void Add_Mab(unsigned short nodeA, unsigned short nodeB, su2double val_Mab) { Mab(nodeA, nodeB) += val_Mab; }
242+
inline void Add_Mab(unsigned short nodeA, unsigned short nodeB, const su2double& val_Mab) {
243+
Mab(nodeA, nodeB) += val_Mab;
244+
}
218245

219246
/*!
220247
* \brief Add the value of a submatrix K relating nodes a and b, for the constitutive term.
@@ -243,7 +270,7 @@ class CElement {
243270
* \param[in] nodeB - index of Node b.
244271
* \param[in] val_Ks_ab - value of the term that will constitute the diagonal of the stress contribution.
245272
*/
246-
inline void Add_Ks_ab(unsigned short nodeA, unsigned short nodeB, su2double val_Ks_ab) {
273+
inline void Add_Ks_ab(unsigned short nodeA, unsigned short nodeB, const su2double& val_Ks_ab) {
247274
Ks_ab(nodeA, nodeB) += val_Ks_ab;
248275
}
249276

@@ -354,7 +381,7 @@ class CElement {
354381
* \param[in] iVar - Variable index.
355382
* \param[in] val_Stress - Value of the stress added.
356383
*/
357-
inline void Add_NodalStress(unsigned short iNode, unsigned short iVar, su2double val_Stress) {
384+
inline void Add_NodalStress(unsigned short iNode, unsigned short iVar, const su2double& val_Stress) {
358385
NodalStress(iNode, iVar) += val_Stress;
359386
}
360387

@@ -789,7 +816,7 @@ class CQUAD4 final : public CElementWithKnownSizes<4, 4, 2> {
789816
/*!
790817
* \brief Shape functions (Ni) evaluated at point Xi,Eta.
791818
*/
792-
inline static void ShapeFunctions(su2double Xi, su2double Eta, su2double* Ni) {
819+
inline static void ShapeFunctions(const su2double& Xi, const su2double& Eta, su2double* Ni) {
793820
Ni[0] = 0.25 * (1.0 - Xi) * (1.0 - Eta);
794821
Ni[1] = 0.25 * (1.0 + Xi) * (1.0 - Eta);
795822
Ni[2] = 0.25 * (1.0 + Xi) * (1.0 + Eta);
@@ -799,7 +826,7 @@ class CQUAD4 final : public CElementWithKnownSizes<4, 4, 2> {
799826
/*!
800827
* \brief Shape function Jacobian (dNi) evaluated at point Xi,Eta.
801828
*/
802-
inline static void ShapeFunctionJacobian(su2double Xi, su2double Eta, su2double dNi[][2]) {
829+
inline static void ShapeFunctionJacobian(const su2double& Xi, const su2double& Eta, su2double dNi[][2]) {
803830
dNi[0][0] = -0.25 * (1.0 - Eta);
804831
dNi[0][1] = -0.25 * (1.0 - Xi);
805832
dNi[1][0] = 0.25 * (1.0 - Eta);

Common/src/CConfig.cpp

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -914,7 +914,10 @@ void CConfig::SetPointersNull() {
914914
Inlet_Velocity = nullptr; Inflow_Mach = nullptr; Inflow_Pressure = nullptr;
915915
Outlet_Pressure = nullptr; Isothermal_Temperature = nullptr;
916916

917-
ElasticityMod = nullptr; PoissonRatio = nullptr; MaterialDensity = nullptr;
917+
ElasticityMod = nullptr;
918+
PoissonRatio = nullptr;
919+
MaterialDensity = nullptr;
920+
MaterialThermalExpansion = nullptr;
918921

919922
Load_Dir = nullptr; Load_Dir_Value = nullptr; Load_Dir_Multiplier = nullptr;
920923
Disp_Dir = nullptr; Disp_Dir_Value = nullptr; Disp_Dir_Multiplier = nullptr;
@@ -2440,6 +2443,10 @@ void CConfig::SetConfig_Options() {
24402443
addDoubleListOption("POISSON_RATIO", nPoissonRatio, PoissonRatio);
24412444
/* DESCRIPTION: Material density */
24422445
addDoubleListOption("MATERIAL_DENSITY", nMaterialDensity, MaterialDensity);
2446+
/* DESCRIPTION: Material thermal expansion coefficient */
2447+
addDoubleListOption("MATERIAL_THERMAL_EXPANSION_COEFF", nMaterialThermalExpansion, MaterialThermalExpansion);
2448+
/* DESCRIPTION: Temperature at which there is no stress from thermal expansion */
2449+
addDoubleOption("MATERIAL_REFERENCE_TEMPERATURE", MaterialReferenceTemperature, 288.15);
24432450
/* DESCRIPTION: Knowles B constant */
24442451
addDoubleOption("KNOWLES_B", Knowles_B, 1.0);
24452452
/* DESCRIPTION: Knowles N constant */
@@ -4834,9 +4841,15 @@ void CConfig::SetPostprocessing(SU2_COMPONENT val_software, unsigned short val_i
48344841
MaterialDensity = new su2double[1]; MaterialDensity[0] = 7854;
48354842
}
48364843

4837-
if (nElasticityMod != nPoissonRatio || nElasticityMod != nMaterialDensity) {
4838-
SU2_MPI::Error("ELASTICITY_MODULUS, POISSON_RATIO, and MATERIAL_DENSITY need to have the same number "
4839-
"of entries (the number of materials).", CURRENT_FUNCTION);
4844+
if (nMaterialThermalExpansion == 0) {
4845+
nMaterialThermalExpansion = 1;
4846+
MaterialThermalExpansion = new su2double[1]();
4847+
}
4848+
4849+
if (nElasticityMod != nPoissonRatio || nElasticityMod != nMaterialDensity ||
4850+
nElasticityMod != nMaterialThermalExpansion) {
4851+
SU2_MPI::Error("ELASTICITY_MODULUS, POISSON_RATIO, MATERIAL_DENSITY, and THERMAL_EXPANSION_COEFF need "
4852+
"to have the same number of entries (the number of materials).", CURRENT_FUNCTION);
48404853
}
48414854

48424855
if (nElectric_Constant == 0) {

Common/src/geometry/elements/CElement.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,8 @@ CElement::CElement(unsigned short ngauss, unsigned short nnodes, unsigned short
4747

4848
NodalStress.resize(nNodes, 6) = su2double(0.0);
4949

50+
NodalTemperature.resize(nNodes) = su2double(0.0);
51+
5052
Mab.resize(nNodes, nNodes);
5153
Ks_ab.resize(nNodes, nNodes);
5254
Kab.resize(nNodes);

Common/src/geometry/elements/CQUAD4.cpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,6 @@ CQUAD4::CQUAD4() : CElementWithKnownSizes<NGAUSS, NNODE, NDIM>() {
6767
/*--- Store the extrapolation functions (used to compute nodal stresses) ---*/
6868

6969
su2double ExtrapCoord[4][2], sqrt3 = 1.732050807568877;
70-
;
7170

7271
ExtrapCoord[0][0] = -sqrt3;
7372
ExtrapCoord[0][1] = -sqrt3;

SU2_CFD/include/numerics/elasticity/CFEAElasticity.hpp

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -54,15 +54,20 @@ class CFEAElasticity : public CNumerics {
5454
su2double Nu = 0.0; /*!< \brief Aux. variable, Poisson's ratio. */
5555
su2double Rho_s = 0.0; /*!< \brief Aux. variable, Structural density. */
5656
su2double Rho_s_DL = 0.0; /*!< \brief Aux. variable, Structural density (for dead loads). */
57+
su2double Alpha = 0.0; /*!< \brief Aux. variable, thermal expansion coefficient. */
5758

5859
su2double Mu = 0.0; /*!< \brief Aux. variable, Lame's coeficient. */
5960
su2double Lambda = 0.0; /*!< \brief Aux. variable, Lame's coeficient. */
6061
su2double Kappa = 0.0; /*!< \brief Aux. variable, Compressibility constant. */
62+
su2double ThermalStressTerm = 0.0; /*!< \brief Aux. variable, Relationship between stress and delta T. */
6163

6264
su2double *E_i = nullptr; /*!< \brief Young's modulus of elasticity. */
6365
su2double *Nu_i = nullptr; /*!< \brief Poisson's ratio. */
6466
su2double *Rho_s_i = nullptr; /*!< \brief Structural density. */
6567
su2double *Rho_s_DL_i = nullptr; /*!< \brief Structural density (for dead loads). */
68+
su2double *Alpha_i = nullptr; /*!< \brief Thermal expansion coefficient. */
69+
70+
su2double ReferenceTemperature = 0.0; /*!< \brief Reference temperature for thermal expansion. */
6671

6772
su2double **Ba_Mat = nullptr; /*!< \brief Matrix B for node a - Auxiliary. */
6873
su2double **Bb_Mat = nullptr; /*!< \brief Matrix B for node b - Auxiliary. */
@@ -72,8 +77,6 @@ class CFEAElasticity : public CNumerics {
7277
su2double **GradNi_Ref_Mat = nullptr; /*!< \brief Gradients of Ni - Auxiliary. */
7378
su2double **GradNi_Curr_Mat = nullptr; /*!< \brief Gradients of Ni - Auxiliary. */
7479

75-
su2double *FAux_Dead_Load = nullptr; /*!< \brief Auxiliar vector for the dead loads */
76-
7780
su2double *DV_Val = nullptr; /*!< \brief For optimization cases, value of the design variables. */
7881
unsigned short n_DV = 0; /*!< \brief For optimization cases, number of design variables. */
7982

@@ -230,6 +233,8 @@ class CFEAElasticity : public CNumerics {
230233
Mu = E / (2.0*(1.0 + Nu));
231234
Lambda = Nu*E/((1.0+Nu)*(1.0-2.0*Nu));
232235
Kappa = Lambda + (2/3)*Mu;
236+
/*--- https://solidmechanics.org/Text/Chapter3_2/Chapter3_2.php ---*/
237+
ThermalStressTerm = -Alpha * E / (1 - (plane_stress ? 1 : 2) * Nu);
233238
}
234239

235240
/*!
@@ -238,8 +243,8 @@ class CFEAElasticity : public CNumerics {
238243
* \param[in] jVar - Index j.
239244
* \return 1 if i=j, 0 otherwise.
240245
*/
241-
inline static su2double deltaij(unsigned short iVar, unsigned short jVar) {
242-
return su2double(iVar==jVar);
246+
inline static passivedouble deltaij(unsigned short iVar, unsigned short jVar) {
247+
return static_cast<passivedouble>(iVar == jVar);
243248
}
244249

245250
};

SU2_CFD/include/numerics/elasticity/CFEANonlinearElasticity.hpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -141,8 +141,9 @@ class CFEANonlinearElasticity : public CFEAElasticity {
141141
* \brief Compute the stress tensor.
142142
* \param[in,out] element_container - The finite element.
143143
* \param[in] config - Definition of the problem.
144+
* \param[in] iGauss - Index of Gaussian integration point.
144145
*/
145-
virtual void Compute_Stress_Tensor(CElement *element_container, const CConfig *config) = 0;
146+
virtual void Compute_Stress_Tensor(CElement *element_container, const CConfig *config, unsigned short iGauss) = 0;
146147

147148
/*!
148149
* \brief Update an element with Maxwell's stress.

SU2_CFD/include/numerics/elasticity/nonlinear_models.hpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ class CFEM_NeoHookean_Comp final : public CFEANonlinearElasticity {
7373
* \param[in,out] element_container - The finite element.
7474
* \param[in] config - Definition of the problem.
7575
*/
76-
void Compute_Stress_Tensor(CElement *element_container, const CConfig *config) override;
76+
void Compute_Stress_Tensor(CElement *element_container, const CConfig *config, unsigned short iGauss) override;
7777

7878
};
7979

@@ -124,7 +124,7 @@ class CFEM_Knowles_NearInc final : public CFEANonlinearElasticity {
124124
* \param[in,out] element_container - The finite element.
125125
* \param[in] config - Definition of the problem.
126126
*/
127-
void Compute_Stress_Tensor(CElement *element_container, const CConfig *config) override;
127+
void Compute_Stress_Tensor(CElement *element_container, const CConfig *config, unsigned short iGauss) override;
128128

129129
};
130130

@@ -172,7 +172,7 @@ class CFEM_DielectricElastomer final : public CFEANonlinearElasticity {
172172
* \param[in,out] element_container - The finite element.
173173
* \param[in] config - Definition of the problem.
174174
*/
175-
void Compute_Stress_Tensor(CElement *element_container, const CConfig *config) override;
175+
void Compute_Stress_Tensor(CElement *element_container, const CConfig *config, unsigned short iGauss) override;
176176

177177
};
178178

@@ -222,6 +222,6 @@ class CFEM_IdealDE final : public CFEANonlinearElasticity {
222222
* \param[in,out] element_container - The finite element.
223223
* \param[in] config - Definition of the problem.
224224
*/
225-
void Compute_Stress_Tensor(CElement *element_container, const CConfig *config) override;
225+
void Compute_Stress_Tensor(CElement *element_container, const CConfig *config, unsigned short iGauss) override;
226226

227227
};

0 commit comments

Comments
 (0)