Skip to content

Commit ceb7c90

Browse files
vishhwamehtaA-CGraykanekosh
authored
Composite material model and Tsai-Wu failure criterion; introduce safety_factor (#444)
* initial commit for tsaiwu wingbox package * Make geometry spline interpolation mesh independent * formatting changes * implemented "useComposite" in the surfdict for the option of using composite materials and made changes to all the relevant scripts along with the calculation of effective stiffness values for composite materials * changed the surface dictionary in the test files to work with the new keys * Made the changes with if statements of "useComposite", bug fixes with numofplies and num_failure_criteria, added raise commands for surf dict * cleaning all the codes, removing unnecessary comments and updating the group descriptions for the failure groups and tsaiwuwingbox * bug fixes due to the hardcoded 4 plies * Modify surface dictionary checks * Rename surface dict variables to follow OAS conventions * Undo artifact from previous merge * Fix error message * correcting the spatial_beam_functionals * `black -l 120 .` * `black -l 120 .` * Fix docstring in failure_ks * fixing the files flagged for pull request tests * removing the call for shwoing n2, and fixing formatting bug * removing the asert.near.equal import statement from test file * failure files and check_surface_dict modified to use "safety_factor". All test files using yield/SF modified to have a safety_factor key * removed unused import statements, adding option for the cases where safety factor is absent * creating and editing the documentation files for OAS documentation * updating heirarchy for the documentation files * Add code excerpt to composites doc page * documemtation for composite wingbox * updated the documentation page * changed the safety factor documentation and added the Pareto front to the walkthrough page * Simplifying some code in failure_ks * small docs fix * variable renaming * More robust if check * Check against lower case strings * move functions to structure.utils * remove unused var * update integration tests * rename test file * moved effective E and G computation to runscript level to be more general * documentation update * moved example script from docs folder to example folder * updated example script * fixed stiffness matrix transformation and added unit test * fixed strain transformation in tsai-wu comp and refactoring * working on Gray2024 benchmark model * updated benchmark example * ruff * docs minor update * docs update * docs minor fixes * update tsaiwu test * format * typos in docs * fixed safety_factor and removed debugging leftovers * Alter composite transformations --------- Co-authored-by: Alasdair Gray <alachris@umich.edu> Co-authored-by: kanekosh <shugok@umich.edu>
1 parent 33685eb commit ceb7c90

60 files changed

Lines changed: 1893 additions & 129 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

openaerostruct/docs/advanced_features.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,3 +22,4 @@ These examples show some advanced features in OpenAeroStruct.
2222
advanced_features/customizing_prob_setup.rst
2323
advanced_features/mphys_coupling.rst
2424
advanced_features/stability_derivatives.rst
25+
advanced_features/composites_walkthrough.rst
Lines changed: 196 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,196 @@
1+
.. _Composites Walkthrough:
2+
3+
Composite Material
4+
==================
5+
6+
This page will walk you through the composites model in OpenAeroStruct.
7+
The composites module allows you to define composite material properties and laminate layups for the wing structure.
8+
9+
Model setup
10+
-----------
11+
12+
First, define the following parameters in the `surface` dictionary:
13+
14+
- ``useComposite`` is a boolean variable that is set to True to enable the composites model mode.
15+
- ``safety_factor`` is the factor of safety used for determining the Tsai-Wu based failure
16+
- ``ply_angles`` is a list of the angles of the plies with respect to the x-axis.
17+
- ``ply_fractions`` is a list of the ply fractions of the plies. (Should be the same length as ``ply_angles``, with the sum of the fractions equal to 1).
18+
- ``E1`` is the modulus of elasticity in the fiber direction.
19+
- ``E2`` is the modulus of elasticity in the transverse direction.
20+
- ``G12`` is the shear modulus.
21+
- ``nu12`` is the Poisson's ratio.
22+
- ``sigma_t1`` is the tensile strength in the fiber direction.
23+
- ``sigma_c1`` is the compressive strength in the fiber direction.
24+
- ``sigma_t2`` is the tensile strength in the transverse direction.
25+
- ``sigma_c2`` is the compressive strength in the transverse direction.
26+
- ``sigma_12max`` is the maximum shear strength.
27+
28+
.. note::
29+
The composites failure model doesn't use the ``strength_factor_for_upper_skin`` option from the surface dictionary.
30+
If you want to apply a knockdown factor on the compressive strength to account for buckling, you should scale down the values of ``sigma_c1`` and ``sigma_c2``.
31+
32+
Next, call a utility function to compute the effective E and G for the composite material.
33+
The following function adds ``E`` and ``G`` to ``surface``.
34+
35+
.. code-block:: python
36+
37+
from openaerostruct.structures.utils import compute_composite_stiffness
38+
compute_composite_stiffness(surf_dict)
39+
40+
The rest of the model setup is the same as aluminum wing aerostructural problems.
41+
OpenAeroStruct will compute the failure metric based on the Tsai-Wu failure criterion instead of the von Mises failure criterion when we set ``useComposite`` to True.
42+
But this is done automatically within ``AerostructPoint``, so you don't need to do anything about it.
43+
44+
Theory
45+
------
46+
47+
Approximation of the Moduli of Elasticity
48+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
49+
50+
Currently, the moduli of elasticity of the entire FEM spatial beam model are assumed to be isotropic
51+
in 2D plane so as to not change the entire model and is left for the future works.
52+
The values of the moduli of elasticity are found using the following procedure.
53+
54+
The unidirectional ply properties are used to find the stiffness matrix of the plies:
55+
56+
.. math::
57+
58+
Q = \begin{bmatrix}
59+
\frac{E_1}{1-\nu_{12}\nu_{21}} & \frac{\nu_{21}E_2}{1-\nu_{12}\nu_{21}} & 0 \\
60+
\frac{\nu_{12}E_1}{1-\nu_{12}\nu_{21}} & \frac{E_2}{1-\nu_{12}\nu_{21}} & 0 \\
61+
0 & 0 & G_{12}
62+
\end{bmatrix}
63+
64+
where :math:`E_1` and :math:`E_2` are the moduli of elasticity in the fiber direction and transverse direction, respectively,
65+
:math:`\nu_{12}` and :math:`\nu_{21}` are the Poisson's ratios, and :math:`G_{12}` is the shear modulus.
66+
67+
We then transform the stiffness matrix of each ply as a function of the ply angle by
68+
69+
.. math::
70+
71+
\bar{Q} = T_\sigma Q T_\varepsilon^{-1}
72+
73+
where :math:`T_\sigma`, :math:`T_\varepsilon` are the stress and strain transformation matrices, respectively.
74+
75+
The effective stiffness matrix for the laminate is found using the weighted sum of the stiffness matrices of the plies,
76+
using their respective ply fraction:
77+
78+
.. math::
79+
80+
Q_{eff} = \sum_{i=1}^{n} f_i \bar{Q}_i
81+
82+
where :math:`f_i` is the ply fraction of the :math:`i^{th}` ply.
83+
84+
The effective compliance matrix is found using the following equation:
85+
86+
.. math::
87+
88+
S_{eff} = Q_{eff}^{-1}
89+
90+
The effective laminate properties are found using the following equations:
91+
92+
.. math::
93+
E = \frac{1}{S_{eff_{11}}}\\
94+
G = \frac{1}{S_{eff_{66}}}
95+
96+
These moduli of elasticity values are hence used to determine the stiffness matrix of the entire FEM spatial beam model.
97+
98+
Tsai-Wu Failure Criterion
99+
~~~~~~~~~~~~~~~~~~~~~~~~~
100+
101+
Thereafter, at the 4 critical points in the wingbox (mentioned in the aerostruct-wingbox walkthrough),
102+
the strains are calculated for each of the constituent plies by transforming the strains at the critical points to the laminate coordinate system. This is done using the following equation:
103+
104+
.. math::
105+
106+
\begin{pmatrix}
107+
\epsilon_1 \\
108+
\epsilon_2 \\
109+
\gamma_{12}
110+
\end{pmatrix}
111+
=
112+
[T_\varepsilon]
113+
\begin{pmatrix}
114+
\epsilon_x \\
115+
\epsilon_y \\
116+
\gamma_{xy}
117+
\end{pmatrix}
118+
119+
The strains are then used to calculate the stresses in the laminate using the following equation:
120+
121+
.. math::
122+
123+
\begin{pmatrix}
124+
\sigma_1 \\
125+
\sigma_2 \\
126+
\tau_{12}
127+
\end{pmatrix}
128+
=
129+
[Q]
130+
\begin{pmatrix}
131+
\epsilon_1 \\
132+
\epsilon_2 \\
133+
\gamma_{12}
134+
\end{pmatrix}
135+
136+
These local axial and shear stresses are then utilized to calculate the value of the **Strength Ratios**, where the coefficients are defined by:
137+
138+
.. math::
139+
140+
F_{11} = \frac{1}{S_L^{(+)} S_L^{(-)}} \quad \text{and} \quad F_1 = \frac{1}{S_L^{(+)}} - \frac{1}{S_L^{(-)}}
141+
142+
.. math::
143+
144+
F_{22} = \frac{1}{S_T^{(+)} S_T^{(-)}} \quad \text{and} \quad F_2 = \frac{1}{S_T^{(+)}} - \frac{1}{S_T^{(-)}}
145+
146+
.. math::
147+
148+
F_{66} = \frac{1}{2 S_{LT}^{2}}
149+
150+
where :math:`S_L^{(+)} \text{and} S_L^{(-)}` are the longitudinal strengths in tension and compression respectively,
151+
:math:`S_T^{(+)} \text{and} S_T^{(-)}` are the transverse strengths in tension and compression respectively and
152+
:math:`S_{LT}^{(+)}` is the shear strength of a ply. The strength ratios are then used to calculate the Tsai-Wu based failure criterion for each ply.
153+
The Tsai-Wu failure criterion is given by:
154+
155+
.. math::
156+
157+
F_1 \sigma_1 + F_2 \sigma_2 + F_{11} \sigma_1^2 + F_{22} \sigma_2^2 + F_{66} \tau_{12}^2 = 1
158+
159+
In order to implement the safety factor in the Tsai-Wu failure criterion, the equation is re-written as:
160+
161+
.. math::
162+
a &= F_1 \sigma_1 + F_2 \sigma_2 \\
163+
b &= F_{11} \sigma_1^2 + F_{22} \sigma_2^2 + F_{12} \sigma_1 \sigma_2
164+
165+
We hence calculate the **Strength Ratios** using the formula:
166+
167+
.. math::
168+
169+
SR = \frac{1}{2} (a + \sqrt{a^2 + 4 b})
170+
171+
The strength ratio values hence calculated for each ply (determined by the length of ``ply_angles``) at each critical point (4 total),
172+
(hence 4 x ``numplies`` strength ratio values for each beam element) for all beam elements are aggregated using a **KS Aggregate** function:
173+
174+
.. math::
175+
176+
\hat{g}_{KS}(\rho, g) = \max_j g_j + \frac{1}{\rho} \ln \left( \sum_{j=1}^{n_g} \exp \left( \rho (g_j - \max_j g_j) \right) \right)
177+
178+
179+
where :math:`g` is :math:`\left( \frac{SR}{SR_{\text{lim}}} - 1 \right)` value for each ply and :math:`SR_{\text{lim}}` is defined as:
180+
181+
.. math::
182+
183+
SR_{\text{lim}} = \frac{1}{\text{safety factor}}
184+
185+
186+
The failure is determined by the value of :math:`\hat{g}_{KS}(\rho, g)` exceeding 0.
187+
188+
189+
Example runscript
190+
-----------------
191+
192+
Here is an example runscript of composite wing aerostructural optimization.
193+
This roughly follows the setup of "Simple Transonic Wing" by `Gray and Martins 2024 <https://www.researchgate.net/publication/377154425_A_Proposed_Benchmark_Model_for_Practical_Aeroelastic_Optimization_of_Aircraft_Wings>`_.
194+
195+
.. embed-code::
196+
../examples/run_aerostruct_composite_benchmark_wing.py

openaerostruct/docs/advanced_features/scripts/two_part_wing_custom_mesh.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,8 @@
160160
# Structural values are based on aluminum 7075
161161
"E": 73.1e9, # [Pa] Young's modulus
162162
"G": (73.1e9 / 2 / 1.33), # [Pa] shear modulus (calculated using E and the Poisson's ratio here)
163-
"yield": (420.0e6 / 1.5), # [Pa] allowable yield stress
163+
"yield": 420.0e6, # [Pa] yield stress
164+
"safety_factor": 1.5, # safety factor
164165
"mrho": 2.78e3, # [kg/m^3] material density
165166
"strength_factor_for_upper_skin": 1.0, # the yield stress is multiplied by this factor for the upper skin
166167
"wing_weight_ratio": 1.25,

openaerostruct/docs/advanced_features/scripts/wingbox_mpt_Q400_example.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,8 @@
9393
# Structural values are based on aluminum 7075
9494
"E": 73.1e9, # [Pa] Young's modulus
9595
"G": (73.1e9 / 2 / 1.33), # [Pa] shear modulus (calculated using E and the Poisson's ratio here)
96-
"yield": (420.0e6 / 1.5), # [Pa] allowable yield stress
96+
"yield": 420.0e6, # [Pa] yield stress
97+
"safety_factor": 1.5, # safety factor
9798
"mrho": 2.78e3, # [kg/m^3] material density
9899
"strength_factor_for_upper_skin": 1.0, # the yield stress is multiplied by this factor for the upper skin
99100
"wing_weight_ratio": 1.25,

openaerostruct/docs/aerostructural_wingbox_walkthrough.rst

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -100,10 +100,10 @@ The `c_max_t` value is the location of the maximum thickness of the airfoil alon
100100
:end-before: checkpoint 6
101101

102102
Next we provide some information related to structures.
103-
We provide the Young's and shear moduli, as well as the allowable yield stress and density of the material being used (the wingbox model currently assumes that the material is isotropic).
104-
Here we use include a safety factor of 1.5 in the allowable yield stress.
103+
We provide the Young's and shear moduli, as well as the maximum yield stress and density of the material being used. The material can either be assumed to be isotropic (like aluminum) or orthotropic (like carbon fiber reinforced polymer).
104+
Here we use include a safety factor of 1.5 using the `safety_factor` key.
105105
The `strength_factor_for_upper_skin` value can be used to adjust the yield strength of the upper skin relative to the lower skin.
106-
For example, if we were using different alloys for the top and bottom skin (e.g., Al7075 vs Al2024) we would provide the allowable yield stress of the lower skin for `yield` and the ratio of the yield strengths of the upper skin to the lower skin for `strength_factor_for_upper_skin`.
106+
For example, if we were using different alloys for the top and bottom skin (e.g., Al7075 vs Al2024) we would provide the maximum yield stress of the lower skin for `yield` and the ratio of the yield strengths of the upper skin to the lower skin for `strength_factor_for_upper_skin`.
107107
The `wing_weight_ratio` number is used to estimate the weight of other components not modeled in the wingbox structure (e.g., overlaps, fasteners, etc.).
108108
With the `exact_failure_constraint` set to `False`, we aggregate the stress constraints for the FEM elements into a single constraint using the Kreisselmeier--Steinhauser function.
109109
This helps reduce computational cost during optimization by replacing a large number of constraints (one for each stress combination for each element) with a single constraint.

openaerostruct/docs/user_reference/mesh_surface_dict.rst

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -243,9 +243,13 @@ The surface dict will be provided to Groups, including ``Geometry``, ``AeroPoint
243243
- Pa
244244
- Shear modulus
245245
* - yield
246-
- 420.0e6 / 1.5
246+
- 420.0e6
247247
- Pa
248-
- Allowable yield stress including the safety factor.
248+
- Maximum yield stress of the material.
249+
* - safety_factor
250+
- 1.5
251+
-
252+
- Factor of safety for the material.
249253
* - mrho
250254
- 2.78e3
251255
- kg/m^3

openaerostruct/docs/wingbox_mpt_opt_example.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,8 @@
7676
# Structural values are based on aluminum 7075
7777
"E": 73.1e9, # [Pa] Young's modulus
7878
"G": (73.1e9 / 2 / 1.33), # [Pa] shear modulus (calculated using E and the Poisson's ratio here)
79-
"yield": (420.0e6 / 1.5), # [Pa] allowable yield stress
79+
"yield": 420.0e6, # [Pa] yield stress
80+
"safety_factor": 1.5, # safety factor
8081
"mrho": 2.78e3, # [kg/m^3] material density
8182
"strength_factor_for_upper_skin": 1.0, # the yield stress is multiplied by this factor for the upper skin
8283
"wing_weight_ratio": 1.25,

openaerostruct/examples/black_box_example.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,8 @@
5252
# Structural values are based on aluminum 7075
5353
"E": 70.0e9, # [Pa] Young's modulus of the spar
5454
"G": 30.0e9, # [Pa] shear modulus of the spar
55-
"yield": 500.0e6 / 2.5, # [Pa] yield stress divided by 2.5 for limiting case
55+
"yield": 500.0e6,
56+
"safety_factor": 2.5, # [Pa] yield stress divided by 2.5 for limiting case
5657
"mrho": 3.0e3, # [kg/m^3] material density
5758
"fem_origin": 0.35, # normalized chordwise location of the spar
5859
"wing_weight_ratio": 2.0,

openaerostruct/examples/run_CRM.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,8 @@
4242
# Structural values are based on aluminum 7075
4343
"E": 70.0e9, # [Pa] Young's modulus of the spar
4444
"G": 30.0e9, # [Pa] shear modulus of the spar
45-
"yield": 500.0e6 / 2.5, # [Pa] yield stress divided by 2.5 for limiting case
45+
"yield": 500.0e6,
46+
"safety_factor": 2.5, # [Pa] yield stress divided by 2.5 for limiting case
4647
"mrho": 3.0e3, # [kg/m^3] material density
4748
"fem_origin": 0.35, # normalized chordwise location of the spar
4849
"wing_weight_ratio": 2.0,

0 commit comments

Comments
 (0)