Skip to content

Commit

Permalink
Use automatic binning of FKMNonLinearDetector
Browse files Browse the repository at this point in the history
Signed-off-by: Johannes Mueller <[email protected]>
  • Loading branch information
johannes-mueller committed Dec 13, 2024
1 parent 190e491 commit 603a28f
Show file tree
Hide file tree
Showing 3 changed files with 17 additions and 55 deletions.
11 changes: 6 additions & 5 deletions src/pylife/materiallaws/notch_approximation_law_seegerbeste.py
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ def stress(self, load, *, rtol=1e-4, tol=1e-4):
The resulting stress
'''
# initial value as given by correction document to FKM nonlinear
x0 = load * (1 - (1 - 1/self._K_p)/1000)
x0 = np.asarray(load * (1 - (1 - 1/self._K_p)/1000))

# suppress the divergence warnings
with warnings.catch_warnings():
Expand All @@ -96,7 +96,8 @@ def stress(self, load, *, rtol=1e-4, tol=1e-4):
# or (value, converged, zero_der) for vector-valued invocation

# only for multiple points at once, if some points diverged
if len(stress) == 3 and not stress[1].all():
multidim = len(x0.shape) > 1 and x0.shape[1] > 1
if multidim and not stress[1].all():
stress = self._stress_fix_not_converged_values(stress, load, x0, rtol, tol)

return stress[0]
Expand Down Expand Up @@ -461,7 +462,7 @@ def _stress_fix_not_converged_values(self, stress, load, x0, rtol, tol):
'''For the values that did not converge in the previous vectorized call to optimize.newton,
call optimize.newton again on the scalar value. This usually finds the correct solution.'''

indices_diverged = [index for index, is_converged in enumerate(stress[1]) if not is_converged]
indices_diverged = np.where(~stress[1].all(axis=1))[0]
x0_array = np.asarray(x0)
load_array = np.asarray(load)

Expand All @@ -471,13 +472,13 @@ def _stress_fix_not_converged_values(self, stress, load, x0, rtol, tol):
load_diverged = load_array[index_diverged]
result = optimize.newton(
func=self._stress_implicit,
x0=x0_diverged,
x0=np.asarray(x0_diverged),
args=([load_diverged]),
full_output=True,
rtol=rtol, tol=tol, maxiter=50
)

if result[1].converged:
if result.converged.all():
stress[0][index_diverged] = result[0]
return stress

Expand Down
24 changes: 7 additions & 17 deletions src/pylife/strength/fkm_nonlinear/assessment_nonlinear_standard.py
Original file line number Diff line number Diff line change
Expand Up @@ -389,27 +389,21 @@ def _compute_component_woehler_curves(assessment_parameters):
return assessment_parameters, component_woehler_curve_P_RAM, component_woehler_curve_P_RAJ


def _compute_hcm_RAM(assessment_parameters, scaled_load_sequence, maximum_absolute_load):
def _compute_hcm_RAM(assessment_parameters, scaled_load_sequence, maximum_absolute_):
"""Perform the HCM rainflow counting with the extended Neuber notch approximation.
The HCM algorithm is executed twice, as described in the FKM nonlinear guideline."""

# initialize notch approximation law
E, K_prime, n_prime, K_p = assessment_parameters[["E", "K_prime", "n_prime", "K_p"]]
extended_neuber = pylife.materiallaws.notch_approximation_law.ExtendedNeuber(E, K_prime, n_prime, K_p)

# wrap the notch approximation law by a binning class, which precomputes the values
extended_neuber_binned = (
pylife.materiallaws.notch_approximation_law.NotchApproxBinner(
extended_neuber
).initialize(maximum_absolute_load)
)

# create recorder object
recorder = pylife.stress.rainflow.recorders.FKMNonlinearRecorder()

# create detector object
detector = pylife.stress.rainflow.fkm_nonlinear.FKMNonlinearDetector(
recorder=recorder, notch_approximation_law=extended_neuber_binned, binner=None)
recorder=recorder, notch_approximation_law=extended_neuber
)

# perform HCM algorithm, first run
detector.process_hcm_first(scaled_load_sequence)
Expand All @@ -418,7 +412,7 @@ def _compute_hcm_RAM(assessment_parameters, scaled_load_sequence, maximum_absolu
# perform HCM algorithm, second run
detector.process_hcm_second(scaled_load_sequence)

return detector_1st, detector, extended_neuber_binned, recorder
return detector_1st, detector, extended_neuber, recorder


def _compute_damage_and_lifetimes_RAM(assessment_parameters, recorder, component_woehler_curve_P_RAM, result):
Expand Down Expand Up @@ -493,17 +487,13 @@ def _compute_hcm_RAJ(assessment_parameters, scaled_load_sequence, maximum_absolu
E, K_prime, n_prime, K_p = assessment_parameters[["E", "K_prime", "n_prime", "K_p"]]
seeger_beste = pylife.materiallaws.notch_approximation_law_seegerbeste.SeegerBeste(E, K_prime, n_prime, K_p)

# wrap the notch approximation law by a binning class, which precomputes the values
seeger_beste_binned = pylife.materiallaws.notch_approximation_law.NotchApproxBinner(
seeger_beste
).initialize(maximum_absolute_load)

# create recorder object
recorder = pylife.stress.rainflow.recorders.FKMNonlinearRecorder()

# create detector object
detector = pylife.stress.rainflow.fkm_nonlinear.FKMNonlinearDetector(
recorder=recorder, notch_approximation_law=seeger_beste_binned, binner=None)
recorder=recorder, notch_approximation_law=seeger_beste
)
detector_1st = copy.deepcopy(detector)

# perform HCM algorithm, first run
Expand All @@ -512,7 +502,7 @@ def _compute_hcm_RAJ(assessment_parameters, scaled_load_sequence, maximum_absolu
# perform HCM algorithm, second run
detector.process_hcm_second(scaled_load_sequence)

return detector_1st, detector, seeger_beste_binned, recorder
return detector_1st, detector, seeger_beste, recorder


def _compute_damage_and_lifetimes_RAJ(assessment_parameters, recorder, component_woehler_curve_P_RAJ, result):
Expand Down
37 changes: 4 additions & 33 deletions tests/strength/test_damage_calculator.py
Original file line number Diff line number Diff line change
Expand Up @@ -92,20 +92,12 @@ def test_woehler_curve_P_RAM_collective_has_no_index():

load_sequence_list = pd.Series([143.696, -287.392, 143.696, -359.240, 287.392, 0.000, 287.392, -287.392])

# wrap the notch approximation law by a binning class, which precomputes the values
maximum_absolute_load = max(np.abs(load_sequence_list))
extended_neuber_binned = (
pylife.materiallaws.notch_approximation_law.NotchApproxBinner(
extended_neuber
).initialize(maximum_absolute_load)
)

# create recorder object
recorder = pylife.stress.rainflow.recorders.FKMNonlinearRecorder()

# create detector object
detector = pylife.stress.rainflow.fkm_nonlinear.FKMNonlinearDetector(
recorder=recorder, notch_approximation_law=extended_neuber_binned, binner=None
recorder=recorder, notch_approximation_law=extended_neuber
)

# perform HCM algorithm, first run
Expand Down Expand Up @@ -202,20 +194,12 @@ def test_woehler_curve_P_RAM_collective_has_MultiIndex():

load_sequence_list = pd.Series([143.696, -287.392, 143.696, -359.240, 287.392, 0.000, 287.392, -287.392])

# wrap the notch approximation law by a binning class, which precomputes the values
maximum_absolute_load = max(np.abs(load_sequence_list))
extended_neuber_binned = (
pylife.materiallaws.notch_approximation_law.NotchApproxBinner(
extended_neuber
).initialize(maximum_absolute_load)
)

# create recorder object
recorder = pylife.stress.rainflow.recorders.FKMNonlinearRecorder()

# create detector object
detector = pylife.stress.rainflow.fkm_nonlinear.FKMNonlinearDetector(
recorder=recorder, notch_approximation_law=extended_neuber_binned, binner=None
recorder=recorder, notch_approximation_law=extended_neuber
)

# perform HCM algorithm, first run
Expand Down Expand Up @@ -300,19 +284,12 @@ def test_woehler_curve_P_RAJ_has_no_index():
seeger_beste = pylife.materiallaws.notch_approximation_law_seegerbeste.SeegerBeste(E, K_prime, n_prime, K_p)

load_sequence_list = pd.Series([143.696, -287.392, 143.696, -359.240, 287.392, 0.000, 287.392, -287.392])

# wrap the notch approximation law by a binning class, which precomputes the values
maximum_absolute_load = max(np.abs(load_sequence_list))
seeger_beste_binned = pylife.materiallaws.notch_approximation_law.NotchApproxBinner(
seeger_beste
).initialize(maximum_absolute_load)

# create recorder object
recorder = pylife.stress.rainflow.recorders.FKMNonlinearRecorder()

# create detector object
detector = pylife.stress.rainflow.fkm_nonlinear.FKMNonlinearDetector(
recorder=recorder, notch_approximation_law=seeger_beste_binned, binner=None
recorder=recorder, notch_approximation_law=seeger_beste
)

# perform HCM algorithm, first run
Expand Down Expand Up @@ -410,18 +387,12 @@ def test_woehler_curve_P_RAJ_has_MultiIndex():

load_sequence_list = pd.Series([143.696, -287.392, 143.696, -359.240, 287.392, 0.000, 287.392, -287.392])

# wrap the notch approximation law by a binning class, which precomputes the values
maximum_absolute_load = max(np.abs(load_sequence_list))
seeger_beste_binned = pylife.materiallaws.notch_approximation_law.NotchApproxBinner(
seeger_beste
).initialize(maximum_absolute_load)

# create recorder object
recorder = pylife.stress.rainflow.recorders.FKMNonlinearRecorder()

# create detector object
detector = pylife.stress.rainflow.fkm_nonlinear.FKMNonlinearDetector(
recorder=recorder, notch_approximation_law=seeger_beste_binned, binner=None
recorder=recorder, notch_approximation_law=seeger_beste
)

# perform HCM algorithm, first run
Expand Down

0 comments on commit 603a28f

Please sign in to comment.