|
1 | 1 | #include <tuple> |
2 | 2 | #include <cmath> |
3 | 3 | #include <limits> |
| 4 | +#include <numbers> |
4 | 5 | #include <stdexcept> |
5 | 6 | #include "Core/Utility.hpp" |
6 | 7 |
|
@@ -161,3 +162,57 @@ Matrix<double> Utility::executeMinerSummation(double category, double resistance |
161 | 162 | return results; |
162 | 163 |
|
163 | 164 | } |
| 165 | + |
| 166 | +std::pair<double, QString> Utility::computeRemainingFatigueLife(const QString& detail, |
| 167 | + const std::unordered_map<QString, double>& parameters, const Matrix<double>& history, |
| 168 | + const Matrix<double>& rainflow, double C, double m, double ΔKth, double ΔKcr, double a0) { |
| 169 | + double sampledTimePeriod = (history.at(history.rowCount() - 1, 0) - history.at(0, 0))/(60*60*24*365.2425); // years |
| 170 | + auto c = rainflow.getColumn(0); |
| 171 | + auto Δσ = rainflow.getColumn(1); |
| 172 | + if (detail == "IIW - Cruciform joint K-butt weld") { |
| 173 | + double w = parameters.at("w"); // Out-of-plane width [mm] |
| 174 | + double H = parameters.at("H"); // Fillet weld leg length [mm] |
| 175 | + double T = parameters.at("T"); // Attachment plate thickness [mm] |
| 176 | + double t = parameters.at("t"); // Main plate thickness [mm] |
| 177 | + double W = parameters.at("W"); // Fillet weld leg length [mm] |
| 178 | + double A = parameters.at("A"); // Weld throat size [mm] |
| 179 | + double θ = parameters.at("θ"); // Weld angle [deg] |
| 180 | + int i = 0; |
| 181 | + int N = 0; |
| 182 | + Matrix<double> ΔK(Δσ.size(), 1); |
| 183 | + double a = a0; |
| 184 | + double af = T; |
| 185 | + double rfl = 0.0; // years |
| 186 | + double dfl = 250.0; // years |
| 187 | + double π = std::numbers::pi; |
| 188 | + while (true) { |
| 189 | + double limit1 = (2*a)/w; |
| 190 | + if (a >= af) return { rfl, "a ≥ a_f" }; |
| 191 | + if (ΔK.at(i) >= ΔKcr) return {rfl, "ΔK ≥ ΔK_cr"}; |
| 192 | + if (limit1 >= 0.8) return { rfl, "(2*a)/w ≥ 0.8" }; |
| 193 | + if (rfl >= dfl) return { dfl, "RFL ≥ 250 years" }; |
| 194 | + double fw = std::sqrt(1.0/std::cos(π*a/w*std::sqrt(a/T))); |
| 195 | + double c1 = 0.7061 - 0.4091*H/T + 0.1596*std::pow(H/T, 2) + 0.3739*W/T - 0.1329*std::pow(W/T, 2); |
| 196 | + double k1 = -0.2434 - 0.3939*H/T + 0.1536*std::pow(H/T, 2) + 0.3004*W/T - 0.0995*std::pow(W/T, 2); |
| 197 | + double Mk = c1*std::pow(a/T, k1); |
| 198 | + double Mm = (1.04 + 0.202*std::pow(a/T, 2) - 0.106*std::pow(a/T, 4))/2.464; |
| 199 | + double Mb = (1.0 - 1.34*a/T - 0.03*std::pow(a/T, 2))*Mm; |
| 200 | + double Y = fw*Mk*Mm; |
| 201 | + ΔK.at(i) = Y * Δσ.at(i) * std::sqrt(π * a); |
| 202 | + if (ΔK.at(i) >= ΔKth) { |
| 203 | + double Δa = c.at(i)*C*std::pow(ΔK.at(i), m); |
| 204 | + a += Δa; |
| 205 | + } |
| 206 | + if (i < Δσ.size() - 1) { |
| 207 | + ++i; |
| 208 | + } |
| 209 | + else { |
| 210 | + if (ΔK.max() < ΔKth) return { dfl, "ΔK < ΔK_th" }; |
| 211 | + ++N; |
| 212 | + i = 0; |
| 213 | + } |
| 214 | + rfl = sampledTimePeriod*N; |
| 215 | + } |
| 216 | + } |
| 217 | + throw std::logic_error("Not implemented."); |
| 218 | +} |
0 commit comments