Skip to content

Commit

Permalink
rfcnt-0.2.0
Browse files Browse the repository at this point in the history
Python:
- New parameter "lc_method" to control counting of falling and/or rising slopes. Default changed from rising AND falling slopes to rising only!
- Results of range pair counting now hold the ranges instead of the amplitudes.
  • Loading branch information
a-ma72 committed Nov 29, 2021
1 parent 436e296 commit 2a4df9d
Show file tree
Hide file tree
Showing 6 changed files with 46 additions and 21 deletions.
2 changes: 1 addition & 1 deletion python/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ predefined functions.
pip install {packagename}.tar.gz
where _{packagename}_ is the current package release, for example:

pip install rfcnt-0.1.1.tar.gz
pip install rfcnt-0.2.0.tar.gz

### Test
_rfcnt_ packages include some unit tests, which can be run:
Expand Down
Binary file modified python/jupyter_screenshot.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion python/setup.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from setuptools import setup, Extension
from os import path

version = (0, 1, 2)
version = (0, 2, 0)

try:
from numpy import get_include as get_numpy_include
Expand Down
59 changes: 42 additions & 17 deletions python/src/rfcnt.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,26 +33,28 @@ const char* rfc_err_str( int nr )
static
int parse_rfc_kwargs( PyObject* kwargs, Py_ssize_t len, Rainflow *rf, Rainflow::rfc_res_method *res_method )
{
PyObject *empty = PyTuple_New(0);
int class_count = 100;
double class_width = -1;
double class_offset = 0;
double hysteresis = -1;
int enforce_margin = 1;
int use_hcm = 0;
int use_astm = 0;
int spread_damage = Rainflow::RFC_SD_TRANSIENT_23c;
PyObject *wl = NULL;
double wl_sd = 1e3, wl_nd = 1e7,
wl_k = 5, wl_k2 = 5;
PyObject *empty = PyTuple_New(0);
int class_count = 100;
double class_width = -1; // -1 = "calculated"
double class_offset = 0;
double hysteresis = -1; // -1 = "calculated"
int enforce_margin = 1; // true
int use_hcm = 0; // false
int use_astm = 0; // false
int lc_method = 0; // Count rising slopes only
int flags = Rainflow::RFC_FLAGS_DEFAULT;
int spread_damage = Rainflow::RFC_SD_TRANSIENT_23c;
PyObject *wl = NULL;
double wl_sd = 1e3, wl_nd = 1e7,
wl_k = 5, wl_k2 = 5;

*res_method = Rainflow::RFC_RES_REPEATED;

char* kw[] = {"class_width", "class_count", "class_offset",
"hysteresis","residual_method", "enforce_margin",
"use_HCM", "use_ASTM", "spread_damage", "wl", NULL};
"use_HCM", "use_ASTM", "spread_damage", "lc_method", "wl", NULL};

if( !PyArg_ParseTupleAndKeywords( empty, kwargs, "d|iddiiiiiO", kw,
if( !PyArg_ParseTupleAndKeywords( empty, kwargs, "d|iddiiiiiiO", kw,
&class_width,
&class_count,
&class_offset,
Expand All @@ -62,6 +64,7 @@ int parse_rfc_kwargs( PyObject* kwargs, Py_ssize_t len, Rainflow *rf, Rainflow::
&use_hcm,
&use_astm,
&spread_damage,
&lc_method,
&wl ) )
{
Py_DECREF( empty );
Expand Down Expand Up @@ -117,7 +120,29 @@ int parse_rfc_kwargs( PyObject* kwargs, Py_ssize_t len, Rainflow *rf, Rainflow::
if( hysteresis < 0 ) hysteresis = class_width;
}

if( !rf->init( class_count, class_width, class_offset, hysteresis ) )
// lc_method
flags &= ~Rainflow::RFC_FLAGS_COUNT_LC;

switch( lc_method )
{
case 0:
flags |= Rainflow::RFC_FLAGS_COUNT_LC_UP;
break;

case 1:
flags |= Rainflow::RFC_FLAGS_COUNT_LC_DN;
break;

case 2:
flags |= Rainflow::RFC_FLAGS_COUNT_LC;
break;

default:
PyErr_SetString( PyExc_RuntimeError, "Parameter 'lc_method' must be in range 0 to 2!" );
return 0;
}

if( !rf->init( class_count, class_width, class_offset, hysteresis, (Rainflow::rfc_flags_e)flags ) )
{
PyErr_Format( PyExc_RuntimeError, "Rainflow initialization error (%s)", rfc_err_str( rf->error_get() ) );
return 0;
Expand Down Expand Up @@ -275,7 +300,7 @@ int prepare_results( Rainflow *rf, Rainflow::rfc_res_method res_method, PyObject
PyArray_FILLWBYTE( arr, 0 );
for( unsigned i = 0; i < class_count; i++ )
{
*(double*)PyArray_GETPTR2( arr, i, 0 ) = (double)sa[i];
*(double*)PyArray_GETPTR2( arr, i, 0 ) = (double)sa[i] * 2; // range = 2 * amplitude
*(double*)PyArray_GETPTR2( arr, i, 1 ) = (double)ct[i];
}
PyDict_SetItemString( *ret, "rp", (PyObject*)arr );
Expand All @@ -290,7 +315,7 @@ int prepare_results( Rainflow *rf, Rainflow::rfc_res_method res_method, PyObject
PyArray_FILLWBYTE( arr, 0 );
for( unsigned i = 0; i < class_count; i++ )
{
*(double*)PyArray_GETPTR2( arr, i, 0 ) = (double)sa[i];
*(double*)PyArray_GETPTR2( arr, i, 0 ) = (double)sa[i]; // class upper limit
*(double*)PyArray_GETPTR2( arr, i, 1 ) = (double)ct[i];
}
PyDict_SetItemString( *ret, "lc", (PyObject*)arr );
Expand Down
2 changes: 1 addition & 1 deletion python/tests/examples.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ def example_1():
y=r["sa"],
drawstyle='steps-pre', ci=None, ax=ax2)
plt.xscale("log")
plt.ylim(bottom=0, top=1000)
plt.ylim(bottom=0, top=2000)
plt.xlim(left=0.9)
plt.grid(which="both")
plt.xlabel("N (log) [1]")
Expand Down
2 changes: 1 addition & 1 deletion python/tests/test_rfcnt.py
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,7 @@ def test_long_series(self):
class_width = 50
x = pd.read_csv(os.path.join(self.get_script_path(), "long_series.csv"), header=None)
x = x.to_numpy().squeeze()
hysteresis = class_width
hysteresis = class_width
use_HCM = 0
enforce_margin = 1 # Enforce first and last data point included in tp
use_HCM = 0 # Use 4 point method, not HCM
Expand Down

0 comments on commit 2a4df9d

Please sign in to comment.