Skip to content

Commit 169d866

Browse files
committed
Update.
1 parent e6e85ea commit 169d866

14 files changed

Lines changed: 516 additions & 37 deletions

FAT-SM.vcxproj

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,7 @@
128128
<ClCompile Include="Source\Gui\MainWindow.cpp" />
129129
<ClCompile Include="Source\Gui\ParisLawTab.cpp" />
130130
<ClCompile Include="Source\Gui\RainflowTab.cpp" />
131+
<ClCompile Include="Source\Gui\RemainingLifeTab.cpp" />
131132
<ClCompile Include="Source\Gui\SnCurveTab.cpp" />
132133
<ClCompile Include="Source\Model\Detail.cpp" />
133134
<ClCompile Include="Source\Model\Project.cpp" />
@@ -173,6 +174,7 @@
173174
<QtMoc Include="Source\Gui\DamageTab.hpp" />
174175
<QtMoc Include="Source\Gui\DetailSelectionTab.hpp" />
175176
<QtMoc Include="Source\Gui\ParisLawTab.hpp" />
177+
<QtMoc Include="Source\Gui\RemainingLifeTab.hpp" />
176178
<ClInclude Include="Source\Model.hpp" />
177179
<QtMoc Include="Source\Model\Project.hpp" />
178180
<QtMoc Include="Source\Model\LefmDetail.hpp" />

FAT-SM.vcxproj.filters

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,9 @@
7575
<ClCompile Include="Source\Gui\ParisLawTab.cpp">
7676
<Filter>Source\Gui</Filter>
7777
</ClCompile>
78+
<ClCompile Include="Source\Gui\RemainingLifeTab.cpp">
79+
<Filter>Source\Gui</Filter>
80+
</ClCompile>
7881
</ItemGroup>
7982
<ItemGroup>
8083
<None Include=".gitignore" />
@@ -182,6 +185,9 @@
182185
<QtMoc Include="Source\Gui\ParisLawTab.hpp">
183186
<Filter>Source\Gui</Filter>
184187
</QtMoc>
188+
<QtMoc Include="Source\Gui\RemainingLifeTab.hpp">
189+
<Filter>Source\Gui</Filter>
190+
</QtMoc>
185191
</ItemGroup>
186192
<ItemGroup>
187193
<QtRcc Include="Resource\Resource.qrc">

Resource/StyleSheets/NavBar.qss

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,12 @@ QListWidget::item {
1616
}
1717

1818
QListWidget::item:selected {
19-
color: #FFFFFF;
20-
background-color: #006CD9;
19+
color: #000000;
20+
border: 1px solid black;
21+
background-color: #E6E6E6;
2122
}
2223

2324
QListWidget::item:hover:!selected {
2425
color: #000000;
25-
background-color: #F0F0F0;
26+
background-color: #E6E6E6;
2627
}

Source/Core/Matrix.cpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
#include <string>
22
#include <QString>
3+
#include <algorithm>
34
#include <stdexcept>
45
#include "Core/Matrix.hpp"
56

@@ -55,6 +56,21 @@ const T& Matrix<T>::at(int i, int j) const {
5556
return _data[i*_columnCount + j];
5657
}
5758

59+
template<typename T>
60+
T& Matrix<T>::max() {
61+
if (_data.empty()) throw std::runtime_error("Empty matrix.");
62+
return *std::max_element(_data.begin(), _data.end());
63+
}
64+
65+
template<typename T>
66+
const T& Matrix<T>::max() const {
67+
if (_data.empty()) throw std::runtime_error("Empty matrix.");
68+
return *std::max_element(_data.begin(), _data.end());
69+
}
70+
71+
template<typename T>
72+
int Matrix<T>::size() const { return _rowCount*_columnCount; }
73+
5874
template<typename T>
5975
int Matrix<T>::rowCount() const { return _rowCount; }
6076

Source/Core/Matrix.hpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,10 +33,17 @@ class Matrix {
3333
T& at(int k);
3434
const T& at(int k) const;
3535

36+
/* Returns the maximum value in the matrix. */
37+
T& max();
38+
const T& max() const;
39+
3640
/* Access to the matrix value at the i-th row and j-th column. */
3741
T& at(int i, int j);
3842
const T& at(int i, int j) const;
3943

44+
/* Total number of elements. */
45+
int size() const;
46+
4047
/* The number of rows. */
4148
int rowCount() const;
4249

Source/Core/Utility.cpp

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
#include <tuple>
22
#include <cmath>
33
#include <limits>
4+
#include <numbers>
45
#include <stdexcept>
56
#include "Core/Utility.hpp"
67

@@ -161,3 +162,57 @@ Matrix<double> Utility::executeMinerSummation(double category, double resistance
161162
return results;
162163

163164
}
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+
}

Source/Core/Utility.hpp

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
1-
#pragma once
1+
#pragma once
22

33
#include <vector>
4+
#include <unordered_map>
45
#include <utility>
6+
#include <QtCore>
57
#include "Core/Matrix.hpp"
68

79
/* Static class of utilities. */
@@ -28,4 +30,9 @@ class Utility {
2830
static Matrix<double> executeMinerSummation(double category, double resistanceFactor, const Matrix<double>& slopes,
2931
const Matrix<double>& rainflow, double stressFactor);
3032

33+
/* Computes the remaining fatigue life of a LEFM detail. */
34+
static std::pair<double, QString> computeRemainingFatigueLife(const QString& detail,
35+
const std::unordered_map<QString, double>& parameters, const Matrix<double>& history,
36+
const Matrix<double>& rainflow, double C, double m, double ΔKth, double ΔKcr, double a0);
37+
3138
};

Source/Gui/HistoryTab.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,8 @@ void HistoryTab::buildGui() {
160160

161161
void HistoryTab::refreshGui() {
162162
if (_detail == nullptr) {
163+
_timeGroupBox->setVisible(true);
164+
_repsGroupBox->setVisible(true);
163165
_timeGroupBox->setEnabled(false);
164166
_timeUnitsBox->setEnabled(false);
165167
_repsBox->setEnabled(false);
@@ -172,6 +174,8 @@ void HistoryTab::refreshGui() {
172174
_sampleTable->setRowCount(0);
173175
_sampleTable->setColumnCount(0);
174176
} else {
177+
_timeGroupBox->setVisible(_detail->approach() != Detail::Approach::Lefm);
178+
_repsGroupBox->setVisible(_detail->approach() != Detail::Approach::Lefm);
175179
_timeGroupBox->setEnabled(true);
176180
_timeUnitsBox->setEnabled(!_detail->ignoreTime());
177181
_repsBox->setEnabled(true);

Source/Gui/MainWindow.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,11 @@ void MainWindow::buildGui() {
134134
_lefmRainflowItem->setText("Rainflow Counting");
135135
_lefmNavBar->addItem(_lefmRainflowItem);
136136

137+
// remaining life item
138+
_remainingLifeItem = new QListWidgetItem(_lefmNavBar);
139+
_remainingLifeItem->setText("Remaining Fatigue Life");
140+
_lefmNavBar->addItem(_remainingLifeItem);
141+
137142
// main stack
138143
_mainStack = new QStackedWidget(_centralWidget);
139144
_mainStack->setProperty("parent", "true");
@@ -168,6 +173,10 @@ void MainWindow::buildGui() {
168173
_parisLawTab = new ParisLawTab(_mainStack);
169174
_mainStack->addWidget(_parisLawTab);
170175

176+
// remaining life tab
177+
_remainingLifeTab = new RemainingLifeTab(_mainStack);
178+
_mainStack->addWidget(_remainingLifeTab);
179+
171180
// connections
172181
QObject::connect(_homeTab, &HomeTab::editDetailRequestReceived, this, &MainWindow::onEditDetailRequestReceived);
173182
QObject::connect(_snNavBar, &QListWidget::currentRowChanged, this, &MainWindow::onSnNavBarCurrentRowChanged);
@@ -309,5 +318,9 @@ void MainWindow::onLefmNavBarCurrentRowChanged() {
309318
_mainStack->setCurrentWidget(_rainflowTab);
310319
_rainflowTab->setDetail(_detail);
311320
}
321+
else if (_lefmNavBar->currentItem() == _remainingLifeItem) {
322+
_mainStack->setCurrentWidget(_remainingLifeTab);
323+
_remainingLifeTab->setDetail(dynamic_cast<LefmDetail*>(_detail));
324+
}
312325

313326
}

Source/Gui/MainWindow.hpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
#include "Gui/DamageTab.hpp"
1212
#include "Gui/DetailSelectionTab.hpp"
1313
#include "Gui/ParisLawTab.hpp"
14+
#include "Gui/RemainingLifeTab.hpp"
1415

1516
/* The main window of the application. */
1617
class MainWindow : public QMainWindow {
@@ -43,6 +44,7 @@ class MainWindow : public QMainWindow {
4344
QListWidgetItem* _parisLawItem;
4445
QListWidgetItem* _lefmHistoryItem;
4546
QListWidgetItem* _lefmRainflowItem;
47+
QListWidgetItem* _remainingLifeItem;
4648
QStackedWidget* _mainStack;
4749
HomeTab* _homeTab;
4850
SnCurveTab* _snCurveTab;
@@ -51,6 +53,7 @@ class MainWindow : public QMainWindow {
5153
DamageTab* _damageTab;
5254
DetailSelectionTab* _detailSelectionTab;
5355
ParisLawTab* _parisLawTab;
56+
RemainingLifeTab* _remainingLifeTab;
5457
Module _module;
5558
Project* _project;
5659
Detail* _detail;

0 commit comments

Comments
 (0)