FEM: result task panel, Histograms added to result object instead of average stats values
This commit is contained in:
@@ -122,37 +122,10 @@
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QFormLayout" name="formLayout">
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="label_2">
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label_4">
|
||||
<property name="text">
|
||||
<string>Avg:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="Gui::InputField" name="le_avg">
|
||||
<property name="readOnly">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="unit" stdset="0">
|
||||
<string notr="true">mm</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string>Max:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="Gui::InputField" name="le_max">
|
||||
<property name="readOnly">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="unit" stdset="0">
|
||||
<string notr="true">mm</string>
|
||||
<string>Min:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
@@ -166,10 +139,27 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label_4">
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string>Min:</string>
|
||||
<string>Max:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="Gui::InputField" name="le_max">
|
||||
<property name="readOnly">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="unit" stdset="0">
|
||||
<string notr="true">mm</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QPushButton" name="show_histogram">
|
||||
<property name="text">
|
||||
<string>Histogram</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
|
||||
@@ -39,6 +39,8 @@ from PySide import QtGui
|
||||
from PySide.QtCore import Qt
|
||||
from PySide.QtGui import QApplication
|
||||
import numpy as np
|
||||
import matplotlib.pyplot as plt
|
||||
|
||||
|
||||
False if FemGui.__name__ else True # flake8, dummy FemGui usage
|
||||
|
||||
@@ -208,6 +210,11 @@ class _TaskPanelFemResultShow:
|
||||
self.peeq_selected
|
||||
)
|
||||
|
||||
# stats
|
||||
self.result_widget.show_histogram.clicked.connect(
|
||||
self.show_histogram_clicked
|
||||
)
|
||||
|
||||
# displacement
|
||||
QtCore.QObject.connect(
|
||||
self.result_widget.cb_show_displacement,
|
||||
@@ -228,9 +235,7 @@ class _TaskPanelFemResultShow:
|
||||
)
|
||||
|
||||
# user defined equation
|
||||
QtCore.QObject.connect(
|
||||
self.result_widget.user_def_eq,
|
||||
QtCore.SIGNAL("textchanged()"),
|
||||
self.result_widget.user_def_eq.textChanged.connect(
|
||||
self.user_defined_text
|
||||
)
|
||||
QtCore.QObject.connect(
|
||||
@@ -331,8 +336,10 @@ class _TaskPanelFemResultShow:
|
||||
|
||||
def none_selected(self, state):
|
||||
FreeCAD.FEM_dialog["results_type"] = "None"
|
||||
self.set_result_stats("mm", 0.0, 0.0, 0.0)
|
||||
self.set_result_stats("mm", 0.0, 0.0)
|
||||
self.reset_mesh_color()
|
||||
if len(plt.get_fignums()) > 0:
|
||||
plt.close()
|
||||
|
||||
# if an analysis has different result types and one has
|
||||
# stress and the other not the restore result dialog
|
||||
@@ -434,6 +441,9 @@ class _TaskPanelFemResultShow:
|
||||
self.result_widget.rb_none.setChecked(True)
|
||||
self.none_selected(True)
|
||||
|
||||
def show_histogram_clicked(self):
|
||||
plt.show()
|
||||
|
||||
def user_defined_text(self, equation):
|
||||
FreeCAD.FEM_dialog["results_type"] = "user"
|
||||
self.result_widget.user_def_eq.toPlainText()
|
||||
@@ -521,9 +531,8 @@ class _TaskPanelFemResultShow:
|
||||
if UserDefinedFormula:
|
||||
self.result_obj.UserDefined = UserDefinedFormula
|
||||
minm = min(UserDefinedFormula)
|
||||
avg = sum(UserDefinedFormula) / len(UserDefinedFormula)
|
||||
maxm = max(UserDefinedFormula)
|
||||
self.update_colors_stats(UserDefinedFormula, "", minm, avg, maxm)
|
||||
self.update_colors_stats(UserDefinedFormula, "", minm, maxm)
|
||||
|
||||
# Dummy use of the variables to get around flake8 error
|
||||
del x, y, z, T, vM, Peeq, P1, P2, P3
|
||||
@@ -540,24 +549,32 @@ class _TaskPanelFemResultShow:
|
||||
|
||||
def result_selected(self, res_type, res_values, res_unit):
|
||||
FreeCAD.FEM_dialog["results_type"] = res_type
|
||||
(minm, avg, maxm) = self.get_result_stats(res_type)
|
||||
self.update_colors_stats(res_values, res_unit, minm, avg, maxm)
|
||||
(minm, maxm) = self.get_result_stats(res_type)
|
||||
self.update_colors_stats(res_values, res_unit, minm, maxm)
|
||||
|
||||
def update_colors_stats(self, res_values, res_unit, minm, avg, maxm):
|
||||
if len(plt.get_fignums()) > 0:
|
||||
plt.close()
|
||||
plt.hist(res_values, bins = 50, alpha = 0.5, facecolor = "blue")
|
||||
plt.xlabel(res_unit)
|
||||
plt.title("Histogram of {}".format(res_type))
|
||||
plt.ylabel("Nodes")
|
||||
plt.grid(True)
|
||||
fig_manager = plt.get_current_fig_manager()
|
||||
fig_manager.window.setWindowFlags(QtCore.Qt.WindowStaysOnTopHint) # stay ontop
|
||||
|
||||
def update_colors_stats(self, res_values, res_unit, minm, maxm):
|
||||
QApplication.setOverrideCursor(Qt.WaitCursor)
|
||||
if self.suitable_results:
|
||||
self.mesh_obj.ViewObject.setNodeColorByScalars(
|
||||
self.result_obj.NodeNumbers,
|
||||
res_values
|
||||
)
|
||||
self.set_result_stats(res_unit, minm, avg, maxm)
|
||||
self.set_result_stats(res_unit, minm, maxm)
|
||||
QtGui.QApplication.restoreOverrideCursor()
|
||||
|
||||
def set_result_stats(self, unit, minm, avg, maxm):
|
||||
def set_result_stats(self, unit, minm, maxm):
|
||||
self.result_widget.le_min.setProperty("unit", unit)
|
||||
self.result_widget.le_min.setProperty("rawText", "{:.6} {}".format(minm, unit))
|
||||
self.result_widget.le_avg.setProperty("unit", unit)
|
||||
self.result_widget.le_avg.setProperty("rawText", "{:.6} {}".format(avg, unit))
|
||||
self.result_widget.le_max.setProperty("unit", unit)
|
||||
self.result_widget.le_max.setProperty("rawText", "{:.6} {}".format(maxm, unit))
|
||||
|
||||
@@ -620,7 +637,7 @@ class _TaskPanelFemResultShow:
|
||||
DisplacementLengths --> rb_abs_displacement
|
||||
DisplacementVectors --> rb_x_displacement, rb_y_displacement, rb_z_displacement
|
||||
Temperature --> rb_temperature
|
||||
vonMises --> rb_vm_stress
|
||||
vonMises --> rb_vm_stress
|
||||
PrincipalMax --> rb_maxprin
|
||||
PrincipalMin --> rb_minprin
|
||||
MaxShear --> rb_max_shear_stress
|
||||
@@ -681,6 +698,7 @@ class _TaskPanelFemResultShow:
|
||||
|
||||
def reject(self):
|
||||
self.reset_result_mesh()
|
||||
plt.close()
|
||||
# if the tasks panel is called from Command obj is not in edit mode
|
||||
# thus reset edit does not close the dialog, maybe don't call but set in edit instead
|
||||
FreeCADGui.Control.closeDialog()
|
||||
|
||||
@@ -171,7 +171,7 @@ def show_color_by_scalar_with_cutoff(resultobj, values, limit=None):
|
||||
|
||||
|
||||
def get_stats(res_obj, result_type):
|
||||
"""Returns minimum, average and maximum value for provided result type
|
||||
"""Returns minimum and maximum value for provided result type
|
||||
|
||||
Parameters
|
||||
----------
|
||||
@@ -180,12 +180,12 @@ def get_stats(res_obj, result_type):
|
||||
result_type : str
|
||||
type of FEM result
|
||||
allowed are: see dict keys in def get_all_stats()
|
||||
None - always return (0.0, 0.0, 0.0)
|
||||
None - always return (0.0, 0.0)
|
||||
|
||||
"""
|
||||
|
||||
match_table = get_all_stats(res_obj)
|
||||
match_table["None"] = (0.0, 0.0, 0.0)
|
||||
match_table["None"] = (0.0, 0.0)
|
||||
stats = ()
|
||||
if result_type in match_table:
|
||||
stats = match_table[result_type]
|
||||
@@ -235,19 +235,19 @@ def get_all_stats(res_obj):
|
||||
|
||||
m = res_obj.Stats
|
||||
stats_dict = {
|
||||
"U1": (m[0], m[1], m[2]),
|
||||
"U2": (m[3], m[4], m[5]),
|
||||
"U3": (m[6], m[7], m[8]),
|
||||
"Uabs": (m[9], m[10], m[11]),
|
||||
"Sabs": (m[12], m[13], m[14]),
|
||||
"MaxPrin": (m[15], m[16], m[17]),
|
||||
"MidPrin": (m[18], m[19], m[20]),
|
||||
"MinPrin": (m[21], m[22], m[23]),
|
||||
"MaxShear": (m[24], m[25], m[26]),
|
||||
"Peeq": (m[27], m[28], m[29]),
|
||||
"Temp": (m[30], m[31], m[32]),
|
||||
"MFlow": (m[33], m[34], m[35]),
|
||||
"NPress": (m[36], m[37], m[38])
|
||||
"U1": (m[0], m[1]),
|
||||
"U2": (m[2], m[3]),
|
||||
"U3": (m[4], m[5]),
|
||||
"Uabs": (m[6], m[7]),
|
||||
"Sabs": (m[8], m[9]),
|
||||
"MaxPrin": (m[10], m[11]),
|
||||
"MidPrin": (m[12], m[13]),
|
||||
"MinPrin": (m[14], m[15]),
|
||||
"MaxShear": (m[16], m[17]),
|
||||
"Peeq": (m[18], m[19]),
|
||||
"Temp": (m[20], m[21]),
|
||||
"MFlow": (m[22], m[23]),
|
||||
"NPress": (m[24], m[25])
|
||||
}
|
||||
return stats_dict
|
||||
|
||||
@@ -264,76 +264,61 @@ def fill_femresult_stats(res_obj):
|
||||
FreeCAD.Console.PrintLog(
|
||||
"Calculate stats list for result obj: " + res_obj.Name + "\n"
|
||||
)
|
||||
no_of_values = 1 # to avoid division by zero
|
||||
# set stats values to 0, they may not exist in res_obj
|
||||
x_min = y_min = z_min = x_max = y_max = z_max = x_avg = y_avg = z_avg = 0
|
||||
a_max = a_min = a_avg = s_max = s_min = s_avg = 0
|
||||
p1_min = p1_avg = p1_max = p2_min = p2_avg = p2_max = p3_min = p3_avg = p3_max = 0
|
||||
ms_min = ms_avg = ms_max = peeq_min = peeq_avg = peeq_max = 0
|
||||
temp_min = temp_avg = temp_max = 0
|
||||
mflow_min = mflow_avg = mflow_max = npress_min = npress_avg = npress_max = 0
|
||||
x_min = y_min = z_min = x_max = y_max = z_max = 0
|
||||
a_max = a_min = s_max = s_min = 0
|
||||
p1_min = p1_max = p2_min = p2_max = p3_min = p3_max = 0
|
||||
ms_min = ms_max = peeq_min = peeq_max = 0
|
||||
temp_min = temp_max = 0
|
||||
mflow_min = mflow_max = npress_min = npress_max = 0
|
||||
|
||||
if res_obj.DisplacementVectors:
|
||||
no_of_values = len(res_obj.DisplacementVectors)
|
||||
x_max, y_max, z_max = map(max, zip(*res_obj.DisplacementVectors))
|
||||
x_min, y_min, z_min = map(min, zip(*res_obj.DisplacementVectors))
|
||||
sum_list = map(sum, zip(*res_obj.DisplacementVectors))
|
||||
x_avg, y_avg, z_avg = [i / no_of_values for i in sum_list]
|
||||
a_min = min(res_obj.DisplacementLengths)
|
||||
a_avg = sum(res_obj.DisplacementLengths) / no_of_values
|
||||
a_max = max(res_obj.DisplacementLengths)
|
||||
if res_obj.vonMises:
|
||||
s_min = min(res_obj.vonMises)
|
||||
s_avg = sum(res_obj.vonMises) / no_of_values
|
||||
s_max = max(res_obj.vonMises)
|
||||
if res_obj.PrincipalMax:
|
||||
p1_min = min(res_obj.PrincipalMax)
|
||||
p1_avg = sum(res_obj.PrincipalMax) / no_of_values
|
||||
p1_max = max(res_obj.PrincipalMax)
|
||||
if res_obj.PrincipalMed:
|
||||
p2_min = min(res_obj.PrincipalMed)
|
||||
p2_avg = sum(res_obj.PrincipalMed) / no_of_values
|
||||
p2_max = max(res_obj.PrincipalMed)
|
||||
if res_obj.PrincipalMin:
|
||||
p3_min = min(res_obj.PrincipalMin)
|
||||
p3_avg = sum(res_obj.PrincipalMin) / no_of_values
|
||||
p3_max = max(res_obj.PrincipalMin)
|
||||
if res_obj.MaxShear:
|
||||
ms_min = min(res_obj.MaxShear)
|
||||
ms_avg = sum(res_obj.MaxShear) / no_of_values
|
||||
ms_max = max(res_obj.MaxShear)
|
||||
if res_obj.Peeq:
|
||||
peeq_min = min(res_obj.Peeq)
|
||||
peeq_avg = sum(res_obj.Peeq) / no_of_values
|
||||
peeq_max = max(res_obj.Peeq)
|
||||
if res_obj.Temperature:
|
||||
temp_min = min(res_obj.Temperature)
|
||||
temp_avg = sum(res_obj.Temperature) / no_of_values
|
||||
temp_max = max(res_obj.Temperature)
|
||||
if res_obj.MassFlowRate:
|
||||
# DisplacementVectors is empty, no_of_values needs to be set
|
||||
no_of_values = len(res_obj.MassFlowRate)
|
||||
mflow_min = min(res_obj.MassFlowRate)
|
||||
mflow_avg = sum(res_obj.MassFlowRate) / no_of_values
|
||||
mflow_max = max(res_obj.MassFlowRate)
|
||||
if res_obj.NetworkPressure:
|
||||
npress_min = min(res_obj.NetworkPressure)
|
||||
npress_avg = sum(res_obj.NetworkPressure) / no_of_values
|
||||
npress_max = max(res_obj.NetworkPressure)
|
||||
|
||||
res_obj.Stats = [x_min, x_avg, x_max,
|
||||
y_min, y_avg, y_max,
|
||||
z_min, z_avg, z_max,
|
||||
a_min, a_avg, a_max,
|
||||
s_min, s_avg, s_max,
|
||||
p1_min, p1_avg, p1_max,
|
||||
p2_min, p2_avg, p2_max,
|
||||
p3_min, p3_avg, p3_max,
|
||||
ms_min, ms_avg, ms_max,
|
||||
peeq_min, peeq_avg, peeq_max,
|
||||
temp_min, temp_avg, temp_max,
|
||||
mflow_min, mflow_avg, mflow_max,
|
||||
npress_min, npress_avg, npress_max]
|
||||
res_obj.Stats = [x_min, x_max,
|
||||
y_min, y_max,
|
||||
z_min, z_max,
|
||||
a_min, a_max,
|
||||
s_min, s_max,
|
||||
p1_min, p1_max,
|
||||
p2_min, p2_max,
|
||||
p3_min, p3_max,
|
||||
ms_min, ms_max,
|
||||
peeq_min, peeq_max,
|
||||
temp_min, temp_max,
|
||||
mflow_min, mflow_max,
|
||||
npress_min, npress_max]
|
||||
"""
|
||||
stat_types = [
|
||||
"U1",
|
||||
|
||||
Reference in New Issue
Block a user