|
23 | 23 | [class_width, ...
|
24 | 24 | class_offset] = class_param( x, class_count );
|
25 | 25 | hysteresis = class_width;
|
26 |
| - enforce_margin = 0; |
27 |
| - use_hcm = 0; |
| 26 | + enforce_margin = 0; % First and last data point may be excluded in tp |
| 27 | + use_hcm = 0; % Use 4 point method, not HCM |
| 28 | + use_astm = 0; % Use 4 point method, not ASTM |
28 | 29 | residual_method = 0;
|
29 | 30 | spread_damage = 0;
|
30 | 31 |
|
31 | 32 | [~,re,rm] = rfc( 'rfc', x, class_count, class_width, class_offset, hysteresis, ...
|
32 |
| - residual_method, enforce_margin, use_hcm, spread_damage ); |
| 33 | + residual_method, enforce_margin, use_hcm, use_astm, spread_damage ); |
33 | 34 |
|
34 | 35 | assert( sum( sum( rm ) ) == 0 );
|
35 | 36 |
|
36 | 37 | assert( isempty(re) );
|
37 | 38 |
|
38 | 39 | save( name, 'rm', 're' );
|
39 | 40 |
|
40 |
| - |
41 | 41 | %% One single cycle (up)
|
42 | 42 | name = 'one_cycle_up';
|
43 | 43 | class_count = 4;
|
|
47 | 47 | [class_width, ...
|
48 | 48 | class_offset] = class_param( x, class_count );
|
49 | 49 | hysteresis = class_width * 0.99;
|
50 |
| - enforce_margin = 0; |
51 |
| - use_hcm = 0; |
| 50 | + enforce_margin = 0; % First and last data point may be excluded in tp |
| 51 | + use_hcm = 0; % Use 4 point method, not HCM |
| 52 | + use_astm = 0; % Use 4 point method, not ASTM |
52 | 53 | residual_method = 0;
|
53 | 54 | spread_damage = 0;
|
54 | 55 |
|
55 | 56 | [~,re,rm] = rfc( 'rfc', x, class_count, class_width, class_offset, hysteresis, ...
|
56 |
| - residual_method, enforce_margin, use_hcm, spread_damage ); |
| 57 | + residual_method, enforce_margin, use_hcm, use_astm, spread_damage ); |
57 | 58 |
|
58 | 59 | assert( sum( sum( rm ) ) == 1 );
|
59 | 60 | assert( rm( 3,2 ) == 1 );
|
|
62 | 63 |
|
63 | 64 | save( name, 'rm', 're' );
|
64 | 65 |
|
65 |
| - |
66 | 66 | %% One single cycle (down)
|
67 | 67 | name = 'one_cycle_down';
|
68 | 68 | class_count = 4;
|
69 | 69 | x = export_series( name, [4,2,3,1], class_count );
|
70 | 70 | x_max = 4;
|
71 | 71 | x_min = 1;
|
72 |
| - class_count = 4; |
73 | 72 | [class_width, ...
|
74 | 73 | class_offset] = class_param( x, class_count );
|
75 | 74 | hysteresis = class_width * 0.99;
|
76 |
| - enforce_margin = 0; |
77 |
| - use_hcm = 0; |
| 75 | + enforce_margin = 0; % First and last data point may be excluded in tp |
| 76 | + use_hcm = 0; % Use 4 point method, not HCM |
| 77 | + use_astm = 0; % Use 4 point method, not ASTM |
78 | 78 | residual_method = 0;
|
79 | 79 | spread_damage = 0;
|
80 | 80 |
|
81 | 81 | [~,re,rm] = rfc( 'rfc', x, class_count, class_width, class_offset, hysteresis, ...
|
82 |
| - residual_method, enforce_margin, use_hcm, spread_damage ); |
| 82 | + residual_method, enforce_margin, use_hcm, use_astm, spread_damage ); |
83 | 83 |
|
84 | 84 | assert( sum( sum( rm ) ) == 1 );
|
85 | 85 | assert( rm( 2,3 ) == 1 );
|
|
88 | 88 |
|
89 | 89 | save( name, 'rm', 're' );
|
90 | 90 |
|
91 |
| - |
92 | 91 | %% Small example, taken from url:
|
93 | 92 | % [https://community.plm.automation.siemens.com/t5/Testing-Knowledge-Base/Rainflow-Counting/ta-p/383093]
|
94 | 93 | name = 'small_example';
|
|
99 | 98 | [class_width, ...
|
100 | 99 | class_offset] = class_param( x, class_count );
|
101 | 100 | hysteresis = class_width;
|
102 |
| - enforce_margin = 0; |
103 |
| - use_hcm = 0; |
| 101 | + enforce_margin = 0; % First and last data point may be excluded in tp |
| 102 | + use_hcm = 0; % Use 4 point method, not HCM |
| 103 | + use_astm = 0; % Use 4 point method, not ASTM |
104 | 104 | residual_method = 0;
|
105 | 105 | spread_damage = 0;
|
106 | 106 |
|
107 | 107 | [~,re,rm] = rfc( 'rfc', x, class_count, class_width, class_offset, hysteresis, ...
|
108 |
| - residual_method, enforce_margin, use_hcm, spread_damage ); |
| 108 | + residual_method, enforce_margin, use_hcm, use_astm, spread_damage ); |
109 | 109 |
|
110 | 110 | assert( sum( sum( rm ) ) == 7 );
|
111 | 111 | assert( rm( 5,3 ) == 2 );
|
|
118 | 118 |
|
119 | 119 | save( name, 'rm', 're' );
|
120 | 120 |
|
121 |
| - |
122 | 121 | %% Long data series
|
123 | 122 | rng(5,'twister') % Init random seed
|
124 | 123 | name = 'long_series';
|
|
130 | 129 | x_int = int16(round(xx));
|
131 | 130 | x = double(x_int);
|
132 | 131 | hysteresis = class_width;
|
133 |
| - enforce_margin = 1; |
134 |
| - use_hcm = 0; |
| 132 | + enforce_margin = 1; % Enforce first and last data point included in tp |
| 133 | + use_hcm = 0; % Use 4 point method, not HCM |
| 134 | + use_astm = 0; % Use 4 point method, not ASTM |
135 | 135 | residual_method = 0; % 0=RFC_RES_NONE, 7=RFC_RES_REPEATED
|
136 | 136 | spread_damage = 1; % 0=RFC_SD_HALF_23, 1=RFC_SD_RAMP_AMPLITUDE_23
|
137 | 137 |
|
138 | 138 | assert( sum(abs(xx-x)) < 1e-4 );
|
139 | 139 |
|
140 | 140 | [pd,re,rm,rp,lc,tp,dh] = ...
|
141 | 141 | rfc( 'rfc', double(x_int), class_count, class_width, class_offset, hysteresis, ...
|
142 |
| - residual_method, enforce_margin, use_hcm, spread_damage ); |
| 142 | + residual_method, enforce_margin, use_hcm, use_astm, spread_damage ); |
143 | 143 |
|
144 | 144 | % With residuum: pd == 9.8934e-06 (repeated)
|
145 | 145 | % Without residuum: pd == 1.1486e-07
|
|
159 | 159 |
|
160 | 160 | [pd,re,rm,rp,lc,tp,dh] = ...
|
161 | 161 | rfc( 'rfc', x, class_count, class_width, class_offset, hysteresis, ...
|
162 |
| - residual_method, enforce_margin, use_hcm, spread_damage ); |
| 162 | + residual_method, enforce_margin, use_hcm, use_astm, spread_damage ); |
163 | 163 |
|
164 | 164 | assert( abs( sum( dh ) / pd - 1 ) < 1e-10 );
|
165 | 165 | hold( ax(2), 'all' );
|
|
198 | 198 | assert( all( test < 1e-1 ))
|
199 | 199 | end
|
200 | 200 |
|
| 201 | + %% Compare with ASTM E 1049-85 (MATLAB) |
| 202 | + if 0 |
| 203 | + enforce_margin = 1; % Enforce first and last data point included in tp |
| 204 | + use_hcm = 0; % Use 4 point method, not HCM |
| 205 | + use_astm = 0; % Use 4 point method, not ASTM |
| 206 | + residual_method = 4; % 4=ASTM related |
| 207 | + spread_damage = 0; % 0=RFC_SD_HALF_23, 1=RFC_SD_RAMP_AMPLITUDE_23 |
| 208 | + class_count = 1000; |
| 209 | + class_width = 5; |
| 210 | + class_offset = -2025; |
| 211 | + hysteresis = class_width; |
| 212 | + |
| 213 | + if 1 |
| 214 | + load long_series_csv.mat |
| 215 | + else |
| 216 | + x_int = [2,5,3,6,2,4,1,6,1,4,1,5,3,6,3,6,1,5,2]; |
| 217 | + x_max = max(x_int)+0.5; |
| 218 | + x_min = min(x_int)-0.5; |
| 219 | + class_width = 1; |
| 220 | + class_offset = x_min; |
| 221 | + hysteresis = 0; |
| 222 | + class_count = (x_max - x_min) / class_width; |
| 223 | + end |
| 224 | + |
| 225 | + residual_method = 7; % 7=repeated |
| 226 | + [pd7,re7,rm7,rp7,lc7,tp7] = ... |
| 227 | + rfc( 'rfc', double(x_int), class_count, class_width, class_offset, hysteresis, ... |
| 228 | + residual_method, enforce_margin, use_hcm, use_astm, spread_damage ); |
| 229 | + |
| 230 | + residual_method = 4; % 4=ASTM related |
| 231 | + [pd4,re4,rm4,rp4,lc4,tp4] = ... |
| 232 | + rfc( 'rfc', double(x_int), class_count, class_width, class_offset, hysteresis, ... |
| 233 | + residual_method, enforce_margin, use_hcm, use_astm, spread_damage ); |
| 234 | + |
| 235 | + use_astm = 1; % Use ASTM algorithm |
| 236 | + residual_method = 4; % 4=ASTM related |
| 237 | + [pd4a,re4a,rm4a,rp4a,lc4a,tp4a] = ... |
| 238 | + rfc( 'rfc', double(x_int), class_count, class_width, class_offset, hysteresis, ... |
| 239 | + residual_method, enforce_margin, use_hcm, use_astm, spread_damage ); |
| 240 | + |
| 241 | + % MATLAB - Rainflow counts for fatigue analysis (according to ASTM E 1049) |
| 242 | + c = rainflow( tp4a(:,2), 'ext' ); |
| 243 | + edges = (0:class_count) .* class_width; |
| 244 | + [~,bin] = histc( c(:,2), edges ); |
| 245 | + N = accumarray( bin, c(:,1) ); |
| 246 | + N(class_count+1) = 0; |
| 247 | + N = N(1:class_count); |
| 248 | + Range = (edges(1:end-1)+edges(2:end)) / 2; |
| 249 | + pd_astm = sum( N(:)' ./ (1e7*(Range/2/1e3).^-5) ); |
| 250 | + |
| 251 | + figure |
| 252 | + plot( cumsum(rp7, 'reverse'), edges(1:end-1), 'g-', 'Disp', '4-point method, res=repeated' ), hold all |
| 253 | + plot( cumsum(rp4, 'reverse'), edges(1:end-1), 'k--', 'Disp', '4-point method, res=half cycles' ), hold all |
| 254 | + plot( cumsum(rp4a, 'reverse'), edges(1:end-1), 'b--', 'Disp', '3-point method, ASTM E 1049-85, res=half cycles' ), hold all |
| 255 | + plot( cumsum(N, 'reverse'), edges(1:end-1), 'r-', 'Disp', '3-point method, ASTM E 1049-85 (MATLAB)' ), hold all |
| 256 | + set( gca, 'XScale', 'log' ); |
| 257 | + set( gca, 'YScale', 'log' ); |
| 258 | + xlim( [0.9 1e3] ); |
| 259 | + xlabel( 'Counts' ); |
| 260 | + ylabel( 'Range (normalized, prepared)' ); |
| 261 | + grid |
| 262 | + legend |
| 263 | + fprintf( 'Damage ratio 4pt,repeated vs. ASTM: %g%%\n', pd7/pd_astm ); |
| 264 | + end |
| 265 | + |
201 | 266 | %% Long series, turning points only
|
202 | 267 | y = rfc( 'turningpoints', x, class_width*2, enforce_margin );
|
203 | 268 | figure
|
204 | 269 | plot( x, 'k-', 'DisplayName', 'time series' );
|
205 | 270 | hold all
|
206 | 271 | plot( y(2,:), y(1,:), 'r--', 'DisplayName', 'turning points' );
|
207 | 272 | legend( 'show' );
|
| 273 | + |
208 | 274 | end
|
209 | 275 |
|
210 | 276 | function rounded_data = export_series( filename, data, class_count, format )
|
|
0 commit comments