1 """Copyright (C) 2016 Joakim A. Taby 3 This program is free software: you can redistribute it and/or modify 4 it under the terms of the GNU General Public License as published by 5 the Free Software Foundation, either version 3 of the License. 7 This program is distributed in the hope that it will be useful, 8 but WITHOUT ANY WARRANTY; without even the implied warranty of 9 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10 GNU General Public License for more details. 12 You should have received a copy of the GNU General Public License 13 along with this program. If not, see <http://www.gnu.org/licenses/>.""" 22 from PySide
import QtGui, QtCore
24 matplotlib.rcParams[
'backend.qt4'] =
"PySide" 26 from matplotlib.backends.backend_qt4agg
import (
27 FigureCanvasQTAgg
as FigureCanvas,
28 NavigationToolbar2QT
as NavigationToolbar)
35 """Module for handling time series""" 40 Defining a time series object 44 def __init__(self, time_filename, histname, directory=None):
51 if directory
is not None:
54 if directory
is not None:
61 Reads in a tim file or directory and retusnrs it 62 :param directory: The directory where the file is located 63 :return: The time history in a matrix as follows: [Time Tension Curvy Curvz] X nsteps 66 headercheck = fid.readline() 67 headercheck = headercheck.lower() 68 if headercheck[:3] ==
'# #':
69 tdict = dict(timeindex=headercheck.find(
'time'),
70 tensionindex=headercheck.find(
'tension'),
71 curvyindex=headercheck.find(
'curvy'),
72 curvzindex=headercheck.find(
'curvz'),
73 p_intindex=headercheck.find(
'p_int'),
74 p_extindex=headercheck.find(
'p_ext'))
75 sorted_dict = sorted(tdict.items(), key=operator.itemgetter(1))
77 for i
in range(len(sorted_dict)):
78 dictionary[sorted_dict[i][0]] = i
80 dictionary = dict(timeindex=0,
86 unsorted = np.loadtxt(directory +
'/' + self.
timeFileName)
87 timehist = np.zeros([len(unsorted[:, 0]), 6])
88 timehist[:, 0] = unsorted[:, dictionary[
'timeindex']]
89 timehist[:, 1] = unsorted[:, dictionary[
'tensionindex']]
90 timehist[:, 2] = unsorted[:, dictionary[
'curvyindex']]
91 timehist[:, 3] = unsorted[:, dictionary[
'curvzindex']]
92 timehist[:, 4] = unsorted[:, dictionary[
'p_intindex']]
93 timehist[:, 5] = unsorted[:, dictionary[
'p_extindex']]
99 Method for plotting itself onto the parent widget. 100 :param parent:A widget where the canvas will be placed 102 fig = matplotlib.figure.Figure()
103 self.
canvas = FigureCanvas(fig)
104 ax1 = fig.add_subplot(211)
106 ax1.set_title(
'Tension')
107 ax2 = fig.add_subplot(212)
109 ax2.set_title(
'Curvatures')
110 fig.suptitle(
'Time series %s' % str(self.
name))
113 temp = QtGui.QWidget()
114 templayout = QtGui.QVBoxLayout()
115 temp.setLayout(templayout)
117 templayout.addWidget(self.
canvas)
118 parent.addTab(temp,
'Plot of %s' % str(self.
name))
119 parent.setCurrentWidget(temp)
123 """Class for holding data for friction calculations""" 164 """ Adding/changing a timeseries obviously. 165 :param ts: A time series 171 Setting up a widget where the input to the friction calculation will be shown. 172 Needs to be placed into the application on the outside to be shown. 173 :param window: The main window of the application. Adds itself to it and uses its eventfilter only. 177 self.mainwidget.setAcceptDrops(
True)
178 self.mainwidget.installEventFilter(window)
179 mainlayout = QtGui.QVBoxLayout()
180 mainlayout.setObjectName(
'mainlayout')
181 self.mainwidget.setLayout(mainlayout)
182 frictiontitle = QtGui.QLabel(
'<H1> Friction calculations </H1>')
183 mainlayout.addWidget(frictiontitle)
186 tslayout = QtGui.QGridLayout()
187 tslayout.setObjectName(
'tslayout')
188 header_name = QtGui.QLabel(
'Name')
189 tslayout.addWidget(header_name, 1, 0)
190 header_starttime = QtGui.QLabel(
'Start time')
191 tslayout.addWidget(header_starttime, 1, 1, columnSpan=2)
192 header_stoptime = QtGui.QLabel(
'Stop time')
193 tslayout.addWidget(header_stoptime, 1, 3, columnSpan=2)
194 use_constant_tension = QtGui.QCheckBox(
'Use constant tension')
195 use_constant_tension.setObjectName(
'use_constant_tension')
196 use_constant_tension.setToolTip(
'From scenario definition')
197 if not hasattr(window.tree_model.slenderdata,
'typical_tension'):
198 use_constant_tension.setEnabled(
False)
199 tslayout.addWidget(use_constant_tension, 0, 1)
200 use_constant_curvature = QtGui.QCheckBox(
'Use constant curvature')
201 use_constant_curvature.setObjectName(
'use_constant_curvature')
202 use_constant_curvature.setToolTip(
'From scenario definition')
203 if not hasattr(window.tree_model.slenderdata,
'typical_curvature'):
204 use_constant_curvature.setEnabled(
False)
205 tslayout.addWidget(use_constant_curvature, 0, 2)
206 mainlayout.addLayout(tslayout)
208 dragdrop = QtGui.QLabel(
'<font color="grey">Drag and drop time series here</font>')
209 dragdrop.setObjectName(
'dragdrop')
210 mainlayout.addWidget(dragdrop)
212 calcbutton = QtGui.QPushButton(
'Calculate')
213 calcbutton.setObjectName(
'calcbutton')
214 calcbutton.setEnabled(
False)
215 mainlayout.addWidget(calcbutton)
216 calcbutton.clicked.connect(window.calculate_friction)
220 Setting up the widget for editing the timeseries. Called when a time series is dropped. 225 self.
stopTime = self.timehist.timehist[-1, 0]
226 self.
startTime = self.timehist.timehist[0, 0]
227 tslayout = self.mainwidget.findChild(QtGui.QGridLayout,
'tslayout')
228 if not hasattr(tslayout,
'made'):
229 label = QtGui.QLabel(self.timehist.name)
230 label.setObjectName(
'label')
231 tslayout.addWidget(label, rows, 0)
233 label = self.mainwidget.findChild(QtGui.QLabel,
'label')
234 label.setText(self.timehist.name)
237 if not hasattr(tslayout,
'made'):
238 self.
startSlider = QtGui.QSlider(QtCore.Qt.Horizontal)
240 self.startSlider.setRange(self.
startTime,
243 if not hasattr(tslayout,
'made'):
246 self.startSpinbox.setRange(self.
startTime,
251 if not hasattr(tslayout,
'made'):
252 self.
endSlider = QtGui.QSlider(QtCore.Qt.Horizontal)
253 tslayout.addWidget(self.
endSlider, rows, 3)
256 if not hasattr(tslayout,
'made'):
264 self.endSlider.setValue(self.
stopTime)
265 self.endSpinbox.setValue(self.
stopTime)
266 calcbutton = self.mainwidget.findChild(QtGui.QPushButton,
'calcbutton')
267 calcbutton.setEnabled(
True)
272 Calculates stress time histories based on given timehistory and model. 273 :param model:A model of slenders.Slender type 282 use_constant_curvature = self.mainwidget.findChild(QtGui.QCheckBox,
'use_constant_curvature')
283 if use_constant_curvature.isChecked():
284 curv = np.array([[model.typical_curvature, 0.0]])
289 curv = np.transpose(curv)
303 for i
in all_bend_stress:
304 i = np.reshape(i, (-1, ntheta, i.shape[-1]))
305 all_bend_stddev = np.std(i, axis=0)
306 self.bendStddev.append(np.amax(np.amax(all_bend_stddev)))
307 self.bendMax.append(np.amax(np.amax(np.amax(i))))
308 self.bendMin.append(np.amin(np.amin(np.amin(i))))
309 tmp = np.unravel_index(all_bend_stddev.argmax(), all_bend_stddev.shape)
310 self.mainwidget.findChild(QtGui.QCheckBox,
'use_constant_curvature')
311 if use_constant_curvature.isChecked():
312 self.bendStress.append(self.
bendMax)
314 self.bendStress.append(i[:, tmp[0], tmp[1]])
315 thetaindex.append(tmp[0])
316 theta.append(tmp[0] * 2 * np.pi / ntheta)
318 phiindex.append(tmp[1])
319 print(
'Contact pressures calculated by analytical means')
320 use_constant_tension = self.mainwidget.findChild(QtGui.QCheckBox,
'use_constant_tension')
321 if use_constant_tension.isChecked():
322 self.
tension = np.array([model.typical_tension])
328 alpha=model.lay_angle
330 thick=model.thickness
332 E=model.youngs_modulus
336 tendonstress,_,_,model.contPress=
axisymmetric.solver(np.asarray(model.layer_type),np.asarray(model.layer_radii),
337 np.asarray(model.thickness), np.asarray(model.width),
338 np.asarray(model.tendon_area),
339 np.asarray(model.lay_angle), np.asarray(model.comp_number),
340 np.asarray(model.youngs_modulus),
341 np.asarray(model.poisson),
342 np.asarray(model.gap_ini),
343 model.intpresslayer-1, model.extpresslayer-1,
344 np.asarray(t_eff), np.asarray(p_int),np.asarray(p_ext))
350 for i
in range(len(model.layer_radii)):
351 self.axialStress.append(tendonstress[:,i])
357 frictionfactors=np.array(model.fricfac))
368 self.stickStddev.append(np.std(i, axis=0))
369 self.stickMax.append(np.amax(i))
370 self.stickMin.append(-np.amax(i))
374 Plotting the calculated results 376 :param parent: Where the plot should plot itself 378 fig = matplotlib.figure.Figure()
379 self.
canvas = FigureCanvas(fig)
380 self.canvas.setFocusPolicy(QtCore.Qt.StrongFocus)
381 self.canvas.setFocus()
382 self.canvas.ax1 = fig.add_subplot(111)
383 self.canvas.ax1.set_xlabel(
'Time')
384 self.canvas.ax1.set_ylabel(
'Stress')
388 use_constant_curvature = self.mainwidget.findChild(QtGui.QCheckBox,
'use_constant_curvature')
389 if use_constant_curvature.isChecked():
392 label=(
'Bend stress for the %d th layer' % (i + 1)))
394 self.canvas.ax1.plot(self.
time,
396 label=(
'Bend stress for the %d th layer' % (i + 1)))
397 if use_constant_curvature.isChecked():
400 label=(
'Stick stress for the %d th layer' % (i + 1)))
402 self.canvas.ax1.plot(self.
time,
404 label=(
'Stick stress for the %d th layer' % (i + 1)))
405 use_constant_tension = self.mainwidget.findChild(QtGui.QCheckBox,
'use_constant_tension')
406 if use_constant_tension.isChecked():
409 label=(
'Axial stress for the %d th layer' % (i + 1)))
411 self.canvas.ax1.plot(self.
time,
413 label=(
'Axial stress for the %d th layer' % (i + 1)))
414 self.canvas.ax1.legend(loc=
'best')
415 self.canvas.ax1.set_title(
'Stress components')
416 fig.subplots_adjust(left=0.1, right=0.97, top=0.9, bottom=0.2)
418 self.canvas.mpl_connect(
'key_press_event', self.
on_key_press, )
419 button_widget = QtGui.QToolButton()
421 self.mpl_toolbar.addWidget(button_widget)
422 temp = QtGui.QWidget()
423 templayout = QtGui.QVBoxLayout()
424 temp.setLayout(templayout)
426 templayout.addWidget(self.
canvas)
428 tabs = parent.count()
430 for index
in range(tabs):
431 text = parent.tabText(index)
432 if text ==
'Plot of stresses from friction calculations':
433 widget = parent.widget(index)
434 parent.removeTab(index)
439 parent.addTab(temp,
'Plot of stresses from friction calculations')
440 parent.setCurrentIndex(tabs)
443 parent.insertTab(index, temp,
'Plot of stresses from friction calculations')
444 parent.setCurrentIndex(index)
448 Wrapper for custom toolbar. 449 implement the default mpl key press events described at 450 http://matplotlib.org/users/navigation_toolbar.html#navigation-keyboard-shortcuts 458 Makes a table of results and puts it in a widget. 459 Max min and stddev is calculated shown. 461 :return: A widget with the table in it 466 tablewidget = QtGui.QTableWidget(items_per_layer * len(self.
bendMin), ncols)
469 headeritem = QtGui.QTableWidgetItem(
'Stress component')
470 tablewidget.setHorizontalHeaderItem(0, headeritem)
471 headeritem = QtGui.QTableWidgetItem(
'Minimum')
472 headeritem.setToolTip(
'The minimum obtain through the applied time series')
473 tablewidget.setHorizontalHeaderItem(1, headeritem)
474 headeritem = QtGui.QTableWidgetItem(
'Maximum')
475 headeritem.setToolTip(
'The maximum obtain through the applied time series')
476 tablewidget.setHorizontalHeaderItem(2, headeritem)
477 headeritem = QtGui.QTableWidgetItem(
'Std')
478 headeritem.setToolTip(
'The he standard deviation of the given stress component')
479 tablewidget.setHorizontalHeaderItem(3, headeritem)
480 for i
in range(len(self.
bendMin)):
482 newitem = QtGui.QTableWidgetItem(
'Local bending stress for layer %d' % (i + 1))
483 newitem.setToolTip(
'Local bending stress for layer %d' % (i + 1))
484 tablewidget.setItem(i * items_per_layer, 0, newitem)
485 newitem = QtGui.QTableWidgetItem(str(self.
bendMin[i]))
486 tablewidget.setItem(i * items_per_layer, 1, newitem)
487 newitem = QtGui.QTableWidgetItem(str(self.
bendMax[i]))
488 tablewidget.setItem(i * items_per_layer, 2, newitem)
489 newitem = QtGui.QTableWidgetItem(str(self.
bendStddev[i]))
490 tablewidget.setItem(i * items_per_layer, 3, newitem)
492 newitem = QtGui.QTableWidgetItem(
'Axial stress for layer %d' % (i + 1))
493 newitem.setToolTip(
'Axial stress from tension variations %d.' % (i + 1))
494 tablewidget.setItem(i * items_per_layer + 1, 0, newitem)
495 newitem = QtGui.QTableWidgetItem(str(self.
axialMin[i]))
496 tablewidget.setItem(i * items_per_layer + 1, 1, newitem)
497 newitem = QtGui.QTableWidgetItem(str(self.
axialMax[i]))
498 tablewidget.setItem(i * items_per_layer + 1, 2, newitem)
499 newitem = QtGui.QTableWidgetItem(str(self.
axialStddev[i]))
500 tablewidget.setItem(i * items_per_layer + 1, 3, newitem)
502 newitem = QtGui.QTableWidgetItem(
'Friction stress estimate for layer %d' % (i + 1))
503 newitem.setToolTip(
'Estimated based on stick slip, but capped by the stress at critical curvature')
504 tablewidget.setItem(i * items_per_layer + 2, 0, newitem)
505 newitem = QtGui.QTableWidgetItem(str(self.
stickMin[i]))
506 tablewidget.setItem(i * items_per_layer + 2, 1, newitem)
507 newitem = QtGui.QTableWidgetItem(str(self.
stickMax[i]))
508 tablewidget.setItem(i * items_per_layer + 2, 2, newitem)
509 newitem = QtGui.QTableWidgetItem(str(self.
stickStddev[i]))
510 tablewidget.setItem(i * items_per_layer + 2, 3, newitem)
511 tablewidget.setSortingEnabled(
True)
516 :param value: Current value of slider 520 if self.startSlider.hasFocus():
523 self.startSpinbox.setValue(value)
525 self.endSlider.setRange(value, math.ceil(self.timehist.timehist[-1, 0]))
527 self.endSpinbox.setRange(value, self.timehist.timehist[-1, 0])
531 :param value: Current value of spinbox 534 if self.startSpinbox.hasFocus():
537 self.startSlider.setValue(value)
539 self.endSpinbox.setRange(value, self.timehist.timehist[-1, 0])
541 self.endSlider.setRange(value, math.ceil(self.timehist.timehist[-1, 0]))
545 :param value: Current value of slider 548 if self.endSlider.hasFocus():
551 self.endSpinbox.setValue(value)
553 self.startSpinbox.setRange(self.timehist.timehist[0, 0], value)
555 self.startSlider.setRange(math.floor(self.timehist.timehist[0, 0]), value)
559 :param value: Current value of spinbox 562 if self.endSpinbox.hasFocus():
565 self.endSlider.setValue(value)
567 self.startSpinbox.setRange(self.timehist.timehist[0, 0], value)
569 self.startSlider.setRange(math.floor(self.timehist.timehist[0, 0]), value)
573 """ Class for taking care of the full stress calculations 575 removeFullCalcResultSignal = QtCore.Signal()
578 super(FullStressCalc, self).
__init__()
605 Method for setting up the tab where user sets preferences 606 :param window: The main application window 609 self.mainwidget.setAcceptDrops(
True)
610 self.mainwidget.installEventFilter(window)
611 mainlayout = QtGui.QVBoxLayout()
612 self.mainwidget.setLayout(mainlayout)
613 title = QtGui.QLabel(
'<H1> Full stress calculations</H1>')
614 mainlayout.addWidget(title)
615 analysiscombo_layout = QtGui.QHBoxLayout()
616 analysiscombobox_text = QtGui.QLabel(
'Choose local methodology')
617 analysiscombo_layout.addWidget(analysiscombobox_text)
618 analysis_combobox = QtGui.QComboBox()
619 analysis_combobox.setObjectName(
'analysis_combobox')
620 analysis_combobox.addItem(
'Use analytical local analysis')
621 analysis_combobox.currentIndexChanged.connect(self.
localmethod)
622 analysiscombo_layout.addWidget(analysis_combobox)
623 mainlayout.addLayout(analysiscombo_layout)
624 setupwidget = QtGui.QWidget()
625 setup_layout = QtGui.QHBoxLayout()
626 setup_layout.setObjectName(
'setup_layout')
627 setupwidget.setLayout(setup_layout)
629 mainlayout.addWidget(setupwidget)
630 tslayout = QtGui.QGridLayout()
631 tslayout.setObjectName(
'tslayout')
632 removeall_button = QtGui.QPushButton(
'Remove all')
633 tslayout.addWidget(removeall_button, 0, 0)
635 header_name = QtGui.QLabel(
'Name')
636 tslayout.addWidget(header_name, 0, 1)
637 header_starttime = QtGui.QLabel(
'Start time')
638 tslayout.addWidget(header_starttime, 0, 2)
640 self.headerStartLinker.setToolTip(
'Set same starttime for all timeseries')
642 header_starttime = QtGui.QLabel(
'Stop time')
643 tslayout.addWidget(header_starttime, 0, 4)
645 self.headerStopLinker.setToolTip(
'Link stop time for all timeseries')
647 scrollarea = QtGui.QScrollArea()
648 scrollarea.setWidgetResizable(
True)
649 self.
widget = QtGui.QWidget()
650 self.widget.setLayout(tslayout)
651 scrollarea.setWidget(self.
widget)
652 mainlayout.addWidget(scrollarea)
653 dragdrop = QtGui.QLabel(
'<font color="grey">Drag and drop time series here</font>')
654 dragdrop.setObjectName(
'dragdrop')
655 mainlayout.addWidget(dragdrop)
656 calcbutton = QtGui.QPushButton(
'Calculate')
657 calcbutton.setObjectName(
'calcbutton')
658 calcbutton.setEnabled(
False)
659 calcbutton.clicked.connect(window.fullcalc)
660 mainlayout.addWidget(calcbutton)
664 MEthod for adding a time series. obviously 665 :param ts: time series object 667 self.timehists.append(ts)
671 Method for setting up the edit area for the time series 675 self.widget.setVisible(
False)
676 for i
in range(rows):
679 removebutton = QtGui.QPushButton(QtGui.QIcon(
'../icons/remove.png'),
'')
680 self.removeButtons.append(removebutton)
681 tslayout = self.mainwidget.findChild(QtGui.QGridLayout,
'tslayout')
683 label = QtGui.QLabel(self.
timehists[i].name)
684 self.labels.append(label)
688 tslayout.addWidget(self.
labels[i], i + 1, 1)
690 startslider = QtGui.QSlider(QtCore.Qt.Horizontal)
691 self.startSliders.append(startslider)
695 startspinbox = QtGui.QDoubleSpinBox()
696 self.startSpinboxes.append(startspinbox)
704 endslider = QtGui.QSlider(QtCore.Qt.Horizontal)
705 self.endSliders.append(endslider)
708 tslayout.addWidget(self.
endSliders[i], i + 1, 4)
709 endspinbox = QtGui.QDoubleSpinBox()
710 self.endSpinboxes.append(endspinbox)
719 calcbutton = self.mainwidget.findChild(QtGui.QPushButton,
'calcbutton')
720 calcbutton.setEnabled(
True)
721 self.widget.setVisible(
True)
725 Method for setting up an area where the user can choose parameters to be used. 726 Should be split up if more options than analyticalare added 727 :param setup_layout: The parent layout in this case 729 analysis_combobox = self.mainwidget.findChild(QtGui.QComboBox,
'analysis_combobox')
730 text = analysis_combobox.currentText()
731 item = setup_layout.itemAt(0)
733 widget = item.widget()
734 setup_layout.removeWidget(widget)
736 if text ==
'Use analytical local analysis':
738 if not self.mainwidget.findChild(QtGui.QGridLayout,
'analytical_layout'):
739 analytical_layout = QtGui.QGridLayout()
740 label = QtGui.QLabel(
'<H2>Analytical settings</H2>')
741 analytical_layout.addWidget(label, 0, 0, 1, 3)
742 analytical_widget = QtGui.QWidget()
743 analytical_widget.setObjectName(
'analytical_widget')
744 analytical_widget.setLayout(analytical_layout)
745 corelabel = QtGui.QLabel(
'Number of cores for calculation')
746 analytical_layout.addWidget(corelabel, 1, 0, 1, 1)
747 corespinbox = QtGui.QSpinBox()
748 corespinbox.setObjectName(
'corespinbox')
749 corespinbox.setRange(1, 1000)
750 bandlabel = QtGui.QLabel(
'Bend model used for local bending stress')
751 analytical_layout.addWidget(bandlabel, 1, 2, 1, 1)
752 bendcombobox = QtGui.QComboBox()
753 bendcombobox.setObjectName(
'bendcombobox')
754 bendcombobox.addItem(
'Savik')
755 bendcombobox.addItem(
'Tan')
756 analytical_layout.addWidget(bendcombobox, 1, 3, 1, 1)
757 analytical_layout.addWidget(corespinbox, 1, 1, 1, 1)
758 thetalabel = QtGui.QLabel(
'Number of calculation points around the crossection')
759 analytical_layout.addWidget(thetalabel, 2, 0, 1, 1)
760 theta_combobox = QtGui.QComboBox()
761 theta_combobox.setObjectName(
'theta_combobox')
762 theta_combobox.addItem(
'4')
763 theta_combobox.addItem(
'8')
764 theta_combobox.addItem(
'16')
765 theta_combobox.addItem(
'32')
766 theta_combobox.addItem(
'64')
767 theta_combobox.setCurrentIndex(2)
768 analytical_layout.addWidget(theta_combobox, 2, 1, 1, 1)
769 philabel = QtGui.QLabel(
'Number of calculation points around the tendon')
770 analytical_layout.addWidget(philabel, 2, 2, 1, 1)
771 phi_combobox = QtGui.QComboBox()
772 phi_combobox.setObjectName(
'phi_combobox')
773 phi_combobox.addItem(
'4')
774 phi_combobox.addItem(
'8')
775 phi_combobox.addItem(
'16')
776 phi_combobox.addItem(
'32')
777 phi_combobox.addItem(
'64')
778 phi_combobox.setCurrentIndex(2)
779 phi_combobox.setToolTip(
'Only applicable for circular tendons')
780 analytical_layout.addWidget(phi_combobox, 2, 3, 1, 1)
782 analytical_widget = self.mainwidget.findChild(QtGui.QWidget,
'analytical_widget')
783 analytical_widget.show()
784 setup_layout.addWidget(analytical_widget)
786 displaytext = QtGui.QLabel(
'<font color="grey">You need to choose a local method</font>')
787 layout = QtGui.QHBoxLayout()
788 layout.addWidget(displaytext)
789 textwidget = QtGui.QWidget()
790 textwidget.setLayout(layout)
791 setup_layout.addWidget(textwidget)
795 Method for removing all the timeseries from view, and with option for also removing them from calculation scope 796 :param deletedata: Toggle for whether the underlying data should be removed 798 self.widget.setVisible(
False)
801 self.widget.setVisible(
True)
805 Method for removing a single time series from view. With option for removing the time 806 series from calculations scope as well 807 :param label: The label of the time series 808 :param deletedata:Toggle for whether the underlying data should be removed 813 tslayout = self.mainwidget.findChild(QtGui.QGridLayout,
'tslayout')
818 tslayout.removeWidget(self.
labels[i])
819 self.
labels[i].deleteLater()
837 if deletedata ==
'yes':
841 self.removeFullCalcResultSignal.emit()
845 Method for keeping track of slider. With possible coupling between elements 846 :param label:Label of the time series of which the slider belong 847 :param value:Curent value of slider 852 if self.headerStartLinker.isChecked():
853 increment = value - self.
timehists[row].startTime
870 Method for keeping track of spinbox. With possible coupling between elements 871 :param label:Label of the time series of which the slider belong 872 :param value:Curent value of slider 877 if self.headerStartLinker.isChecked():
878 increment = value - self.
timehists[row].startTime
895 Method for keeping track of slider. With possible coupling between elements 896 :param label:Label of the time series of which the slider belong 897 :param value:Curent value of slider 902 if self.headerStopLinker.isChecked():
903 increment = value - self.
timehists[row].endTime
906 tmp = min(tmp, self.
timehists[i].timehist[-1, 0])
920 Method for keeping track of slider. With possible coupling between elements 921 :param label:Label of the time series of which the spinbox belong 922 :param value:Curent value of slider 927 if self.headerStopLinker.isChecked():
928 increment = value - self.
timehists[row].endTime
931 tmp = min(tmp, self.
timehists[i].timehist[-1, 0])
945 Method responsible for setting up the calculation. Calculation thrown to threads 946 :param model: The model of the riser. Type slenders.Slender 949 calcbutton = self.mainwidget.findChild(QtGui.QPushButton,
'calcbutton')
950 calcbutton.setEnabled(
False)
951 analysis_combobox = self.mainwidget.findChild(QtGui.QComboBox,
'analysis_combobox')
952 if analysis_combobox.currentText() ==
'Use analytical local analysis':
953 corespinbox = self.mainwidget.findChild(QtGui.QSpinBox,
'corespinbox')
954 cores = corespinbox.value()
955 analysespercore = math.ceil(len(self.
timehists) / cores)
956 theta_combobox = self.mainwidget.findChild(QtGui.QComboBox,
'theta_combobox')
957 ntheta = int(theta_combobox.currentText())
958 phi_combobox = self.mainwidget.findChild(QtGui.QComboBox,
'phi_combobox')
959 nphi = int(phi_combobox.currentText())
960 bendcombobox = self.mainwidget.findChild(QtGui.QComboBox,
'bendcombobox')
961 bendmodel = bendcombobox.currentText()
962 properties =
AnalysisProp(
'Analytical', ntheta, nphi, bendmodel, model)
963 for i
in range(cores):
964 startindex = i * analysespercore
965 stopindex = min(analysespercore * (i + 1), len(self.
timehists))
967 timehists = self.
timehists[startindex:stopindex]
968 numbers = list(range(startindex, stopindex))
976 Method for finding the index in the time series vector . 977 :param label: Label of the timeseries 980 for i
in range(len(self.
labels)):
981 if self.
labels[i] == label:
986 Method for finding the index in the time series vector . 987 :param name: Name of the timeseries 995 def plot(self, plotdata, layout):
997 Plots data on the layout <layout>. Uses the color given in plotdata 998 :param plotdata: object of PlotData type. 999 :param layout: Where to add the plot 1003 fig = matplotlib.figure.Figure()
1004 self.
canvas = FigureCanvas(fig)
1005 self.canvas.setFocusPolicy(QtCore.Qt.StrongFocus)
1006 self.canvas.setFocus()
1007 self.canvas.ax1 = fig.add_subplot(111)
1008 fig.subplots_adjust(left=0.1, right=0.97, top=0.9, bottom=0.2)
1010 self.canvas.mpl_connect(
'key_press_event', self.
on_key_press, )
1011 anotherwidget = QtGui.QToolButton()
1013 self.mpl_toolbar.addWidget(anotherwidget)
1014 temp = QtGui.QWidget()
1015 plotlayout = QtGui.QVBoxLayout()
1016 plotlayout.setObjectName(
'plotlayout')
1018 plotlayout.addWidget(self.
canvas)
1020 for plot
in plotdata:
1022 fname =
'tmp/fullresult_' + str(tsnumber) +
'.h5' 1023 f = h5py.File(fname,
'r') 1025 , self.timehists[tsnumber].timehist[:, 0]) 1026 if plot.type ==
'Axial stress':
1027 if plot.addRemove ==
'Add':
1028 x_plot = self.
timehists[tsnumber].timehist[startindex:endindex, 0]
1029 y_plot = f[self.
timehists[tsnumber].name +
'/AxialStress'][str(plot.layer - 1)]
1030 legend = plot.label +
'/AxialStress/Layer' + str(plot.layer)
1032 plot.color[0] * (1.0 / 255.0), plot.color[1] * (1.0 / 255.0), plot.color[2] * (1.0 / 255.0))
1033 self.plotlist.append(plot)
1036 for i
in range(len(self.
plotlist)):
1037 if self.
plotlist[i].type == plot.type
and self.
plotlist[i].layer == plot.layer
and \
1038 self.
plotlist[i].label == plot.label:
1040 self.
lines[i].pop(0).remove()
1044 if plot.type ==
'Critical curvature':
1045 if plot.addRemove ==
'Add':
1046 x_plot = self.
timehists[tsnumber].timehist[startindex:endindex, 0]
1047 y_plot = f[self.
timehists[tsnumber].name +
'/CriticalCurvature'][str(plot.layer - 1)]
1048 legend = plot.label +
'/CriticalCurvature/Layer' + str(plot.layer)
1050 plot.color[0] * (1.0 / 255.0), plot.color[1] * (1.0 / 255.0), plot.color[2] * (1.0 / 255.0))
1051 self.plotlist.append(plot)
1054 for i
in range(len(self.
plotlist)):
1055 if self.
plotlist[i].type == plot.type
and self.
plotlist[i].layer == plot.layer
and \
1056 self.
plotlist[i].label == plot.label:
1058 self.
lines[i].pop(0).remove()
1062 if plot.type ==
'Stick stress':
1063 if plot.addRemove ==
'Add':
1064 x_plot = self.
timehists[tsnumber].timehist[startindex:endindex, 0]
1065 y_plot = f[self.
timehists[tsnumber].name +
'/MaxStickStress'][str(plot.layer - 1)]
1066 legend = plot.label +
'/MaxStickStress/Layer' + str(plot.layer)
1068 plot.color[0] * (1.0 / 255.0), plot.color[1] * (1.0 / 255.0), plot.color[2] * (1.0 / 255.0))
1069 self.plotlist.append(plot)
1072 for i
in range(len(self.
plotlist)):
1073 if self.
plotlist[i].type == plot.type
and self.
plotlist[i].layer == plot.layer
and \
1074 self.
plotlist[i].label == plot.label:
1076 self.
lines[i].pop(0).remove()
1080 if plot.type ==
'Local bending stress':
1081 if plot.addRemove ==
'Add':
1082 ntheta = f[self.
timehists[tsnumber].name +
'/LocalBendingStress'][str(plot.layer - 1)].shape[1]
1083 if f[self.
timehists[tsnumber].name +
'/StressResultant'][str(plot.layer - 1)].ndim==3:
1084 nphi = f[self.
timehists[tsnumber].name +
'/LocalBendingStress'][str(plot.layer - 1)].shape[2]
1085 for thetaindex
in range(ntheta):
1086 theta = thetaindex * 2 * np.pi / ntheta
1087 if theta >= plot.theta - 1.0e-5:
1089 if f[self.
timehists[tsnumber].name +
'/StressResultant'][str(plot.layer - 1)].ndim==3:
1091 for phiindex
in range(nphi):
1092 if phiindex + 1 == plot.cornerPhi:
1095 for phiindex
in range(nphi):
1096 phi = phiindex * 2 * np.pi / nphi
1097 if phi >= plot.cornerPhi - 1.0e-5:
1099 x_plot = self.
timehists[tsnumber].timehist[startindex:endindex, 0]
1100 y_plot = f[self.
timehists[tsnumber].name +
'/LocalBendingStress'][
1101 str(plot.layer - 1)][:, thetaindex, phiindex]
1103 legend = plot.label +
'/LocalBendingStress/Layer' + str(plot.layer) +
'Theta' + str(
1104 theta) +
'Corner' + str(phiindex)
1107 legend = plot.label +
'/LocalBendingStress/Layer' + str(plot.layer) +
'Theta' + str(
1108 theta) +
'Phi' + str(phi)
1109 if f[self.
timehists[tsnumber].name +
'/StressResultant'][str(plot.layer - 1)].ndim==2:
1110 x_plot = self.
timehists[tsnumber].timehist[startindex:endindex, 0]
1111 y_plot = f[self.
timehists[tsnumber].name +
'/LocalBendingStress'][
1112 str(plot.layer - 1)][:, thetaindex]
1113 legend = plot.label +
'/LocalBendingStress/Layer' + str(plot.layer) +
'Theta' + str(
1117 plot.color[0] * (1.0 / 255.0), plot.color[1] * (1.0 / 255.0), plot.color[2] * (1.0 / 255.0))
1118 self.plotlist.append(plot)
1120 for i
in range(len(self.
plotlist)):
1121 if self.
plotlist[i].type == plot.type
and self.
plotlist[i].layer == plot.layer
and \
1122 self.
plotlist[i].label == plot.label:
1124 self.
lines[i].pop(0).remove()
1127 if plot.type ==
'Friction stress':
1128 if plot.addRemove ==
'Add':
1129 ntheta = f[self.
timehists[tsnumber].name +
'/FrictionStress'][str(plot.layer - 1)].shape[1]
1130 for thetaindex
in range(ntheta):
1131 theta = thetaindex * 2 * np.pi / ntheta
1132 if theta >= plot.theta - 1.0e-5:
1134 x_plot = self.
timehists[tsnumber].timehist[startindex:endindex, 0]
1135 y_plot = f[self.
timehists[tsnumber].name +
'/FrictionStress'][str(plot.layer - 1)][:, thetaindex]
1136 legend = plot.label +
'/FrictionStress/Layer' + str(plot.layer) +
'Theta' + str(theta)
1138 plot.color[0] * (1.0 / 255.0), plot.color[1] * (1.0 / 255.0), plot.color[2] * (1.0 / 255.0))
1139 self.plotlist.append(plot)
1141 for i
in range(len(self.
plotlist)):
1142 if self.
plotlist[i].type == plot.type
and self.
plotlist[i].layer == plot.layer
and \
1143 self.
plotlist[i].label == plot.label:
1145 self.
lines[i].pop(0).remove()
1149 if plot.type ==
'Stress resultant':
1150 if plot.addRemove ==
'Add':
1151 ntheta = f[self.
timehists[tsnumber].name +
'/StressResultant'][str(plot.layer - 1)].shape[1]
1152 if f[self.
timehists[tsnumber].name +
'/StressResultant'][str(plot.layer - 1)].ndim==3:
1153 nphi = f[self.
timehists[tsnumber].name +
'/StressResultant'][str(plot.layer - 1)].shape[2]
1154 for thetaindex
in range(ntheta):
1155 theta = thetaindex * 2 * np.pi / ntheta
1156 if theta >= plot.theta - 1.0e-5:
1158 if f[self.
timehists[tsnumber].name +
'/StressResultant'][str(plot.layer - 1)].ndim==3:
1160 for phiindex
in range(nphi):
1161 if phiindex + 1 == plot.cornerPhi:
1164 for phiindex
in range(nphi):
1165 phi = phiindex * 2 * np.pi / nphi
1166 if phi >= plot.cornerPhi - 1.0e-5:
1168 x_plot = self.
timehists[tsnumber].timehist[startindex:endindex, 0]
1169 if f[self.
timehists[tsnumber].name +
'/StressResultant'][str(plot.layer - 1)].ndim==3:
1170 y_plot = f[self.
timehists[tsnumber].name +
'/StressResultant'][
1171 str(plot.layer - 1)][:, thetaindex, phiindex]
1173 legend = plot.label +
'/StressResultant/Layer' + str(plot.layer) +
'Theta' + str(
1174 theta) +
'Corner' + str(phiindex)
1177 legend = plot.label +
'/StressResultant/Layer' + str(plot.layer) +
'Theta' + str(
1178 theta) +
'Phi' + str(phi)
1179 elif f[self.
timehists[tsnumber].name +
'/StressResultant'][str(plot.layer - 1)].ndim==2:
1180 y_plot = f[self.
timehists[tsnumber].name +
'/StressResultant'][
1181 str(plot.layer - 1)][:, thetaindex]
1182 legend = plot.label +
'/StressResultant/Layer' + str(plot.layer) +
'Theta' + str(
1186 plot.color[0] * (1.0 / 255.0), plot.color[1] * (1.0 / 255.0), plot.color[2] * (1.0 / 255.0))
1187 self.plotlist.append(plot)
1189 for i
in range(len(self.
plotlist)):
1190 if self.
plotlist[i].type == plot.type
and self.
plotlist[i].layer == plot.layer
and \
1191 self.
plotlist[i].label == plot.label:
1193 self.
lines[i].pop(0).remove()
1197 if plot.addRemove ==
'Add':
1199 self.lines.append(self.canvas.ax1.plot(x_plot, y_plot, label=legend, c=color))
1201 plotted = self.canvas.ax1.get_lines()
1202 max_ylim = -float(
'Inf')
1203 min_ylim = float(
'Inf')
1204 max_xlim = -float(
'Inf')
1205 min_xlim = float(
'Inf')
1206 for plot
in plotted:
1207 xdata = plot.get_xdata()
1208 ydata = plot.get_ydata()
1209 max_yplot = max(ydata)
1210 if max_yplot >= 0
and max_yplot > max_ylim:
1211 max_ylim = max(max_ylim, max_yplot * 1.1 + 0.1)
1213 max_ylim = max(max_ylim, max_yplot * 0.9 + 0.1)
1214 min_yplot = min(ydata)
1215 if min_yplot >= 0
and min_yplot < min_ylim:
1216 min_ylim = min(min_ylim, min_yplot * 0.9 - 0.1)
1218 min_ylim = min(min_ylim, min_yplot * 1.1 - 0.1)
1219 max_xplot = max(xdata)
1220 if max_xplot >= 0
and max_xplot > max_xlim:
1221 max_xlim = max(max_xlim, max_xplot * 1.1 + 0.1)
1223 max_xlim = max(max_xlim, max_xplot * 0.9 + 0.1)
1224 min_xplot = min(xdata)
1225 if min_xplot >= 0
and min_xplot < min_xlim:
1226 min_xlim = min(min_xlim, min_xplot * 0.9 - 0.1)
1228 min_xlim = min(min_xlim, min_xplot * 1.1 - 0.1)
1230 self.canvas.ax1.set_ylim([min_ylim, max_ylim])
1231 self.canvas.ax1.set_xlim([min_xlim, max_xlim])
1235 for i
in range(layout.count()):
1236 widget = layout.widget(i)
1237 if hasattr(widget,
'accessibleName'):
1238 name = widget.accessibleName()
1239 if name ==
'plotwidget':
1244 plotwidget = QtGui.QWidget()
1245 plotwidget.setAccessibleName(
'plotwidget')
1247 plotwidget.setLayout(plotlayout)
1248 layout.addWidget(plotwidget)
1256 Method for removign the plot thouroghly 1265 implement the default mpl key press events described at 1266 http://matplotlib.org/users/navigation_toolbar.html#navigation-keyboard-shortcuts 1269 matplotlib.backend_bases.key_press_handler(event, self.
canvas, self.
mpl_toolbar)
1273 Enables the calcbutton, so new calculations can be carried out 1275 calcbutton = self.mainwidget.findChild(QtGui.QPushButton,
'calcbutton')
1276 calcbutton.setEnabled(
True)
1280 Method for merging all the files from the full calculations to one h5 file 1282 file_dialog = QtGui.QFileDialog()
1283 file_types =
"hdf5 file (*.h5);;Any file (*)" 1285 fname, extension = file_dialog.getSaveFileName(self.
mainwidget,
'Save file',
'', file_types)
1287 if extension.find(
'h5') == -1:
1289 output_file = h5py.File(fname,
'w')
1292 if fname.find(
'h5', -2) != -1:
1294 output_file = h5py.File(fname,
'w')
1297 output_file = h5py.File(fname +
'.h5',
'w')
1300 for input_file_name
in os.listdir(
'tmp'):
1301 if fnmatch.fnmatch(input_file_name,
'fullresult*.h5'):
1303 input_file = h5py.File(
'tmp/' + input_file_name,
'r+')
1304 keys = input_file.keys()
1306 input_file.copy(key, output_file)
1309 output_file[key].create_dataset(
'Time', data=self.
timehists[index].timehist[:, 0])
1310 output_file[key].create_dataset(
'Tension', data=self.
timehists[index].timehist[:, 1])
1311 output_file[key].create_dataset(
'Curvature', data=self.
timehists[index].timehist[:, 2:4])
1320 A thread to carry out full stress calculations. 1322 addFullCalcSignal = QtCore.Signal(int)
1323 finishedSignal = QtCore.Signal(bool)
1325 def __init__(self, model, timeseries, indices, properties):
1326 QtCore.QThread.__init__(self)
1346 Method for running the analysis 1353 for k
in range(len(self.
indices)):
1356 globalstartindex, globalstopindex =
find_indices(ts.startTime, ts.endTime, ts.timehist[:, 0])
1357 tslength = globalstopindex - globalstartindex
1360 for i
in range(len(self.model.layer_radii)):
1361 mid.append([0.0, 0.0])
1363 parts = math.ceil((globalstopindex - globalstartindex) / maxlength)
1364 for part
in range(parts):
1365 startindex = globalstartindex + part * maxlength
1366 stopindex = min(startindex + maxlength, globalstopindex)
1370 thickness=self.model.thickness
1372 np.asarray(self.model.layer_radii),
1373 np.asarray(self.model.thickness),
1374 np.asarray(self.model.width),
1375 np.asarray(self.model.tendon_area),
1376 np.asarray(self.model.lay_angle),
1377 np.asarray(self.model.comp_number),
1378 np.asarray(self.model.youngs_modulus),
1379 np.asarray(self.model.poisson),
1380 np.asarray(self.model.gap_ini),
1381 self.model.intpresslayer-1, self.model.extpresslayer-1,
1382 np.asarray(ts.timehist[startindex:stopindex,1]),
1383 np.asarray(ts.timehist[startindex:stopindex,4]),
1384 np.asarray(ts.timehist[startindex:stopindex,5]))
1385 for i
in range(len(self.model.layer_radii)):
1386 self.axialstress.append(sigma[:,i])
1393 ts.timehist[startindex:stopindex, 2:4],
1394 ntheta=ntheta, nphi=max(nphi),
1395 bend_model=bend_model)
1398 frictionfactors=np.array(self.model.fricfac))
1400 eff_full_slipcurvature = []
1401 for i
in range(len(self.model.layer_radii)):
1402 self.critcurv.append(critcurv[:, i]*np.pi/2.0)
1403 eff_full_slipcurvature.append(critcurv[:, i] * np.pi / 2.0)
1409 timehist = ts.timehist[startindex:stopindex, 2:4]
1410 for i
in range(len(self.model.layer_radii)):
1411 if self.model.layer_type[i]==
'wires':
1412 self.fricStress.append(np.empty([len(ts.timehist[startindex:stopindex, 0]), ntheta]))
1414 effectivecurvature = eff_full_slipcurvature[i]
1418 for j
in range(ntheta):
1419 self.
fricStress[i][:, j] = (stress[:, 0] * np.cos(j * 2 * np.pi / ntheta) +
1420 stress[:, 1] * np.sin(j * 2 * np.pi / ntheta))
1421 elif self.model.layer_type[i]==
'sheath':
1422 self.fricStress.append(np.empty([len(ts.timehist[startindex:stopindex, 0]), ntheta]))
1424 print(
'Layer type for layer ',i+1,
' not understood')
1428 if self.model.layer_type[i]==
'wires':
1429 self.resultantstress.append(np.swapaxes(np.swapaxes(self.
bendstress[i],0,2)+
1431 elif self.model.layer_type[i]==
'sheath':
1432 self.resultantstress.append(np.swapaxes(np.swapaxes(self.
bendstress[i],0,1)+
1436 self.
filedump(part, tslength, k, globalindex)
1438 self.addFullCalcSignal.emit(globalindex)
1440 self.finishedSignal.emit(
True)
1442 def filedump(self, part, tslength, localindex, globalindex):
1444 Method for dumping to file. Makes files, keep track of indices and dumps data 1445 :param part: counter for which part of the analysis is carried out. 1446 :param tslength: Total length of time series 1447 :param globalindex: index in all timeseries analysed 1448 :param localindex: index in timeseries analyzed in this thread 1450 fname =
'tmp/fullresult_' + str(globalindex) +
'.h5' 1454 hf = h5py.File(fname,
'w')
1459 axial = hf.create_group(self.
timeseries[localindex].name +
'/AxialStress')
1460 bend = hf.create_group(self.
timeseries[localindex].name +
'/LocalBendingStress')
1461 fric = hf.create_group(self.
timeseries[localindex].name +
'/FrictionStress')
1462 stressres = hf.create_group(self.
timeseries[localindex].name +
'/StressResultant')
1463 critcurv = hf.create_group(self.
timeseries[localindex].name +
'/CriticalCurvature')
1464 maxstick = hf.create_group(self.
timeseries[localindex].name +
'/MaxStickStress')
1467 axial.create_dataset(str(i), (tslength,))
1469 if self.model.layer_type[i]==
'wires':
1470 bend.create_dataset(str(i), (tslength, self.
ntheta, self.
nphi[i]))
1471 elif self.model.layer_type[i]==
'sheath':
1472 bend.create_dataset(str(i), (tslength, self.
ntheta))
1474 if self.model.layer_type[i]==
'wires':
1475 fric.create_dataset(str(i), (tslength, self.
ntheta))
1477 if self.model.layer_type[i]==
'wires':
1478 stressres.create_dataset(str(i), (tslength, self.
ntheta, self.
nphi[i]))
1479 elif self.model.layer_type[i]==
'sheath':
1480 stressres.create_dataset(str(i), (tslength, self.
ntheta))
1482 if self.model.layer_type[i]==
'wires':
1483 critcurv.create_dataset(str(i), (tslength,))
1485 maxstick.create_dataset(str(i), (tslength,))
1490 hf = h5py.File(fname,
'r+')
1492 axial = hf[self.
timeseries[localindex].name +
'/AxialStress']
1494 bend = hf[self.
timeseries[localindex].name +
'/LocalBendingStress']
1496 fric = hf[self.
timeseries[localindex].name +
'/FrictionStress']
1498 bend = hf[self.
timeseries[localindex].name +
'/StressResultant']
1500 critcurv = hf[self.
timeseries[localindex].name +
'/CriticalCurvature']
1502 maxstick = hf[self.
timeseries[localindex].name +
'/MaxStickStress']
1511 Custom toolbaer for friction class plot 1513 picked = QtCore.Signal(int, name=
'picked')
1516 NavigationToolbar.__init__(self, canvas, parent)
1521 for c
in self.findChildren(QtGui.QToolButton):
1522 if c.text() ==
'Customize':
1525 savedata = QtGui.QAction(
"Save data", self)
1526 savedata.setIcon(QtGui.QIcon(
"../icons/savedata.png"))
1527 savedata.setCheckable(
True)
1528 savedata.setToolTip(
"Save raw data")
1530 button = QtGui.QToolButton(self)
1531 button.setDefaultAction(self.
picker)
1534 self.insertWidget(nextbutton.defaultAction(), button)
1542 Method for saving plot data to h5 file 1545 file_dialog = QtGui.QFileDialog()
1546 file_types =
"hdf5 file (*.h5);;Any file (*)" 1548 fname, extension = file_dialog.getSaveFileName(self,
'Save file',
'', file_types)
1550 if extension.find(
'h5') == -1:
1552 hf = h5py.File(fname)
1555 if fname.find(
'h5', -2) != -1:
1557 hf = h5py.File(fname)
1560 hf = h5py.File(fname +
'.h5')
1562 lines = self.canvas.ax1.get_lines()
1564 xydata = line.get_xydata()
1565 label = line.get_label()
1566 g1 = hf.create_group(
'frictioncalc/%s' % label)
1567 g1.create_dataset(
'x', data=xydata[:, 0])
1568 g1.create_dataset(
'y', data=xydata[:, 1])
1574 Class for custom toolbar for Full calculation plot 1577 FricCalcNavigationToolbar.__init__(self, canvas, parent)
1581 Method for saving plot data as h5 file 1583 file_dialog = QtGui.QFileDialog()
1584 file_types =
"hdf5 file (*.h5);;ASCII file (*.ts)" 1586 fname, extension = file_dialog.getSaveFileName(self,
'Save file',
'', file_types)
1588 if extension.find(
'ts') != -1:
1589 if fname[-3:-1]==
'ts':
1592 filename=fname+
'.ts' 1594 elif extension.find(
'h5') != -1:
1595 if fname[-2:]==
'h5':
1598 filename=fname+
'.h5' 1601 lines = self.canvas.ax1.get_lines()
1605 printmatrix.append(lines[0].get_xdata())
1607 ydata = line.get_ydata()
1608 label = line.get_label()
1609 printmatrix.append(ydata)
1611 npprintmatrix=np.array(printmatrix)
1612 np.savetxt(filename, npprintmatrix.T, delimiter=
"\t", header=header)
1615 hf = h5py.File(filename,
'w')
1617 xydata = line.get_xydata()
1618 label = line.get_label()
1619 g1 = hf.create_group(label)
1620 g1.create_dataset(
'Time', data=xydata[:, 0])
1621 g1.create_dataset(
'Value', data=xydata[:, 1])
1627 Class for making plot data. Keeps track of what color it should be and whether it should be removed or added 1628 Several plot data instances keep track of each other through colortaken and colorlist Could be made class 1631 def __init__(self, treedata, colorlist, colortaken, add_remove):
1633 self.
layer = int(treedata[1].split()[-1])
1637 colormin = min(colortaken)
1638 for i
in range(len(colortaken)):
1639 if colortaken[i] == colormin:
1646 :param active: Whether the plot should be active or not 1647 :param color_taken: list of which colors that are currently in use in the plot 1653 for i
in range(len(active)):
1654 if [active[i].type, active[i].label, active[i].layer] == [self.
type, self.
label, self.
layer]:
1655 color_taken[active[i].colorindex] -= 1
1661 """ As parent, only with one more level of refineent with distinguishing thetas 1663 def __init__(self, treedata, colorlist, colortaken, add_remove):
1664 super(FourLevelPlotData, self).
__init__(treedata, colorlist, colortaken, add_remove)
1665 self.
theta = float(treedata[3].split()[-1])
1672 for i
in range(len(active)):
1673 if hasattr(active,
'theta'):
1674 if ([active[i].type, active[i].label, active[i].layer, active[i].theta] ==
1676 color_taken[active[i].colorindex] -= 1
1682 """ As parent, only with one more level of refineent with distinguishing phis 1684 def __init__(self, treedata, colorlist, colortaken, add_remove):
1685 super(FiveLevelPlotData, self).
__init__(treedata, colorlist, colortaken, add_remove)
1687 if treedata[4][0:4] ==
'Corn':
1697 for i
in range(len(active)):
1698 if hasattr(active,
'theta')
and hasattr(active,
'cornerPhi'):
1699 if ([active[i].type, active[i].label, active[i].layer, active[i].theta, active[i].cornerPhi] ==
1701 color_taken[active[i].colorindex] -= 1
1708 Method for grouping together analysis properties 1710 def __init__(self, analysistype, ntheta, nphi, bendmodel, model):
1711 if analysistype ==
'Analytical':
1715 for i
in range(len(model.layer_radii)):
1721 Assumes sorted data. 1722 :param startvalue: start value in vector to find 1723 :param endvalue: End value to find in vector 1725 :return startindex: index of last value smaller or equal to startvalue 1726 :return endindex: first index equal or larger than vector.Bound by length of vector 1728 startindex = np.argmax(vector > startvalue)
1730 endindex = np.argmax(vector >= endvalue)
1731 endindex = np.amin([endindex, len(vector)])
1734 return startindex, endindex
1738 Subclassed proxy model for custom filter behaviour 1741 super(FullTreeProxyModel, self).
__init__(parent)
1744 index0 = self.sourceModel().index(sourceRow, 0, sourceParent)
1745 index1 = self.sourceModel().index(sourceRow, 1, sourceParent)
1746 index2 = self.sourceModel().index(sourceRow, 2, sourceParent)
1748 return ( (self.filterRegExp().indexIn(self.sourceModel().data(index0,QtCore.Qt.DisplayRole)) >= 0
1749 or self.filterRegExp().indexIn(self.sourceModel().data(index1,QtCore.Qt.DisplayRole)) >= 0))
def calculate(self, model)
def localmethod(self, setup_layout)
def on_key_press(self, event)
def __init__(self, treedata, colorlist, colortaken, add_remove)
def startspinbox_changed(self, value)
def __init__(self, time_filename, histname, directory=None)
def endspinbox_changed(self, value)
def update(self, active, color_taken)
def enablecalcbutton(self)
def startspinbox_changed(self, label, value)
def plot(self, plotdata, layout)
def on_key_press(self, event)
def update(self, active, color_taken)
def __init__(self, treedata, colorlist, colortaken, add_remove)
def update(self, active, color_taken)
def fric_stress(curv, eps_mat, sig_mat, midpoint)
def startslider_changed(self, label, value)
def setup_tab(self, window)
def index_from_name(self, name)
def endspinbox_changed(self, label, value)
def __init__(self, parent=None)
def export_all_results(self)
def __init__(self, model, timeseries, indices, properties)
def solver(layerinfo, r, t, b, A, alpha, n, E, nu, gap_ini, intpresslayer, extpresslayer, T_eff, p_int, p_ext)
def endslider_changed(self, label, value)
def filterAcceptsRow(self, sourceRow, sourceParent)
def set_from_tim(self, directory)
def bending_stress_history(slenderobject, curvhist, ntheta=16, nphi=16, bend_model="Savik")
def max_stickstress(model, critcurv)
def remove_ts(self, label, deletedata='yes')
def __init__(self, treedata, colorlist, colortaken, add_remove)
def setup_tab(self, window)
def find_indices(startvalue, endvalue, vector)
def stick_stress(model, curv, critcurv, theta=None)
def __init__(self, analysistype, ntheta, nphi, bendmodel, model)
def calculate(self, model)
def index_from_label(self, label)
def remove_all_ts(self, deletedata='yes')
def critical_curvature(slenderobject, contact_pressure, frictionfactors=np.array([5, 5, 5]))
def filedump(self, part, tslength, localindex, globalindex)
def endslider_changed(self, value)
def startslider_changed(self, value)