Skip to content

Commit bbf1e68

Browse files
Merge pull request #154 from boschresearch/154-assessment-levels
Make HCM rainflow counter agnostic of the assessment point index
2 parents 94d3f8d + ddbfbed commit bbf1e68

File tree

3 files changed

+34
-10
lines changed

3 files changed

+34
-10
lines changed

Diff for: src/pylife/stress/rainflow/fkm_nonlinear.py

+5-7
Original file line numberDiff line numberDiff line change
@@ -543,17 +543,17 @@ def _adjust_samples_and_flush_for_hcm_first_run(self, samples):
543543
if not is_multi_index:
544544
samples = np.concatenate([[0], np.asarray(samples)])
545545
else:
546-
# get the index with all node_id`s
547-
node_id_index = samples.groupby("node_id").first().index
546+
assessment_levels = [name for name in samples.index.names if name != "load_step"]
547+
assessment_idx = samples.groupby(assessment_levels).first().index
548548

549549
# create a new sample with 0 load for all nodes
550-
multi_index = pd.MultiIndex.from_product([[0], node_id_index], names=["load_step","node_id"])
550+
multi_index = pd.MultiIndex.from_product([[0], assessment_idx], names=samples.index.names)
551551
first_sample = pd.Series(0, index=multi_index)
552552

553553
# increase the load_step index value by one for all samples
554554
samples_without_index = samples.reset_index()
555555
samples_without_index.load_step += 1
556-
samples = samples_without_index.set_index(["load_step", "node_id"])[0]
556+
samples = samples_without_index.set_index(samples.index.names)[0]
557557

558558
# prepend the new zero load sample
559559
samples = pd.concat([first_sample, samples], axis=0)
@@ -568,9 +568,7 @@ def _adjust_samples_and_flush_for_hcm_first_run(self, samples):
568568
scalar_samples_twice = np.concatenate([scalar_samples, scalar_samples])
569569
turn_indices, _ = RFG.find_turns(scalar_samples_twice)
570570

571-
flush = True
572-
if len(scalar_samples)-1 not in turn_indices:
573-
flush = False
571+
flush = len(scalar_samples)-1 in turn_indices
574572

575573
return samples, flush
576574

Diff for: src/pylife/stress/rainflow/recorders.py

+4-3
Original file line numberDiff line numberDiff line change
@@ -288,11 +288,12 @@ def collective(self):
288288
"""
289289

290290
if len(self.S_min) > 0 and len(self.S_min.index.names) > 1:
291-
n_nodes = self.S_min.groupby('node_id').first().count()
292-
n_hystereses = int(len(self.S_min) / n_nodes)
291+
assessment_levels = [name for name in self.S_min.index.names if name != "load_step"]
292+
n_assessment_points = self.S_min.groupby(assessment_levels).first().count()
293+
n_hystereses = int(len(self.S_min) / n_assessment_points)
293294

294295
index = pd.MultiIndex.from_product(
295-
[range(n_hystereses), range(n_nodes)],
296+
[range(n_hystereses), range(n_assessment_points)],
296297
names=["hysteresis_index", "assessment_point_index"],
297298
)
298299
else:

Diff for: tests/stress/rainflow/test_fkm_nonlinear.py

+25
Original file line numberDiff line numberDiff line change
@@ -817,6 +817,31 @@ def test_hcm_first_second(vals, num):
817817
assert multi_collective.to_json(indent=4) == reference
818818

819819

820+
def test_element_id():
821+
vals = np.array([100., -200., 100., -250., 200., 0., 200., -200.]) * (250+6.6)/250 * 1.4
822+
signal = pd.DataFrame({11: vals, 12: 2*vals, 13: 3*vals, 'load_step': range(len(vals))}).set_index('load_step').stack()
823+
signal.index.names = ['load_step', 'element_id']
824+
825+
E = 206e3 # [MPa] Young's modulus
826+
K = 3.1148*(1251)**0.897 / (( np.min([0.338, 1033.*1251.**(-1.235)]) )**0.187)
827+
#K = 2650.5 # [MPa]
828+
n = 0.187 # [-]
829+
K_p = 3.5 # [-] (de: Traglastformzahl) K_p = F_plastic / F_yield (3.1.1)
830+
831+
extended_neuber = NAL.ExtendedNeuber(E, K, n, K_p)
832+
833+
detector = FKMNonlinearDetector(
834+
recorder=RFR.FKMNonlinearRecorder(), notch_approximation_law=extended_neuber
835+
)
836+
detector.process_hcm_first(signal).process_hcm_second(signal)
837+
838+
with open(f'tests/stress/rainflow/reference-fkm-nonlinear/reference_first_second-7.json') as f:
839+
reference = f.read()
840+
841+
assert detector.recorder.collective.to_json(indent=4) == reference
842+
assert detector.recorder.loads_max.index.names == ["load_step", "element_id"]
843+
844+
820845
@pytest.fixture
821846
def detector_seeger_beste():
822847
E = 206e3 # [MPa] Young's modulus

0 commit comments

Comments
 (0)