Skip to content

Commit 1a8dee4

Browse files
Use singleton as source of constants and allow to add custom materials
Signed-off-by: Johannes Mueller <[email protected]>
1 parent 484ff18 commit 1a8dee4

File tree

6 files changed

+190
-183
lines changed

6 files changed

+190
-183
lines changed

docs/strength/fkm_nonlinear.rst

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,4 @@ The ``fkm_nonlinear`` functions
33

44
.. autofunction:: pylife.strength.fkm_nonlinear.assessment_nonlinear_standard.perform_fkm_nonlinear_assessment
55

6-
.. autofunction:: pylife.strength.fkm_nonlinear.constants.for_material_group
6+
.. class:: pylife.strength.fkm_nonlinear.FKMNLConstants

src/pylife/strength/damage_parameter.py

+3-2
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
import pylife.strength.fkm_nonlinear
2525
import pylife.materiallaws.rambgood
2626
import pylife.strength.woehler_fkm_nonlinear
27+
from pylife.strength.fkm_nonlinear.constants import FKMNLConstants
2728

2829
class P_RAM:
2930
"""This class implements the damage parameter P_RAM according to guideline FKM nonlinear.
@@ -58,7 +59,7 @@ def __init__(self, collective, assessment_parameters):
5859
self._assessment_parameters = assessment_parameters
5960

6061
# select set of constants according to given material group
61-
self._constants = pylife.strength.fkm_nonlinear.constants.for_material_group(assessment_parameters)
62+
self._constants = FKMNLConstants().for_material_group(assessment_parameters)
6263

6364
# check if collective contains required columns
6465
assert "S_a" in self._collective.columns
@@ -150,7 +151,7 @@ def __init__(self, collective, assessment_parameters, component_woehler_curve_P_
150151
self._P_RAJ_D_0 = self._component_woehler_curve_P_RAJ.fatigue_strength_limit
151152

152153
# select set of constants according to given material group
153-
self._constants = pylife.strength.fkm_nonlinear.constants.for_material_group(assessment_parameters)
154+
self._constants = FKMNLConstants().for_material_group(assessment_parameters)
154155

155156
# check if collective contains required columns
156157
assert "S_a" in self._collective.columns

src/pylife/strength/fkm_nonlinear/constants.py

+165-146
Original file line numberDiff line numberDiff line change
@@ -20,149 +20,168 @@
2020
import numpy as np
2121
import pandas as pd
2222

23-
"""Constants for various formulas used in the FKM nonlinear procedure."""
24-
all_constants = pd.DataFrame({
25-
"Steel": {
26-
# general values and values for P_RAM
27-
"E": 206e3, # table 2.7 (2.16)
28-
"n_prime": 0.187, # table 2.8 (2.17)
29-
"a_sigma": 3.1148,
30-
"a_epsilon": 1033,
31-
"b_sigma": 0.897,
32-
"b_epsilon": -1.235,
33-
"epsilon_grenz": 0.338,
34-
"f_25percent_damage_woehler": 0.86, # table 2.9
35-
"a_PZ_RAM": 20.0, # table 2.10 (2.18), note that values for P_RAJ are different
36-
"b_PZ_RAM": 0.587,
37-
"a_PD_RAM": 0.82,
38-
"b_PD_RAM": 0.92,
39-
"d_1": -0.302,
40-
"d_2": -0.197,
41-
"f_25percent_material_woehler_FKM_nonlinear_RAM": 0.71, # table 2.18
42-
"f_25percent_material_woehler_FKM_roughness_RAM": 0.73, # table 35 in report "Rauheit und Randschicht 2022"
43-
"k_st": 30, # table 2.11 (2.19)
44-
"a_RP": 0.27, # table 2.12 (2.20)
45-
"b_RP": 0.43,
46-
"R_m_N_min": 400,
47-
"a_M": 0.35, # table 2.14 (2.22)
48-
"b_M": -0.1,
49-
"R_m_bm": 680, # eq. (2.5-33)
50-
51-
# values for P_RAJ
52-
"d_RAJ": -0.63, # table 2.33 (2.41) Note, this is -0.56 in the FKM nonlinear document, however due to an error by the authors, the value was corrected later (e-mail of Moritz Hupka 15.09.22 10:27)
53-
"f_25percent_material_woehler_FKM_nonlinear_RAJ": 0.39, # This value is listed as 0.39, table 2.33 in FKM nonlinear 2019, and as 0.35 in table 35 in report "Rauheit und Randschicht 2022".
54-
"f_25percent_material_woehler_FKM_roughness_RAJ": 0.25, # table 35 in report "Rauheit und Randschicht 2022"
55-
"a_PZ_RAJ": 10, # Note, this is 1.173 in the FKM nonlinear document, however due to an error by the authors, the value was corrected later (e-mail of Moritz Hupka 15.09.22 10:27)
56-
"b_PZ_RAJ": 0.826, # Note, this is 1 in the FKM nonlinear document, however due to an error by the authors, the value was corrected later (e-mail of Moritz Hupka 15.09.22 10:27)
57-
"a_PD_RAJ": 3.33e-5,
58-
"b_PD_RAJ": 1.55,
59-
},
60-
"SteelCast": {
61-
# general values and values for P_RAM
62-
"E": 206e3, # table 2.7 (2.16)
63-
"n_prime": 0.176, # table 2.8 (2.17)
64-
"a_sigma": 1.732,
65-
"a_epsilon": 0.847,
66-
"b_sigma": 0.982,
67-
"b_epsilon": -0.181,
68-
"epsilon_grenz": np.inf,
69-
"f_25percent_damage_woehler": 0.68, # table 2.9
70-
"a_PZ_RAM": 25.56, # table 2.10 (2.18), note that values for P_RAJ are different
71-
"b_PZ_RAM": 0.519,
72-
"a_PD_RAM": 0.46,
73-
"b_PD_RAM": 0.96,
74-
"d_1": -0.289,
75-
"d_2": -0.189,
76-
"f_25percent_material_woehler_FKM_nonlinear_RAM": 0.51,
77-
"k_st": 15, # table 2.11 (2.19)
78-
"a_RP": 0.25, # table 2.12 (2.20)
79-
"b_RP": 0.42,
80-
"R_m_N_min": 400,
81-
"a_M": 0.35, # table 2.14 (2.22)
82-
"b_M": 0.05,
83-
"R_m_bm": 680, # eq. (2.5-33)
84-
85-
# values for P_RAJ
86-
"d_RAJ": -0.66, # table 2.33 (2.41)
87-
"f_25percent_material_woehler_FKM_nonlinear_RAJ": 0.40,
88-
"a_PZ_RAJ": 10.03,
89-
"b_PZ_RAJ": 0.695,
90-
"a_PD_RAJ": 5.15e-6,
91-
"b_PD_RAJ": 1.63,
92-
},
93-
"Al_wrought": {
94-
# general values and values for P_RAM
95-
"E": 70e3, # table 2.7 (2.16)
96-
"n_prime": 0.128, # table 2.8 (2.17)
97-
"a_sigma": 9.12,
98-
"a_epsilon": 895.9,
99-
"b_sigma": 0.742,
100-
"b_epsilon": -1.183,
101-
"epsilon_grenz": np.inf,
102-
"f_25percent_damage_woehler": 0.88, # table 2.9
103-
"a_PZ_RAM": 16.71, # table 2.10 (2.18), note that values for P_RAJ are different
104-
"b_PZ_RAM": 0.537,
105-
"a_PD_RAM": 0.30,
106-
"b_PD_RAM": 1.00,
107-
"d_1": -0.238,
108-
"d_2": -0.167,
109-
"f_25percent_material_woehler_FKM_nonlinear_RAM": 0.61,
110-
"k_st": 20, # table 2.11 (2.19)
111-
"a_RP": 0.27, # table 2.12 (2.20)
112-
"b_RP": 0.43,
113-
"R_m_N_min": 133,
114-
"a_M": 1.0, # table 2.14 (2.22)
115-
"b_M": -0.04,
116-
"R_m_bm": 270, # eq. (2.5-33)
117-
118-
# values for P_RAJ
119-
"d_RAJ": -0.61, # table 2.33 (2.41)
120-
"f_25percent_material_woehler_FKM_nonlinear_RAJ": 0.36,
121-
"a_PZ_RAJ": 101.7,
122-
"b_PZ_RAJ": 0.26,
123-
"a_PD_RAJ": 5.18e-7,
124-
"b_PD_RAJ": 2.04,
125-
}
126-
})
127-
128-
129-
def for_material_group(assessment_parameters):
130-
"""
131-
Retrieve the constants for one of the three material groups that are defined in FKM nonlinear.
132-
133-
.. note::
134-
135-
The constants for all material groups can be accessed as
136-
``pylife.strength.fkm_nonlinear.constants.all_constants``.
137-
138-
Parameters
139-
----------
140-
assessment_parameters : pandas Series
141-
A Series with at least the item ``MatGroupFKM``, which has to be one of
142-
``Steel``, ``SteelCast``, ``Al_wrought``.
143-
144-
Returns
145-
-------
146-
pandas Series
147-
All constants that are defined by FKM nonlinear for the given material group.
148-
149-
"""
150-
# call user hook to modify constants if necessary
151-
global all_constants
152-
if "user_hook" in assessment_parameters:
153-
all_constants = assessment_parameters["user_hook"](all_constants)
154-
155-
# select set of constants according to given material group
156-
assert "MatGroupFKM" in assessment_parameters
157-
158-
material_group = assessment_parameters["MatGroupFKM"]
159-
160-
resulting_constants = all_constants[material_group]
161-
162-
# Rename the key for the safety factor f_25%
163-
resulting_constants["f_25percent_material_woehler_RAM"] \
164-
= resulting_constants["f_25percent_material_woehler_FKM_nonlinear_RAM"]
165-
resulting_constants["f_25percent_material_woehler_RAJ"] \
166-
= resulting_constants["f_25percent_material_woehler_FKM_nonlinear_RAJ"]
167-
168-
return resulting_constants
23+
24+
class FKMNLConstants:
25+
_instance = None
26+
27+
def __new__(cls):
28+
if cls._instance is None:
29+
cls._instance = super(FKMNLConstants, cls).__new__(cls)
30+
cls._instance._initialize()
31+
return cls._instance
32+
33+
def _initialize(self):
34+
"""Constants for various formulas used in the FKM nonlinear procedure."""
35+
self._all_constants = pd.DataFrame({
36+
"Steel": {
37+
# general values and values for P_RAM
38+
"E": 206e3, # table 2.7 (2.16)
39+
"n_prime": 0.187, # table 2.8 (2.17)
40+
"a_sigma": 3.1148,
41+
"a_epsilon": 1033,
42+
"b_sigma": 0.897,
43+
"b_epsilon": -1.235,
44+
"epsilon_grenz": 0.338,
45+
"f_25percent_damage_woehler": 0.86, # table 2.9
46+
"a_PZ_RAM": 20.0, # table 2.10 (2.18), note that values for P_RAJ are different
47+
"b_PZ_RAM": 0.587,
48+
"a_PD_RAM": 0.82,
49+
"b_PD_RAM": 0.92,
50+
"d_1": -0.302,
51+
"d_2": -0.197,
52+
"f_25percent_material_woehler_FKM_nonlinear_RAM": 0.71, # table 2.18
53+
"f_25percent_material_woehler_FKM_roughness_RAM": 0.73, # table 35 in report "Rauheit und Randschicht 2022"
54+
"k_st": 30, # table 2.11 (2.19)
55+
"a_RP": 0.27, # table 2.12 (2.20)
56+
"b_RP": 0.43,
57+
"R_m_N_min": 400,
58+
"a_M": 0.35, # table 2.14 (2.22)
59+
"b_M": -0.1,
60+
"R_m_bm": 680, # eq. (2.5-33)
61+
62+
# values for P_RAJ
63+
"d_RAJ": -0.63, # table 2.33 (2.41) Note, this is -0.56 in the FKM nonlinear document, however due to an error by the authors, the value was corrected later (e-mail of Moritz Hupka 15.09.22 10:27)
64+
"f_25percent_material_woehler_FKM_nonlinear_RAJ": 0.39, # This value is listed as 0.39, table 2.33 in FKM nonlinear 2019, and as 0.35 in table 35 in report "Rauheit und Randschicht 2022".
65+
"f_25percent_material_woehler_FKM_roughness_RAJ": 0.25, # table 35 in report "Rauheit und Randschicht 2022"
66+
"a_PZ_RAJ": 10, # Note, this is 1.173 in the FKM nonlinear document, however due to an error by the authors, the value was corrected later (e-mail of Moritz Hupka 15.09.22 10:27)
67+
"b_PZ_RAJ": 0.826, # Note, this is 1 in the FKM nonlinear document, however due to an error by the authors, the value was corrected later (e-mail of Moritz Hupka 15.09.22 10:27)
68+
"a_PD_RAJ": 3.33e-5,
69+
"b_PD_RAJ": 1.55,
70+
},
71+
"SteelCast": {
72+
# general values and values for P_RAM
73+
"E": 206e3, # table 2.7 (2.16)
74+
"n_prime": 0.176, # table 2.8 (2.17)
75+
"a_sigma": 1.732,
76+
"a_epsilon": 0.847,
77+
"b_sigma": 0.982,
78+
"b_epsilon": -0.181,
79+
"epsilon_grenz": np.inf,
80+
"f_25percent_damage_woehler": 0.68, # table 2.9
81+
"a_PZ_RAM": 25.56, # table 2.10 (2.18), note that values for P_RAJ are different
82+
"b_PZ_RAM": 0.519,
83+
"a_PD_RAM": 0.46,
84+
"b_PD_RAM": 0.96,
85+
"d_1": -0.289,
86+
"d_2": -0.189,
87+
"f_25percent_material_woehler_FKM_nonlinear_RAM": 0.51,
88+
"k_st": 15, # table 2.11 (2.19)
89+
"a_RP": 0.25, # table 2.12 (2.20)
90+
"b_RP": 0.42,
91+
"R_m_N_min": 400,
92+
"a_M": 0.35, # table 2.14 (2.22)
93+
"b_M": 0.05,
94+
"R_m_bm": 680, # eq. (2.5-33)
95+
96+
# values for P_RAJ
97+
"d_RAJ": -0.66, # table 2.33 (2.41)
98+
"f_25percent_material_woehler_FKM_nonlinear_RAJ": 0.40,
99+
"a_PZ_RAJ": 10.03,
100+
"b_PZ_RAJ": 0.695,
101+
"a_PD_RAJ": 5.15e-6,
102+
"b_PD_RAJ": 1.63,
103+
},
104+
"Al_wrought": {
105+
# general values and values for P_RAM
106+
"E": 70e3, # table 2.7 (2.16)
107+
"n_prime": 0.128, # table 2.8 (2.17)
108+
"a_sigma": 9.12,
109+
"a_epsilon": 895.9,
110+
"b_sigma": 0.742,
111+
"b_epsilon": -1.183,
112+
"epsilon_grenz": np.inf,
113+
"f_25percent_damage_woehler": 0.88, # table 2.9
114+
"a_PZ_RAM": 16.71, # table 2.10 (2.18), note that values for P_RAJ are different
115+
"b_PZ_RAM": 0.537,
116+
"a_PD_RAM": 0.30,
117+
"b_PD_RAM": 1.00,
118+
"d_1": -0.238,
119+
"d_2": -0.167,
120+
"f_25percent_material_woehler_FKM_nonlinear_RAM": 0.61,
121+
"k_st": 20, # table 2.11 (2.19)
122+
"a_RP": 0.27, # table 2.12 (2.20)
123+
"b_RP": 0.43,
124+
"R_m_N_min": 133,
125+
"a_M": 1.0, # table 2.14 (2.22)
126+
"b_M": -0.04,
127+
"R_m_bm": 270, # eq. (2.5-33)
128+
129+
# values for P_RAJ
130+
"d_RAJ": -0.61, # table 2.33 (2.41)
131+
"f_25percent_material_woehler_FKM_nonlinear_RAJ": 0.36,
132+
"a_PZ_RAJ": 101.7,
133+
"b_PZ_RAJ": 0.26,
134+
"a_PD_RAJ": 5.18e-7,
135+
"b_PD_RAJ": 2.04,
136+
}
137+
})
138+
139+
def for_material_group(self, assessment_parameters):
140+
"""
141+
Retrieve the constants for one of the three material groups that are defined in FKM nonlinear.
142+
143+
.. note::
144+
145+
The constants for all material groups can be accessed as
146+
``pylife.strength.fkm_nonlinear.constants.all_constants``.
147+
148+
Parameters
149+
----------
150+
assessment_parameters : pandas Series
151+
A Series with at least the item ``MatGroupFKM``, which has to be one of
152+
``Steel``, ``SteelCast``, ``Al_wrought``.
153+
154+
Returns
155+
-------
156+
pandas Series
157+
All constants that are defined by FKM nonlinear for the given material group.
158+
159+
"""
160+
# select set of constants according to given material group
161+
assert "MatGroupFKM" in assessment_parameters
162+
163+
material_group = assessment_parameters["MatGroupFKM"]
164+
165+
resulting_constants = self._all_constants[material_group]
166+
167+
# Rename the key for the safety factor f_25%
168+
resulting_constants["f_25percent_material_woehler_RAM"] \
169+
= resulting_constants["f_25percent_material_woehler_FKM_nonlinear_RAM"]
170+
resulting_constants["f_25percent_material_woehler_RAJ"] \
171+
= resulting_constants["f_25percent_material_woehler_FKM_nonlinear_RAJ"]
172+
173+
return resulting_constants
174+
175+
def add_custom_material(self, material_group_nme, material_constants):
176+
self._all_constants[material_group_nme] = pd.Series(material_constants)
177+
return self
178+
179+
def __iter__(self):
180+
for mg in self._all_constants:
181+
yield mg
182+
183+
def __getitem__(self, material_group_name):
184+
return self._all_constants[material_group_name].copy()
185+
186+
def to_pandas(self):
187+
return self._all_constants.copy()

src/pylife/strength/fkm_nonlinear/damage_calculator.py

+3-2
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424

2525
import pylife.strength.woehler_fkm_nonlinear
2626
import pylife.strength.fkm_nonlinear.parameter_calculations
27+
from pylife.strength.fkm_nonlinear.constants import FKMNLConstants
2728

2829
class DamageCalculatorPRAM:
2930
"""This class performs the lifetime assessment according to the FKM nonlinear assessment.
@@ -189,7 +190,7 @@ def get_lifetime_functions(self, assessment_parameters):
189190
python function, ``failure_probability(N)``
190191
"""
191192

192-
constants = pylife.strength.fkm_nonlinear.constants.for_material_group(assessment_parameters)
193+
constants = FKMNLConstants().for_material_group(assessment_parameters)
193194

194195
f_25 = constants.f_25percent_material_woehler_RAM
195196

@@ -449,7 +450,7 @@ def get_lifetime_functions(self):
449450
python function, ``failure_probability(N)``
450451
"""
451452

452-
constants = pylife.strength.fkm_nonlinear.constants.for_material_group(self._assessment_parameters)
453+
constants = FKMNLConstants().for_material_group(self._assessment_parameters)
453454
f_25 = constants.f_25percent_material_woehler_RAJ
454455
slope_woehler = abs(1/self._component_woehler_curve_P_RAJ.d)
455456
lifetime_n_cycles = self.lifetime_n_cycles

0 commit comments

Comments
 (0)