Skip to content

Commit 6f6c96c

Browse files
committed
Fixed shear flow for zero N and M,
incorporated version check, validity check of geometry thickness, wall length and clockwise def.
1 parent a97b90d commit 6f6c96c

7 files changed

Lines changed: 150 additions & 65 deletions

File tree

Analysis.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -421,20 +421,21 @@ def dualSection(section, SF, Mat):
421421
dx = 0.001 # [m] Offset
422422
SF2 = SectionForces.SectionForces(SF.N, SF.Mx + dx * SF.Vy, SF.My - dx * SF.Vx)
423423
# SF2 = prep_dual_section(SF, dx) # nabouring SF
424-
424+
425425
# --------------- Optimize plane strain variables for the secondary section ---------------
426426
opt2 = nlopt.opt(nlopt.LN_NELDERMEAD, len(x))
427427
opt2.set_min_objective(lambda x, grad: errorFunBending(x, section, SF2, Mat))
428428
opt2.set_xtol_rel(1e-8)
429-
x2 = opt2.optimize(x)
429+
x0 = [0 if abs(x)<1e-6 else x for x in x0] # the initial guess may not contain extremely small values such as 3e-169
430+
x2 = opt2.optimize(x0)
430431
print("Optimized strain state2 =", x2)
431432
print("Minimized error2 value = ", opt.last_optimum_value())
432433

433434
# --------------- Shear flow - Counter-clockwise shear flow is positive ---------------
434435
_, dist = BendingEQ(section, Mat, x[0], x[1], x[2]) # get distributions from first section
435436
_, dist2 = BendingEQ(section, Mat, x2[0], x2[1], x2[2]) # get distributions from first section
436437
H = shear_flow(dist, dist2, SF, section, dx)
437-
438+
438439
# --------------- SLS verification ---------------
439440
# Disk stress components
440441
theta, sigma_c, sigma_sx, sigma_sy = [], [], [], []

MyMainWindow.py renamed to AppWindows.py

Lines changed: 64 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
# -*- coding: utf-8 -*-
22
"""
3-
MainWindow class for the "Hollow section analysis tool" GUI
4-
5-
Script defining the MainWindow class including functions for any interactive element
3+
This module containes all the application window classes for the "Hollow section analysis tool" GUI
64
75
History log:
86
Version 0.1 - first working build based on UI from Qt Designer
@@ -25,15 +23,19 @@
2523
import Material
2624
import Results
2725
import Geometry
28-
#import TableInterface
2926
import pickle
27+
#import TableInterface
3028

31-
class MyMainWindow(QtWidgets.QMainWindow, design.Ui_MainWindow): # PyQt5 compatible
29+
class HollowRCWindow(QtWidgets.QMainWindow, design.Ui_MainWindow): # PyQt5 compatible
3230
def __init__(self):
3331
super().__init__() # initialize the QMainWindow parent object from the Qt Designer file
3432
self.setupUi(self) # setup layout and widgets defined in design.py by Qt Designer
3533
#self.geometry_table = TableInterface.MyTable(self.coordinates_tableWidget)
3634

35+
# version tag and label
36+
self.tag = 'v1.1'
37+
self.label_version.setText(self.tag)
38+
3739
# --- Triggers --- (interactive elements such as actions and buttons with a custom function)
3840
self.exitAct.triggered.connect(self.exit_app)
3941
self.saveAct.triggered.connect(self.save_file)
@@ -83,6 +85,11 @@ def __init__(self):
8385
viewStatusAct.setChecked(True)
8486
viewStatusAct.triggered.connect(self.toggle_menu)
8587
viewMenu.addAction(viewStatusAct)
88+
89+
aboutMenu = self.menuBar().addMenu('About')
90+
aboutVersionAct = QtWidgets.QAction('Check version', self)
91+
aboutVersionAct.triggered.connect(self.version_check)
92+
aboutMenu.addAction(aboutVersionAct)
8693

8794
# Correcting QT Designer bug sometimes making table headers invisible
8895
self.coordinates_tableWidget.horizontalHeader().setVisible(True) # show horizontal header in Geometry table
@@ -100,6 +107,9 @@ def __init__(self):
100107
# make sure to start at first tab (overrules Qt designer)
101108
self.tabWidget.setCurrentIndex(0)
102109

110+
# check if version is up-to-date
111+
# self.version_check()
112+
103113
def tab_changed(self): # signal function
104114
if self.checkBox_analSLS_1.isChecked():
105115
self.pushButton_analyse.setText('Analyse SLS')
@@ -127,10 +137,6 @@ def refresh_plots(self): # signal/normal function
127137
except:
128138
None
129139

130-
def not_yet_implemented_popup(self):
131-
msg_string = 'This feature has not yet men implemented'
132-
self.show_msg_box(msg_string)
133-
134140
def save_file(self):
135141
try: # try to save file
136142
openfile = QtWidgets.QFileDialog.getSaveFileName(filter='*.pkj') # save file dialog
@@ -167,21 +173,24 @@ def load_file(self):
167173
print(e)
168174
self.show_msg_box('Failed to open file')
169175

170-
def show_msg_box(self, info_str):
176+
def show_msg_box(self, msg_str, title="Error Message", set_load_fac_label=False):
171177
msg = QtWidgets.QMessageBox()
172178
msg.setIcon(QtWidgets.QMessageBox.Information)
173179

174-
msg.setWindowTitle("Error Message")
175-
if isinstance(info_str, str):
176-
msg.setText(info_str)
177-
self.load_fac_label.setText(info_str)
178-
elif isinstance(info_str, list):
179-
msg.setText(info_str[0])
180-
print(info_str)
181-
self.load_fac_label.setText(info_str[0])
182-
if len(info_str) > 1:
183-
msg.setInformativeText(info_str[1])
184-
self.load_fac_label.setText(info_str[0]+' '+info_str[1])
180+
msg.setWindowTitle(title)
181+
if isinstance(msg_str, str):
182+
msg.setText(msg_str)
183+
if set_load_fac_label:
184+
self.load_fac_label.setText(msg_str)
185+
elif isinstance(msg_str, list): # if a list
186+
msg.setText(msg_str[0]) # set text in msg box
187+
print(msg_str)
188+
if set_load_fac_label:
189+
self.load_fac_label.setText(msg_str[0]) # update label
190+
if len(msg_str) > 1:
191+
msg.setInformativeText(msg_str[1]) # set info text
192+
if set_load_fac_label:
193+
self.load_fac_label.setText(msg_str[0] + ' ' + msg_str[1])
185194

186195
# msg.setDetailedText("The details are as follows: ")
187196
msg.setStandardButtons(QtWidgets.QMessageBox.Ok)
@@ -202,6 +211,13 @@ def initiate_analysis(self):
202211
SF = self.getSF()
203212
Mat = self.getMaterial()
204213

214+
# check if geometry is valid
215+
if not section.valid():
216+
self.show_msg_box(['Geometry error', 'The defined geometry is not valid'])
217+
self.Res = None
218+
self.refresh_plots()
219+
return
220+
205221
# print(Geometry)
206222
print('SF: ' + SF.print_str())
207223

@@ -224,7 +240,7 @@ def initiate_analysis(self):
224240

225241
# Show message
226242
if error_msg:
227-
self.show_msg_box(error_msg)
243+
self.show_msg_box(error_msg, set_load_fac_label=True)
228244
else:
229245
self.load_fac_label.setText('No load-factor currently applied')
230246

@@ -809,6 +825,32 @@ def closeEvent(self, event): # reimplementing the QWidget closeEvent() event ha
809825
else:
810826
event.ignore()
811827

828+
def version_check(self):
829+
# This method retreivings the latest release version from GitHub
830+
import requests
831+
r = requests.get('https://api.github.com/repos/Kleissl/HollowRC/releases/latest')
832+
# print(r)
833+
if r.status_code == 200:
834+
# print(r.headers['content-type'])
835+
data = r.json()
836+
# print(data.keys())
837+
# for key in data:
838+
# print(key, 'corresponds to', data[key])
839+
latest_tag = data['tag_name']
840+
published = data['published_at']
841+
print('The latest release (' + latest_tag +') was published at ' + published)
842+
if latest_tag == self.tag:
843+
print('version up-to-date')
844+
msg_str = 'version up-to-date'
845+
msg_info_str = 'The current version ('+ self.tag +') matches the latest release'
846+
else:
847+
msg_str = 'The application ('+ self.tag +') is NOT up-to-date!'
848+
msg_info_str = 'There is a newer release (' + latest_tag + ') from ' + published + ' available for download at https://github.com/Kleissl/HollowRC/releases/latest'
849+
print(msg_str)
850+
self.show_msg_box([msg_str, msg_info_str], title='Information')
851+
else:
852+
print('Github API requests returned statuscode', r.status_code)
853+
812854
# # Creating my own GraphicsScene class so I can overwrite its mousePressEvent
813855
# class MyGraphicsScene(QtWidgets.QGraphicsScene):
814856
# def __init__(self, parent=None):

Geometry.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,20 @@ def get_e(self, local_data=False):
133133
else:
134134
return e
135135

136+
def valid(self):
137+
for T in self.get_thick():
138+
if T <= 0:
139+
print('Negative or zero wall thickness!')
140+
return False
141+
for L in self.get_wallLength():
142+
if L <= 0:
143+
print('Negative or zero wall length!')
144+
return False
145+
if self.get_enclosed_area() > 0: # note that the correct clockwise definition yields a negative enclosed area
146+
print('Counter-clockwise definition of cross-section!')
147+
return False
148+
return True
149+
136150
# Second Moment of Area
137151
#Ix.append(wallLength[i]*T[i]/12 * ( wallLength[i]**2 * math.cos(wallAngle[i])**2 + T[i]**2 * math.sin(wallAngle[i])**2 ))
138152
#Ix.append(wallLength[i] * T[i] / 12 * (

convert_ui.bat

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
"C:\Users\Kenneth\Anaconda3\Library\bin\pyside2-uic.bat" -x design.ui -o design.py
22
"C:\Users\kekl\Anaconda3\Library\bin\pyside2-uic.bat" -x design.ui -o design.py
33
"C:\Program Files (x86)\Python37-32\Scripts\pyside2-uic.exe" -x design.ui -o design.py
4+
"C:\Users\kekl\AppData\Local\Programs\Python\Python37-32\Scripts\pyside2-uic.exe" -x design.ui -o design.py
45
pause

design.py

Lines changed: 27 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
# Form implementation generated from reading ui file 'design.ui',
44
# licensing of 'design.ui' applies.
55
#
6-
# Created: Tue Nov 6 21:55:00 2018
6+
# Created: Thu Jan 17 20:10:14 2019
77
# by: pyside2-uic running on PySide2 5.11.2
88
#
99
# WARNING! All changes made in this file will be lost!
@@ -74,7 +74,7 @@ def setupUi(self, MainWindow):
7474
self.label_31.setWordWrap(True)
7575
self.label_31.setObjectName("label_31")
7676
self.label_33 = QtWidgets.QLabel(self.tab)
77-
self.label_33.setGeometry(QtCore.QRect(10, 10, 751, 31))
77+
self.label_33.setGeometry(QtCore.QRect(10, 10, 521, 31))
7878
font = QtGui.QFont()
7979
font.setPointSize(12)
8080
font.setWeight(75)
@@ -99,6 +99,13 @@ def setupUi(self, MainWindow):
9999
self.label_38 = QtWidgets.QLabel(self.tab)
100100
self.label_38.setGeometry(QtCore.QRect(930, 450, 111, 101))
101101
self.label_38.setObjectName("label_38")
102+
self.label_version = QtWidgets.QLabel(self.tab)
103+
self.label_version.setGeometry(QtCore.QRect(20, 630, 61, 31))
104+
font = QtGui.QFont()
105+
font.setPointSize(9)
106+
font.setItalic(True)
107+
self.label_version.setFont(font)
108+
self.label_version.setObjectName("label_version")
102109
self.tabWidget.addTab(self.tab, "")
103110
self.tab_geometry = QtWidgets.QWidget()
104111
self.tab_geometry.setObjectName("tab_geometry")
@@ -731,6 +738,7 @@ def retranslateUi(self, MainWindow):
731738
self.label_36.setText(QtWidgets.QApplication.translate("MainWindow", "<html><head/><body><p><img src=\":/Figures/coordinates.PNG\"/></p></body></html>", None, -1))
732739
self.label_37.setText(QtWidgets.QApplication.translate("MainWindow", "<html><head/><body><p><img src=\":/Figures/force_sign_convention.PNG\"/></p></body></html>", None, -1))
733740
self.label_38.setText(QtWidgets.QApplication.translate("MainWindow", "<html><head/><body><p><img src=\":/Figures/moment_sign_convention.PNG\"/></p></body></html>", None, -1))
741+
self.label_version.setText(QtWidgets.QApplication.translate("MainWindow", "v1.0", None, -1))
734742
self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab), QtWidgets.QApplication.translate("MainWindow", "About", None, -1))
735743
self.label.setText(QtWidgets.QApplication.translate("MainWindow", "Define starting coordinates and properties of each wall element here:", None, -1))
736744
self.coordinates_tableWidget.setSortingEnabled(False)
@@ -746,24 +754,24 @@ def retranslateUi(self, MainWindow):
746754
__sortingEnabled = self.coordinates_tableWidget.isSortingEnabled()
747755
self.coordinates_tableWidget.setSortingEnabled(False)
748756
self.coordinates_tableWidget.item(0, 0).setText(QtWidgets.QApplication.translate("MainWindow", "0", None, -1))
749-
self.coordinates_tableWidget.item(0, 1).setText(QtWidgets.QApplication.translate("MainWindow", "2250", None, -1))
750-
self.coordinates_tableWidget.item(0, 2).setText(QtWidgets.QApplication.translate("MainWindow", "400", None, -1))
751-
self.coordinates_tableWidget.item(0, 3).setText(QtWidgets.QApplication.translate("MainWindow", "0.013", None, -1))
757+
self.coordinates_tableWidget.item(0, 1).setText(QtWidgets.QApplication.translate("MainWindow", "2000", None, -1))
758+
self.coordinates_tableWidget.item(0, 2).setText(QtWidgets.QApplication.translate("MainWindow", "300", None, -1))
759+
self.coordinates_tableWidget.item(0, 3).setText(QtWidgets.QApplication.translate("MainWindow", "0.01", None, -1))
752760
self.coordinates_tableWidget.item(0, 4).setText(QtWidgets.QApplication.translate("MainWindow", "0.01", None, -1))
753-
self.coordinates_tableWidget.item(1, 0).setText(QtWidgets.QApplication.translate("MainWindow", "4000", None, -1))
754-
self.coordinates_tableWidget.item(1, 1).setText(QtWidgets.QApplication.translate("MainWindow", "2250", None, -1))
755-
self.coordinates_tableWidget.item(1, 2).setText(QtWidgets.QApplication.translate("MainWindow", "400", None, -1))
756-
self.coordinates_tableWidget.item(1, 3).setText(QtWidgets.QApplication.translate("MainWindow", "0.013", None, -1))
761+
self.coordinates_tableWidget.item(1, 0).setText(QtWidgets.QApplication.translate("MainWindow", "1500", None, -1))
762+
self.coordinates_tableWidget.item(1, 1).setText(QtWidgets.QApplication.translate("MainWindow", "2000", None, -1))
763+
self.coordinates_tableWidget.item(1, 2).setText(QtWidgets.QApplication.translate("MainWindow", "200", None, -1))
764+
self.coordinates_tableWidget.item(1, 3).setText(QtWidgets.QApplication.translate("MainWindow", "0.01", None, -1))
757765
self.coordinates_tableWidget.item(1, 4).setText(QtWidgets.QApplication.translate("MainWindow", "0.01", None, -1))
758-
self.coordinates_tableWidget.item(2, 0).setText(QtWidgets.QApplication.translate("MainWindow", "4000", None, -1))
766+
self.coordinates_tableWidget.item(2, 0).setText(QtWidgets.QApplication.translate("MainWindow", "1500", None, -1))
759767
self.coordinates_tableWidget.item(2, 1).setText(QtWidgets.QApplication.translate("MainWindow", "0", None, -1))
760-
self.coordinates_tableWidget.item(2, 2).setText(QtWidgets.QApplication.translate("MainWindow", "400", None, -1))
761-
self.coordinates_tableWidget.item(2, 3).setText(QtWidgets.QApplication.translate("MainWindow", "0.013", None, -1))
768+
self.coordinates_tableWidget.item(2, 2).setText(QtWidgets.QApplication.translate("MainWindow", "300", None, -1))
769+
self.coordinates_tableWidget.item(2, 3).setText(QtWidgets.QApplication.translate("MainWindow", "0.01", None, -1))
762770
self.coordinates_tableWidget.item(2, 4).setText(QtWidgets.QApplication.translate("MainWindow", "0.01", None, -1))
763771
self.coordinates_tableWidget.item(3, 0).setText(QtWidgets.QApplication.translate("MainWindow", "0", None, -1))
764772
self.coordinates_tableWidget.item(3, 1).setText(QtWidgets.QApplication.translate("MainWindow", "0", None, -1))
765-
self.coordinates_tableWidget.item(3, 2).setText(QtWidgets.QApplication.translate("MainWindow", "400", None, -1))
766-
self.coordinates_tableWidget.item(3, 3).setText(QtWidgets.QApplication.translate("MainWindow", "0.013", None, -1))
773+
self.coordinates_tableWidget.item(3, 2).setText(QtWidgets.QApplication.translate("MainWindow", "200", None, -1))
774+
self.coordinates_tableWidget.item(3, 3).setText(QtWidgets.QApplication.translate("MainWindow", "0.01", None, -1))
767775
self.coordinates_tableWidget.item(3, 4).setText(QtWidgets.QApplication.translate("MainWindow", "0.01", None, -1))
768776
self.coordinates_tableWidget.setSortingEnabled(__sortingEnabled)
769777
self.addRowButton.setToolTip(QtWidgets.QApplication.translate("MainWindow", "Insert new row at the bottom", None, -1))
@@ -820,11 +828,11 @@ def retranslateUi(self, MainWindow):
820828
self.SectionForces_tableWidget.horizontalHeaderItem(5).setText(QtWidgets.QApplication.translate("MainWindow", "T [kNm]", None, -1))
821829
__sortingEnabled = self.SectionForces_tableWidget.isSortingEnabled()
822830
self.SectionForces_tableWidget.setSortingEnabled(False)
823-
self.SectionForces_tableWidget.item(0, 0).setText(QtWidgets.QApplication.translate("MainWindow", "-38000", None, -1))
824-
self.SectionForces_tableWidget.item(0, 1).setText(QtWidgets.QApplication.translate("MainWindow", "0", None, -1))
825-
self.SectionForces_tableWidget.item(0, 2).setText(QtWidgets.QApplication.translate("MainWindow", "50000", None, -1))
826-
self.SectionForces_tableWidget.item(0, 3).setText(QtWidgets.QApplication.translate("MainWindow", "5000", None, -1))
827-
self.SectionForces_tableWidget.item(0, 4).setText(QtWidgets.QApplication.translate("MainWindow", "0", None, -1))
831+
self.SectionForces_tableWidget.item(0, 0).setText(QtWidgets.QApplication.translate("MainWindow", "-15000", None, -1))
832+
self.SectionForces_tableWidget.item(0, 1).setText(QtWidgets.QApplication.translate("MainWindow", "20000", None, -1))
833+
self.SectionForces_tableWidget.item(0, 2).setText(QtWidgets.QApplication.translate("MainWindow", "0", None, -1))
834+
self.SectionForces_tableWidget.item(0, 3).setText(QtWidgets.QApplication.translate("MainWindow", "0", None, -1))
835+
self.SectionForces_tableWidget.item(0, 4).setText(QtWidgets.QApplication.translate("MainWindow", "5000", None, -1))
828836
self.SectionForces_tableWidget.item(0, 5).setText(QtWidgets.QApplication.translate("MainWindow", "0", None, -1))
829837
self.SectionForces_tableWidget.setSortingEnabled(__sortingEnabled)
830838
self.load_fac_label.setText(QtWidgets.QApplication.translate("MainWindow", "No load-factor currently applied", None, -1))

0 commit comments

Comments
 (0)