Git Product home page Git Product logo

fatpack's Introduction

logo_img

fatpack

Python package for fatigue analysis of data series. The package requires numpy.

Installation

Either install from the github repository (latest version),

pip install git+https://github.com/gunnstein/fatpack.git

install from the python package index

pip install fatpack

or from the conda-forge:

conda install --channel=conda-forge fatpack

Usage

The package provides functionality for rainflow cycle counting, defining endurance curves, mean and compressive stress range correction and racetrack filtering. The code example below shows how fatigue damage can be calculated:

import numpy as np
import fatpack


# Assume that `y` is the data series, we generate one here
y = np.random.normal(0., 30., size=10000)

# Extract the stress ranges by rainflow counting
S = fatpack.find_rainflow_ranges(y)

# Determine the fatigue damage, using a trilinear fatigue curve
# with detail category Sc, Miner's linear damage summation rule.
Sc = 90.0
curve = fatpack.TriLinearEnduranceCurve(Sc)
fatigue_damage = curve.find_miner_sum(S)

An example is included (example.py) which extracts rainflow cycles, generates the rainflow matrix and rainflow stress spectrum, see the figure presented below. The example is a good place to start to get into the use of the package.

example_img

Additional examples are found in the examples folder.

Support

Please open an issue for support.

Contributing

Please contribute using Github Flow. Create a branch, add commits, and open a pull request.

fatpack's People

Contributors

greschd avatar gunnstein avatar lollocappo avatar sfreund-dlr avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

fatpack's Issues

A little distance between reversals and peaks(valleys)

There is a little distance (about 5 in my example) between reversals and peaks (valleys), whether or not filtered.

Is it normal? Shall I do something to reduce the deviation?

code:

import numpy as np
import matplotlib.pyplot as plt
import fatpack

plt.rcParams['figure.figsize'] = (10, 5)
plt.rcParams['grid.linestyle'] = "--"
plt.rcParams['axes.grid'] = True


def reversals(data, draw=False, filterrange=0.0):
    rev = fatpack.find_reversals(data[0])
    if filterrange < 1.0e-9:
        x, ix = rev
    else:
        x, ix = fatpack.find_reversals_racetrack_filtered(data[0], filterrange)
    if draw:
        plt.plot(data[0], color="black", label='original data')
        plt.plot(ix, x, 'ro', fillstyle='none', label='reversals')
        plt.axis([0, 10000, -0.045, 0.045])
        plt.show()
    return x


if __name__ == '__main__':
    response = np.load('response.npy', allow_pickle=True)
    reversals(response, True)
    reversals(response, True, 0.0001)
    print()

output:

image

image

response.npy:

response.zip

Error in find_rainflow_ranges for boundary cases

find_rainflow_ranges gives error for arbitrary numpy array. For example if the array doesn't contain any cycles - fatpack.find_rainflow_ranges(np.array([1,2,3,4,5]), return_means=True, k=2**14) produces error.

image

Other rainflow matrices

Dear Thomas,
thank you for your effort. The package seems to be very useful. I was wondering if it could be possible to plot also the other two rainflow matrices (avg - range and min - max).
Thank you very much

Endurance curve

Can you please provide a reference and theoretical explanations for the endurance curve definition? It is not that clear to me the usage of Sc on the definitions.
Thanks

Error in Rainflow bins

I noticed an error in the find_rainflow_matrix bin creation step, I assume below should be cc[:, 0].max instead?
image

Missing case in concatenate_reversals?

Is there a missing case in the concatenate_reversals in rainflow.py file? What happens when t1=0? Or should that be an impossible case?

R1, R2 = reversals1, reversals2
dRstart, dRend, dRjoin = R2[1] - R2[0], R1[-1] - R1[-2], R2[0] - R1[-1]
t1, t2 = dRend*dRstart, dRend*dRjoin
if (t1 > 0) and (t2 < 0):
    result = (R1, R2)
elif (t1 > 0) and (t2 >= 0):
    result = (R1[:-1], R2[1:])
elif (t1 < 0) and (t2 >= 0):
    result = (R1, R2[1:])
elif (t1 < 0) and (t2 < 0):
    result = (R1[:-1], R2)
return np.concatenate(result)

racetrack

Dear,
I am approaching the racetrack filtering, can you please provide an example?
Thank you very much.

Reference and theory

Thanks a lot for the great and easy to use tool!
I'm looking for references for the different endurance curve you're using, and even though you mention EC9, I'm trying to find something a bit more simple than a complete eurocode document.
Apart from that it's working great on pandas timeseries, making it a great tool for simulation analysis.
Cheers !

Numpy asfarray was removed in numpy 2.0

When running:
curve.find_miner_sum(S)
line 126, in find_miner_sum
Sr = np.asfarray(S)

AttributeError: np.asfarray was removed in the NumPy 2.0 release. Use np.asarray with a proper dtype instead.

Rainflow count on a dataseries with repetitions

Dear Thomas,
thank for the package. It is very helpful and a good starting point on timeseries fatigue calculation.
My use-case of the package is in wind turbine engineering to retrieve the Markov matrices and damage equivalent values of several dataseries which are combined with a single repetitions file giving the occurrence number of each dataseries within a representative lifetime.

For the use-case wind turbines, the lifetime fatigue loads are given by a set of dataseries and a file giving the number of occurrences for each of these dataseries during the turbines lifetime:

#filename; occurrences
dataseries_1; n
dataseries_2; m

My approach is to calculate the ranges per file and add a third column giving the occurrence of each row and aggregate the ranges from all dataseries in one array:

#range; rean; occurrence
S_i_dataseries_1; S_m_j_dataseries_1; n
S_j_dataseries_2; S_m_j_dataseries_2; m

Now, how to get the representative Markov Matrix for all dataseries and their respective occurrences?

My guess on how to incorporate this would be directly at the function "find_rainflow_matrix()" of "rainflow.py".
image

Does this make sense to add as a feature or capability to the code itself or can this already be solved with the present release?
Thank you very much!

Cheers,
Max

help with half cycle counting

Hi there! This is not an issue--can you please explain how half cycles are accounted for in your rainflow script? I have read through some of the cited articles, but I only have a beginner level understanding of rainflow counting. Does it have to do with reversal concatenation?

The only place I see it mentioned explicitly in the code is in find_range_count using the optional "weight" argument.

Thank you!

SN Array instead of Sc

Hello, I was wondering if you have a suggestion on a quick way to import own array of SN values (SN curve from test or from a simulation of a notch). I am familiar with many standards/ books that try to estimate SN curve but often enough, historic info or test data is best for damage comparison/ sensitivity bounds studies on damage and risk assessments.

Adding fatpack to conda-forge

Many thanks to @Gunnstein for creating such a helpful python package. The NREL team has been using it more and more and we would like to add it to the conda-forge ecosystem. I have done the initial effort to make that happen and am looking for the blessing from the core team to push ahead. gunnstein has been added to the list of feedstock maintainers, of course. See the pending PR here.

add min max for load class boundaries

when calculating some fatigue characteristics of a load set using fatpack.rainflow and one wants to calculcate intermediate steps using just a slice of the load set, then the load class boundaries vary. This is due to the absolute min/max values might not be in the slice of the given load set. Example:

Figure_1

The unsteady steps at approx 2.5E7 and 4.8E7 result from a shift in the values of ymin or ymax in fatpack.rainflow.get_load_class_boundaries().

Thus, ymin and ymax are introduced as optional parameters. Result:

Figure_2

Recalculating the Wikipedia example with fatpack

Hey, I used the values from https://en.wikipedia.org/wiki/Rainflow-counting_algorithm as reversals in example.py:
reversals = np.array([2,-14,10,0,13,-9,11,-8,8,-9,15,-4,10,0,13,0])
And I am wondering, why the fatpack results (cycles and half-cycles) are slightly different from those in the table in the wiki-article:

Stress (MPa) Whole cycles Half cycles
10 2 0
13 0 1
16 1 1
17 0 1
19 0 1
20 1 0
22 1 0
29 0 1

fatpack total cycles:
[[ 10 0]
[ -8 8]
[ -9 11]
[ 13 -9]
[ 10 0]
[ 0 2]
[ -4 13]
[ 15 -14]]

I would appreciate your comment on this. Do you compute sth. like "averaged full cycles" from the half cycles? Where does the [0, 2]-cycle come from? Why do you asses [15, -14] as a full cycle? Thank you very much!

Large Damage on Miner's Rule

Hi, the signal I'm using is the one below and as you can see the pressure isn't even in MPa:

Captura de Tela 2021-09-22 às 01 13 17

Despite this fact, when I apply the find_miner_sum function I get this:
Captura de Tela 2021-09-22 às 01 17 02

I would like to state that I'm new at this subject and I thought only pressures in MPa would cause damage to the equipment, so my question is: Is this value possible or normal to find for pressure values like these? Because if a value such as 1.62E+01 is true then the equipment would pretty damaged.

Oscillations in mean values

I was trying to benchmark results from fatpack with another python package called rainflow on my sample data (sample.txt) with 64 bins in both fatpack and rainflow. Range vs cycles looks reasonable but I observed some weird behavior in fatpack cycles for mean.
image

Python Script

`
import fatpack, rainflow
import numpy as np

import matplotlib.pyplot as plt
import matplotlib.pyplot as plt

y = np.loadtxt(r"sample.txt")

S, Sm = fatpack.find_rainflow_ranges(y, return_means=True, k=64)
data_arr = np.array([Sm, S]).T
rowbins, colbins, rfcmat = fatpack.find_rainflow_matrix(data_arr, 64, 64, return_bins=True)

rowbins = 0.5 * (rowbins[:-1] + rowbins[1:]) # get mid points 
colbins = 0.5 * (colbins[:-1] + colbins[1:]) # get mid points 

ranges = []
means = []
counts = []

for range_, mean_, count, *_ in rainflow.extract_cycles(y):
    ranges.append(range_)
    means.append(mean_)
    counts.append(count)

import numpy as np

matrix = np.histogram2d(x=ranges, y=means, bins = 64, weights=counts)
rnges = 0.5 * (matrix[1][:-1] + matrix[1][1:])
men = 0.5 * (matrix[2][:-1] + matrix[2][1:])

plt.close('all')
plt.rcParams['font.size'] = 12
fig, (ax1,ax2) = plt.subplots(2,1)
ax1.plot(colbins, np.sum(rfcmat, axis = 0), label = 'fatpack')
ax1.plot(rnges, np.sum(matrix[0], axis = 1), label = 'rainflow')
ax1.set_title('Range vs Cycles')
ax1.set_ylabel('Range')
ax1.set_xlabel('Cycles')
ax1.grid()
ax1.legend()

ax2.plot(rowbins, np.sum(rfcmat, axis = 1), label = 'fatpack')
ax2.plot(men, np.sum(matrix[0], axis = 0), label = 'rainflow')
ax2.set_title('Mean vs Cycles')
ax2.set_xlabel('Mean')
ax2.set_ylabel('Cycles')
ax2.legend()
ax2.grid()
plt.tight_layout()
`

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.