Skip to content

Commit 603a28f

Browse files
Use automatic binning of FKMNonLinearDetector
Signed-off-by: Johannes Mueller <johannes.mueller4@de.bosch.com>
1 parent 190e491 commit 603a28f

File tree

3 files changed

+17
-55
lines changed

3 files changed

+17
-55
lines changed

src/pylife/materiallaws/notch_approximation_law_seegerbeste.py

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ def stress(self, load, *, rtol=1e-4, tol=1e-4):
7777
The resulting stress
7878
'''
7979
# initial value as given by correction document to FKM nonlinear
80-
x0 = load * (1 - (1 - 1/self._K_p)/1000)
80+
x0 = np.asarray(load * (1 - (1 - 1/self._K_p)/1000))
8181

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

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

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

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

@@ -471,13 +472,13 @@ def _stress_fix_not_converged_values(self, stress, load, x0, rtol, tol):
471472
load_diverged = load_array[index_diverged]
472473
result = optimize.newton(
473474
func=self._stress_implicit,
474-
x0=x0_diverged,
475+
x0=np.asarray(x0_diverged),
475476
args=([load_diverged]),
476477
full_output=True,
477478
rtol=rtol, tol=tol, maxiter=50
478479
)
479480

480-
if result[1].converged:
481+
if result.converged.all():
481482
stress[0][index_diverged] = result[0]
482483
return stress
483484

src/pylife/strength/fkm_nonlinear/assessment_nonlinear_standard.py

Lines changed: 7 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -389,27 +389,21 @@ def _compute_component_woehler_curves(assessment_parameters):
389389
return assessment_parameters, component_woehler_curve_P_RAM, component_woehler_curve_P_RAJ
390390

391391

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

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

400-
# wrap the notch approximation law by a binning class, which precomputes the values
401-
extended_neuber_binned = (
402-
pylife.materiallaws.notch_approximation_law.NotchApproxBinner(
403-
extended_neuber
404-
).initialize(maximum_absolute_load)
405-
)
406-
407400
# create recorder object
408401
recorder = pylife.stress.rainflow.recorders.FKMNonlinearRecorder()
409402

410403
# create detector object
411404
detector = pylife.stress.rainflow.fkm_nonlinear.FKMNonlinearDetector(
412-
recorder=recorder, notch_approximation_law=extended_neuber_binned, binner=None)
405+
recorder=recorder, notch_approximation_law=extended_neuber
406+
)
413407

414408
# perform HCM algorithm, first run
415409
detector.process_hcm_first(scaled_load_sequence)
@@ -418,7 +412,7 @@ def _compute_hcm_RAM(assessment_parameters, scaled_load_sequence, maximum_absolu
418412
# perform HCM algorithm, second run
419413
detector.process_hcm_second(scaled_load_sequence)
420414

421-
return detector_1st, detector, extended_neuber_binned, recorder
415+
return detector_1st, detector, extended_neuber, recorder
422416

423417

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

496-
# wrap the notch approximation law by a binning class, which precomputes the values
497-
seeger_beste_binned = pylife.materiallaws.notch_approximation_law.NotchApproxBinner(
498-
seeger_beste
499-
).initialize(maximum_absolute_load)
500-
501490
# create recorder object
502491
recorder = pylife.stress.rainflow.recorders.FKMNonlinearRecorder()
503492

504493
# create detector object
505494
detector = pylife.stress.rainflow.fkm_nonlinear.FKMNonlinearDetector(
506-
recorder=recorder, notch_approximation_law=seeger_beste_binned, binner=None)
495+
recorder=recorder, notch_approximation_law=seeger_beste
496+
)
507497
detector_1st = copy.deepcopy(detector)
508498

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

515-
return detector_1st, detector, seeger_beste_binned, recorder
505+
return detector_1st, detector, seeger_beste, recorder
516506

517507

518508
def _compute_damage_and_lifetimes_RAJ(assessment_parameters, recorder, component_woehler_curve_P_RAJ, result):

tests/strength/test_damage_calculator.py

Lines changed: 4 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -92,20 +92,12 @@ def test_woehler_curve_P_RAM_collective_has_no_index():
9292

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

95-
# wrap the notch approximation law by a binning class, which precomputes the values
96-
maximum_absolute_load = max(np.abs(load_sequence_list))
97-
extended_neuber_binned = (
98-
pylife.materiallaws.notch_approximation_law.NotchApproxBinner(
99-
extended_neuber
100-
).initialize(maximum_absolute_load)
101-
)
102-
10395
# create recorder object
10496
recorder = pylife.stress.rainflow.recorders.FKMNonlinearRecorder()
10597

10698
# create detector object
10799
detector = pylife.stress.rainflow.fkm_nonlinear.FKMNonlinearDetector(
108-
recorder=recorder, notch_approximation_law=extended_neuber_binned, binner=None
100+
recorder=recorder, notch_approximation_law=extended_neuber
109101
)
110102

111103
# perform HCM algorithm, first run
@@ -202,20 +194,12 @@ def test_woehler_curve_P_RAM_collective_has_MultiIndex():
202194

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

205-
# wrap the notch approximation law by a binning class, which precomputes the values
206-
maximum_absolute_load = max(np.abs(load_sequence_list))
207-
extended_neuber_binned = (
208-
pylife.materiallaws.notch_approximation_law.NotchApproxBinner(
209-
extended_neuber
210-
).initialize(maximum_absolute_load)
211-
)
212-
213197
# create recorder object
214198
recorder = pylife.stress.rainflow.recorders.FKMNonlinearRecorder()
215199

216200
# create detector object
217201
detector = pylife.stress.rainflow.fkm_nonlinear.FKMNonlinearDetector(
218-
recorder=recorder, notch_approximation_law=extended_neuber_binned, binner=None
202+
recorder=recorder, notch_approximation_law=extended_neuber
219203
)
220204

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

302286
load_sequence_list = pd.Series([143.696, -287.392, 143.696, -359.240, 287.392, 0.000, 287.392, -287.392])
303-
304-
# wrap the notch approximation law by a binning class, which precomputes the values
305-
maximum_absolute_load = max(np.abs(load_sequence_list))
306-
seeger_beste_binned = pylife.materiallaws.notch_approximation_law.NotchApproxBinner(
307-
seeger_beste
308-
).initialize(maximum_absolute_load)
309-
310287
# create recorder object
311288
recorder = pylife.stress.rainflow.recorders.FKMNonlinearRecorder()
312289

313290
# create detector object
314291
detector = pylife.stress.rainflow.fkm_nonlinear.FKMNonlinearDetector(
315-
recorder=recorder, notch_approximation_law=seeger_beste_binned, binner=None
292+
recorder=recorder, notch_approximation_law=seeger_beste
316293
)
317294

318295
# perform HCM algorithm, first run
@@ -410,18 +387,12 @@ def test_woehler_curve_P_RAJ_has_MultiIndex():
410387

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

413-
# wrap the notch approximation law by a binning class, which precomputes the values
414-
maximum_absolute_load = max(np.abs(load_sequence_list))
415-
seeger_beste_binned = pylife.materiallaws.notch_approximation_law.NotchApproxBinner(
416-
seeger_beste
417-
).initialize(maximum_absolute_load)
418-
419390
# create recorder object
420391
recorder = pylife.stress.rainflow.recorders.FKMNonlinearRecorder()
421392

422393
# create detector object
423394
detector = pylife.stress.rainflow.fkm_nonlinear.FKMNonlinearDetector(
424-
recorder=recorder, notch_approximation_law=seeger_beste_binned, binner=None
395+
recorder=recorder, notch_approximation_law=seeger_beste
425396
)
426397

427398
# perform HCM algorithm, first run

0 commit comments

Comments
 (0)