FEM: result task panel, Histograms added to result object instead of average stats values

This commit is contained in:
UR-0
2020-02-17 18:53:43 +01:00
committed by Bernd Hahnebach
parent 47def896a1
commit 35cde48588
3 changed files with 90 additions and 97 deletions

View File

@@ -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>

View File

@@ -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()

View File

@@ -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",