Skip to content

Commit db6e087

Browse files
Fix 2D von Mises formula and thermal expansion for nonlinear material in plane stress (#2667)
* FIX: Correct 2D Von Mises formula in CFEAElasticity (#2603) * FIX: Implement Plane Strain Von Mises formulation with Poisson ratio * Update SU2_CFD/include/numerics/elasticity/CFEAElasticity.hpp Co-authored-by: Pedro Gomes <38071223+pcarruscag@users.noreply.github.com> * Update SU2_CFD/include/numerics/elasticity/CFEAElasticity.hpp Co-authored-by: Pedro Gomes <38071223+pcarruscag@users.noreply.github.com> * FIX: Compute and store Szz for Plane Strain in 2D linear elasticity * DOCS: Add contributor to AUTHORS.md * REF: Decouple physics from VonMisesStress utility * CHORE: Revert accidental submodule updates * CHORE: Sync opdi with develop branch * fixes for 2D VMS and nonlinear plane stress with thermal expansion * update regressions * update --------- Co-authored-by: Ayush <ayushssp74@gmail.com>
1 parent deb80aa commit db6e087

20 files changed

Lines changed: 250 additions & 145 deletions

AUTHORS.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ Aniket C. Aranake
5656
Antonio Rubino
5757
Arne Bachmann
5858
Arne Voß
59+
Ayush Kumar
5960
Beckett Y. Zhou
6061
Benjamin S. Kirk
6162
Brendan Tracey

Common/src/linear_algebra/CSysSolve.cpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -626,14 +626,15 @@ unsigned long CSysSolve<ScalarType>::RFGMRES_LinSolver(const CSysVector<ScalarTy
626626
}
627627
END_SU2_OMP_SAFE_GLOBAL_ACCESS
628628

629-
for (auto totalIter = 0ul; totalIter < MaxIter;) {
629+
auto totalIter = 0ul;
630+
while (totalIter < MaxIter) {
630631
/*--- Enforce a hard limit on total number of iterations ---*/
631632
auto iterLimit = min(restartIter, MaxIter - totalIter);
632633
auto iter = FGMRES_LinSolver(b, x, mat_vec, precond, tol, iterLimit, residual, monitoring, config);
633634
totalIter += iter;
634-
if (residual <= tol || iter < iterLimit) return totalIter;
635+
if (residual <= tol || iter < iterLimit) break;
635636
}
636-
return 0;
637+
return totalIter;
637638
}
638639

639640
template <class ScalarType>

SU2_CFD/include/numerics/elasticity/CFEAElasticity.hpp

Lines changed: 20 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,8 @@ class CFEAElasticity : public CNumerics {
8080
su2double *DV_Val = nullptr; /*!< \brief For optimization cases, value of the design variables. */
8181
unsigned short n_DV = 0; /*!< \brief For optimization cases, number of design variables. */
8282

83-
bool plane_stress = false; /*!< \brief Checks if we are solving a plane stress case */
83+
bool plane_stress = false; /*!< \brief Checks if we are solving a plane stress case. */
84+
bool linear = false; /*!< \brief Checks if we are solving a linear elasticity case. */
8485

8586
public:
8687
/*!
@@ -181,28 +182,21 @@ class CFEAElasticity : public CNumerics {
181182

182183
/*!
183184
* \brief Compute VonMises stress from components Sxx Syy Sxy Szz Sxz Syz.
185+
* \note Szz is required in 2D whereas Sxz and Syz are assumed to be 0.
184186
*/
185-
template<class T>
187+
template <class T>
186188
static su2double VonMisesStress(unsigned short nDim, const T& stress) {
187-
if (nDim == 2) {
188-
su2double Sxx = stress[0], Syy = stress[1], Sxy = stress[2];
189-
190-
su2double S1, S2; S1 = S2 = (Sxx+Syy)/2;
191-
su2double tauMax = sqrt(pow((Sxx-Syy)/2, 2) + pow(Sxy,2));
192-
S1 += tauMax;
193-
S2 -= tauMax;
194-
195-
return sqrt(S1*S1+S2*S2-2*S1*S2);
196-
}
197-
else {
198-
su2double Sxx = stress[0], Syy = stress[1], Szz = stress[3];
199-
su2double Sxy = stress[2], Sxz = stress[4], Syz = stress[5];
200-
201-
return sqrt(0.5*(pow(Sxx - Syy, 2) +
202-
pow(Syy - Szz, 2) +
203-
pow(Szz - Sxx, 2) +
204-
6.0*(Sxy*Sxy+Sxz*Sxz+Syz*Syz)));
189+
/*--- In 2D, we only have 4 components: Sxx, Syy, Sxy, Szz. ---*/
190+
const auto& Sxx = stress[0];
191+
const auto& Syy = stress[1];
192+
const auto& Sxy = stress[2];
193+
const auto& Szz = stress[3];
194+
su2double Sxz = 0, Syz = 0;
195+
if (nDim == 3) {
196+
Sxz = stress[4];
197+
Syz = stress[5];
205198
}
199+
return sqrt(0.5 * (pow(Sxx - Syy, 2) + pow(Syy - Szz, 2) + pow(Szz - Sxx, 2) + 6 * (Sxy * Sxy + Sxz * Sxz + Syz * Syz)));
206200
}
207201

208202
protected:
@@ -233,8 +227,12 @@ class CFEAElasticity : public CNumerics {
233227
Mu = E / (2.0*(1.0 + Nu));
234228
Lambda = Nu*E/((1.0+Nu)*(1.0-2.0*Nu));
235229
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);
230+
/*--- https://solidmechanics.org/Text/Chapter3_2/Chapter3_2.php
231+
* The stress tensor for nonlinear problems is still 3x3 and plane stress is imposed
232+
* by determining the deformation that makes sigma_33 = 0, hence this denominator is
233+
* only changed for linear elasticity. ---*/
234+
const auto nu_mult = (linear && plane_stress) ? 1 : 2;
235+
ThermalStressTerm = -Alpha * E / (1 - nu_mult * Nu);
238236
}
239237

240238
/*!

SU2_CFD/include/numerics/elasticity/CFEANonlinearElasticity.hpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -134,8 +134,9 @@ class CFEANonlinearElasticity : public CFEAElasticity {
134134
* \brief Compute the plane stress term.
135135
* \param[in,out] element_container - The finite element.
136136
* \param[in] config - Definition of the problem.
137+
* \param[in] iGauss - Index of Gaussian integration point.
137138
*/
138-
virtual void Compute_Plane_Stress_Term(CElement *element_container, const CConfig *config) = 0;
139+
virtual void Compute_Plane_Stress_Term(CElement *element_container, const CConfig *config, unsigned short iGauss) = 0;
139140

140141
/*!
141142
* \brief Compute the stress tensor.

SU2_CFD/include/numerics/elasticity/nonlinear_models.hpp

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -58,8 +58,9 @@ class CFEM_NeoHookean_Comp final : public CFEANonlinearElasticity {
5858
* \brief Compute the plane stress term.
5959
* \param[in,out] element_container - The finite element.
6060
* \param[in] config - Definition of the problem.
61+
* \param[in] iGauss - Index of Gaussian integration point.
6162
*/
62-
void Compute_Plane_Stress_Term(CElement *element_container, const CConfig *config) override;
63+
void Compute_Plane_Stress_Term(CElement *element_container, const CConfig *config, unsigned short iGauss) override;
6364

6465
/*!
6566
* \brief Compute the constitutive matrix.
@@ -72,9 +73,9 @@ class CFEM_NeoHookean_Comp final : public CFEANonlinearElasticity {
7273
* \brief Compute the stress tensor.
7374
* \param[in,out] element_container - The finite element.
7475
* \param[in] config - Definition of the problem.
76+
* \param[in] iGauss - Index of Gaussian integration point.
7577
*/
7678
void Compute_Stress_Tensor(CElement *element_container, const CConfig *config, unsigned short iGauss) override;
77-
7879
};
7980

8081

@@ -109,8 +110,9 @@ class CFEM_Knowles_NearInc final : public CFEANonlinearElasticity {
109110
* \brief Compute the plane stress term.
110111
* \param[in,out] element_container - The finite element.
111112
* \param[in] config - Definition of the problem.
113+
* \param[in] iGauss - Index of Gaussian integration point.
112114
*/
113-
void Compute_Plane_Stress_Term(CElement *element_container, const CConfig *config) override;
115+
void Compute_Plane_Stress_Term(CElement *element_container, const CConfig *config, unsigned short iGauss) override;
114116

115117
/*!
116118
* \brief Compute the constitutive matrix.
@@ -123,6 +125,7 @@ class CFEM_Knowles_NearInc final : public CFEANonlinearElasticity {
123125
* \brief Compute the stress tensor.
124126
* \param[in,out] element_container - The finite element.
125127
* \param[in] config - Definition of the problem.
128+
* \param[in] iGauss - Index of Gaussian integration point.
126129
*/
127130
void Compute_Stress_Tensor(CElement *element_container, const CConfig *config, unsigned short iGauss) override;
128131

@@ -157,8 +160,9 @@ class CFEM_DielectricElastomer final : public CFEANonlinearElasticity {
157160
* \brief Compute the plane stress term.
158161
* \param[in,out] element_container - The finite element.
159162
* \param[in] config - Definition of the problem.
163+
* \param[in] iGauss - Index of Gaussian integration point.
160164
*/
161-
inline void Compute_Plane_Stress_Term(CElement *element_container, const CConfig *config) override { };
165+
inline void Compute_Plane_Stress_Term(CElement *element_container, const CConfig *config, unsigned short iGauss) override { };
162166

163167
/*!
164168
* \brief Compute the constitutive matrix.
@@ -171,6 +175,7 @@ class CFEM_DielectricElastomer final : public CFEANonlinearElasticity {
171175
* \brief Compute the stress tensor.
172176
* \param[in,out] element_container - The finite element.
173177
* \param[in] config - Definition of the problem.
178+
* \param[in] iGauss - Index of Gaussian integration point.
174179
*/
175180
void Compute_Stress_Tensor(CElement *element_container, const CConfig *config, unsigned short iGauss) override;
176181

@@ -207,8 +212,9 @@ class CFEM_IdealDE final : public CFEANonlinearElasticity {
207212
* \brief Compute the plane stress term.
208213
* \param[in,out] element_container - The finite element.
209214
* \param[in] config - Definition of the problem.
215+
* \param[in] iGauss - Index of Gaussian integration point.
210216
*/
211-
void Compute_Plane_Stress_Term(CElement *element_container, const CConfig *config) override;
217+
void Compute_Plane_Stress_Term(CElement *element_container, const CConfig *config, unsigned short iGauss) override;
212218

213219
/*!
214220
* \brief Compute the constitutive matrix.
@@ -221,6 +227,7 @@ class CFEM_IdealDE final : public CFEANonlinearElasticity {
221227
* \brief Compute the stress tensor.
222228
* \param[in,out] element_container - The finite element.
223229
* \param[in] config - Definition of the problem.
230+
* \param[in] iGauss - Index of Gaussian integration point.
224231
*/
225232
void Compute_Stress_Tensor(CElement *element_container, const CConfig *config, unsigned short iGauss) override;
226233

SU2_CFD/src/numerics/elasticity/CFEAElasticity.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -64,9 +64,10 @@ CFEAElasticity::CFEAElasticity(unsigned short val_nDim, unsigned short val_nVar,
6464
Alpha = Alpha_i[0];
6565
ReferenceTemperature = config->GetMaterialReferenceTemperature();
6666

67-
Compute_Lame_Parameters();
68-
6967
plane_stress = (nDim == 2) && (config->GetElas2D_Formulation() == STRUCT_2DFORM::PLANE_STRESS);
68+
linear = config->GetGeometricConditions() == STRUCT_DEFORMATION::SMALL;
69+
70+
Compute_Lame_Parameters();
7071

7172
KAux_ab = new su2double* [nDim];
7273
for (iVar = 0; iVar < nDim; iVar++) {

SU2_CFD/src/numerics/elasticity/CFEALinearElasticity.cpp

Lines changed: 19 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -206,26 +206,18 @@ void CFEALinearElasticity::Compute_Constitutive_Matrix(CElement *element_contain
206206

207207
/*--- Compute the D Matrix (for plane stress and 2-D)---*/
208208

209-
210209
if (nDim == 2) {
211210
if (plane_stress) {
212-
/*--- We enable plane stress cases ---*/
213-
214-
D_Mat[0][0] = E/(1-Nu*Nu); D_Mat[0][1] = (E*Nu)/(1-Nu*Nu); D_Mat[0][2] = 0.0;
215-
D_Mat[1][0] = (E*Nu)/(1-Nu*Nu); D_Mat[1][1] = E/(1-Nu*Nu); D_Mat[1][2] = 0.0;
216-
D_Mat[2][0] = 0.0; D_Mat[2][1] = 0.0; D_Mat[2][2] = ((1-Nu)*E)/(2*(1-Nu*Nu));
217-
}
218-
else {
219-
/*--- Assuming plane strain as a general case ---*/
220-
211+
su2double D = E / (1 - Nu * Nu);
212+
D_Mat[0][0] = D; D_Mat[0][1] = Nu * D; D_Mat[0][2] = 0.0;
213+
D_Mat[1][0] = Nu * D; D_Mat[1][1] = D; D_Mat[1][2] = 0.0;
214+
D_Mat[2][0] = 0.0; D_Mat[2][1] = 0.0; D_Mat[2][2] = (1 - Nu) * D / 2;
215+
} else {
221216
D_Mat[0][0] = Lambda + 2.0*Mu; D_Mat[0][1] = Lambda; D_Mat[0][2] = 0.0;
222217
D_Mat[1][0] = Lambda; D_Mat[1][1] = Lambda + 2.0*Mu; D_Mat[1][2] = 0.0;
223218
D_Mat[2][0] = 0.0; D_Mat[2][1] = 0.0; D_Mat[2][2] = Mu;
224219
}
225-
226-
}
227-
else {
228-
220+
} else {
229221
su2double Lbda_2Mu = Lambda + 2.0*Mu;
230222

231223
D_Mat[0][0] = Lbda_2Mu; D_Mat[0][1] = Lambda; D_Mat[0][2] = Lambda; D_Mat[0][3] = 0.0; D_Mat[0][4] = 0.0; D_Mat[0][5] = 0.0;
@@ -234,7 +226,6 @@ void CFEALinearElasticity::Compute_Constitutive_Matrix(CElement *element_contain
234226
D_Mat[3][0] = 0.0; D_Mat[3][1] = 0.0; D_Mat[3][2] = 0.0; D_Mat[3][3] = Mu; D_Mat[3][4] = 0.0; D_Mat[3][5] = 0.0;
235227
D_Mat[4][0] = 0.0; D_Mat[4][1] = 0.0; D_Mat[4][2] = 0.0; D_Mat[4][3] = 0.0; D_Mat[4][4] = Mu; D_Mat[4][5] = 0.0;
236228
D_Mat[5][0] = 0.0; D_Mat[5][1] = 0.0; D_Mat[5][2] = 0.0; D_Mat[5][3] = 0.0; D_Mat[5][4] = 0.0; D_Mat[5][5] = Mu;
237-
238229
}
239230

240231
}
@@ -336,30 +327,27 @@ su2double CFEALinearElasticity::Compute_Averaged_NodalStress(CElement *element,
336327
avgStress[iVar] += Stress[iVar] / nGauss;
337328
}
338329

339-
for (iNode = 0; iNode < nNode; iNode++) {
330+
if (nDim == 2 && config->GetElas2D_Formulation() == STRUCT_2DFORM::PLANE_STRAIN) {
331+
Stress[3] = Nu * (Stress[0] + Stress[1]) + (1 - 2 * Nu) * thermalStress;
332+
avgStress[3] += Stress[3] / nGauss;
333+
}
340334

341-
su2double Ni_Extrap = element->GetNi_Extrap(iNode, iGauss);
335+
/*--- If nDim is 3 and we compute it this way, the 3rd component is the Szz,
336+
* while in the output it is the 4th component for practical reasons. ---*/
337+
if (nDim == 3) std::swap(Stress[2], Stress[3]);
342338

343-
if (nDim == 2) {
344-
for(iVar = 0; iVar < 3; ++iVar)
345-
element->Add_NodalStress(iNode, iVar, Stress[iVar] * Ni_Extrap);
346-
}
347-
else {
348-
/*--- If nDim is 3 and we compute it this way, the 3rd component is the Szz,
349-
* while in the output it is the 4th component for practical reasons. ---*/
350-
element->Add_NodalStress(iNode, 0, Stress[0] * Ni_Extrap);
351-
element->Add_NodalStress(iNode, 1, Stress[1] * Ni_Extrap);
352-
element->Add_NodalStress(iNode, 2, Stress[3] * Ni_Extrap);
353-
element->Add_NodalStress(iNode, 3, Stress[2] * Ni_Extrap);
354-
element->Add_NodalStress(iNode, 4, Stress[4] * Ni_Extrap);
355-
element->Add_NodalStress(iNode, 5, Stress[5] * Ni_Extrap);
339+
for (iNode = 0; iNode < nNode; iNode++) {
340+
su2double Ni_Extrap = element->GetNi_Extrap(iNode, iGauss);
341+
for (iVar = 0; iVar < DIM_STRAIN_3D; ++iVar) {
342+
element->Add_NodalStress(iNode, iVar, Stress[iVar] * Ni_Extrap);
356343
}
357344
}
358345

359346
}
360347

348+
/*--- See note regarding output order above. ---*/
361349
if (nDim == 3) std::swap(avgStress[2], avgStress[3]);
362-
auto elStress = VonMisesStress(nDim, avgStress);
350+
auto elStress = CFEAElasticity::VonMisesStress(nDim, avgStress);
363351

364352
/*--- We only differentiate w.r.t. an avg VM stress for the element as
365353
* considering all nodal stresses would use too much memory. ---*/

SU2_CFD/src/numerics/elasticity/CFEANonlinearElasticity.cpp

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -320,7 +320,7 @@ void CFEANonlinearElasticity::Compute_Tangent_Matrix(CElement *element, const CC
320320
if (nDim == 2) {
321321
if (plane_stress) {
322322
// Compute the value of the term 33 for the deformation gradient
323-
Compute_Plane_Stress_Term(element, config);
323+
Compute_Plane_Stress_Term(element, config, iGauss);
324324
F_Mat[2][2] = f33;
325325
}
326326
else { // plane strain
@@ -542,7 +542,7 @@ void CFEANonlinearElasticity::Compute_NodalStress_Term(CElement *element, const
542542
if (nDim == 2) {
543543
if (plane_stress) {
544544
// Compute the value of the term 33 for the deformation gradient
545-
Compute_Plane_Stress_Term(element, config);
545+
Compute_Plane_Stress_Term(element, config, iGauss);
546546
F_Mat[2][2] = f33;
547547
}
548548
else { // plane strain
@@ -821,10 +821,10 @@ su2double CFEANonlinearElasticity::Compute_Averaged_NodalStress(CElement *elemen
821821
if (nDim == 2) {
822822
if (plane_stress) {
823823
// Compute the value of the term 33 for the deformation gradient
824-
Compute_Plane_Stress_Term(element, config);
824+
Compute_Plane_Stress_Term(element, config, iGauss);
825825
F_Mat[2][2] = f33;
826-
}
827-
else { // plane strain
826+
} else {
827+
// Plane strain
828828
F_Mat[2][2] = 1.0;
829829
}
830830
}
@@ -856,8 +856,8 @@ su2double CFEANonlinearElasticity::Compute_Averaged_NodalStress(CElement *elemen
856856
avgStress[0] += Stress_Tensor[0][0] / nGauss;
857857
avgStress[1] += Stress_Tensor[1][1] / nGauss;
858858
avgStress[2] += Stress_Tensor[0][1] / nGauss;
859+
avgStress[3] += Stress_Tensor[2][2] / nGauss;
859860
if (nDim == 3) {
860-
avgStress[3] += Stress_Tensor[2][2] / nGauss;
861861
avgStress[4] += Stress_Tensor[0][2] / nGauss;
862862
avgStress[5] += Stress_Tensor[1][2] / nGauss;
863863
}
@@ -883,8 +883,8 @@ su2double CFEANonlinearElasticity::Compute_Averaged_NodalStress(CElement *elemen
883883
element->Add_NodalStress(iNode, 0, Stress_Tensor[0][0] * Ni_Extrap);
884884
element->Add_NodalStress(iNode, 1, Stress_Tensor[1][1] * Ni_Extrap);
885885
element->Add_NodalStress(iNode, 2, Stress_Tensor[0][1] * Ni_Extrap);
886+
element->Add_NodalStress(iNode, 3, Stress_Tensor[2][2] * Ni_Extrap);
886887
if (nDim == 3) {
887-
element->Add_NodalStress(iNode, 3, Stress_Tensor[2][2] * Ni_Extrap);
888888
element->Add_NodalStress(iNode, 4, Stress_Tensor[0][2] * Ni_Extrap);
889889
element->Add_NodalStress(iNode, 5, Stress_Tensor[1][2] * Ni_Extrap);
890890
}
@@ -893,7 +893,7 @@ su2double CFEANonlinearElasticity::Compute_Averaged_NodalStress(CElement *elemen
893893

894894
}
895895

896-
auto elStress = VonMisesStress(nDim, avgStress);
896+
auto elStress = CFEAElasticity::VonMisesStress(nDim, avgStress);
897897

898898
/*--- We only differentiate w.r.t. an avg VM stress for the element as
899899
* considering all nodal stresses would use too much memory. ---*/

0 commit comments

Comments
 (0)