FEM: 1DFlow, result reading and display results

This commit is contained in:
kgoao 2017-02-28 11:50:25 +01:00 committed by wmayer
parent 8bb1df3736
commit 919823dfb9
6 changed files with 625 additions and 473 deletions

View File

@ -54,6 +54,8 @@ FemResultObject::FemResultObject()
ADD_PROPERTY_TYPE(PrincipalMin,(0), "Fem",Prop_None,"List of Third Principal (Min) stress values");
ADD_PROPERTY_TYPE(MaxShear,(0), "Fem",Prop_None,"List of Maximum Shear stress values");
ADD_PROPERTY_TYPE(Temperature,(0), "Fem",Prop_None,"Nodal temperatures");
ADD_PROPERTY_TYPE(MassFlowRate,(0), "Fem",Prop_None,"Nodal network mass flow rate");
ADD_PROPERTY_TYPE(NetworkPressure,(0), "Fem",Prop_None,"Nodal network pressure");
ADD_PROPERTY_TYPE(Eigenmode,(0), "Fem",Prop_None,"Number of the eigenmode");
ADD_PROPERTY_TYPE(EigenmodeFrequency,(0), "Fem",Prop_None,"Frequency of the eigenmode");
ADD_PROPERTY_TYPE(UserDefined,(0), "Fem",Prop_None,"User Defined Results");
@ -74,6 +76,8 @@ FemResultObject::FemResultObject()
PrincipalMin.setStatus(App::Property::ReadOnly, true);
MaxShear.setStatus(App::Property::ReadOnly, true);
Temperature.setStatus(App::Property::ReadOnly, true);
MassFlowRate.setStatus(App::Property::ReadOnly, true);
NetworkPressure.setStatus(App::Property::ReadOnly, true);
Eigenmode.setStatus(App::Property::ReadOnly, true);
EigenmodeFrequency.setStatus(App::Property::ReadOnly, true);
UserDefined.setStatus(App::Property::ReadOnly, false);

View File

@ -913,6 +913,8 @@ void FemVTKTools::importMechanicalResult(vtkSmartPointer<vtkDataSet> dataset, Ap
scalers["PrincipalMin"] = "Minimum Principal stress";
scalers["MaxShear"] = "Max shear stress (Tresca)";
scalers["StressValues"] = "Von Mises stress";
scalers["MassFlowRate"] = "Mass Flow Rate";
scalers["NetworkPressure"] = "Network Pressure";
//scalers["DisplacementLengths"] = ""; // not yet exported in exportMechanicalResult()
std::map<std::string, int> varids;
@ -951,6 +953,8 @@ void FemVTKTools::exportMechanicalResult(const App::DocumentObject* res, vtkSmar
scalers["PrincipalMin"] = "Minimum Principal stress";
scalers["MaxShear"] = "Max shear stress (Tresca)";
scalers["StressValues"] = "Von Mises stress";
scalers["MassFlowRate"] = "Mass Flow Rate";
scalers["NetworkPressure"] = "Network Pressure";
//scalers["DisplacementLengths"] = ""; // not yet exported in exportMechanicalResult()
std::string essential_property = std::string("DisplacementVectors");

View File

@ -7,387 +7,405 @@
<x>0</x>
<y>0</y>
<width>446</width>
<height>620</height>
<height>898</height>
</rect>
</property>
<property name="windowTitle">
<string>Show result</string>
</property>
<layout class="QHBoxLayout" name="horizontalLayout">
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<layout class="QVBoxLayout" name="verticalLayout_3">
<item>
<widget class="QGroupBox" name="gb_result_type">
<property name="title">
<string>Result type</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<layout class="QGridLayout" name="gridLayout">
<item row="4" column="0">
<widget class="QRadioButton" name="rb_z_displacement">
<property name="text">
<string>Z displacement</string>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QRadioButton" name="rb_y_displacement">
<property name="text">
<string>Y displacement</string>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QRadioButton" name="rb_x_displacement">
<property name="text">
<string>X displacement</string>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QRadioButton" name="rb_none">
<property name="text">
<string>None</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QRadioButton" name="rb_abs_displacement">
<property name="text">
<string>Abs displacement</string>
</property>
</widget>
</item>
<item row="4" column="1">
<widget class="QRadioButton" name="rb_max_shear_stress">
<property name="text">
<string>Max shear stress(Tresca)</string>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QRadioButton" name="rb_minprin">
<property name="text">
<string>Min Principal stress</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QRadioButton" name="rb_maxprin">
<property name="text">
<string>Max Principal stress</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QRadioButton" name="rb_vm_stress">
<property name="text">
<string>Von Mises stress</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QRadioButton" name="rb_temperature">
<property name="text">
<string>Temperature</string>
</property>
</widget>
</item>
</layout>
<widget class="QGroupBox" name="gb_result_type">
<property name="title">
<string>Result type</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<widget class="QRadioButton" name="rb_none">
<property name="text">
<string>None</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<layout class="QFormLayout" name="formLayout">
<item row="1" column="0">
<widget class="QLabel" name="label_2">
<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>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="Gui::InputField" name="le_min">
<property name="readOnly">
<bool>true</bool>
</property>
<property name="unit" stdset="0">
<string notr="true">mm</string>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QLabel" name="label_4">
<property name="text">
<string>Min:</string>
</property>
</widget>
</item>
</layout>
<item row="0" column="1">
<widget class="QRadioButton" name="rb_temperature">
<property name="text">
<string>Temperature</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QRadioButton" name="rb_abs_displacement">
<property name="text">
<string>Abs displacement</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QRadioButton" name="rb_vm_stress">
<property name="text">
<string>Von Mises stress</string>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QRadioButton" name="rb_x_displacement">
<property name="text">
<string>X displacement</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QRadioButton" name="rb_maxprin">
<property name="text">
<string>Max Principal stress</string>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QRadioButton" name="rb_y_displacement">
<property name="text">
<string>Y displacement</string>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QRadioButton" name="rb_minprin">
<property name="text">
<string>Min Principal stress</string>
</property>
</widget>
</item>
<item row="4" column="0">
<widget class="QRadioButton" name="rb_z_displacement">
<property name="text">
<string>Z displacement</string>
</property>
</widget>
</item>
<item row="4" column="1">
<widget class="QRadioButton" name="rb_max_shear_stress">
<property name="text">
<string>Max shear stress(Tresca)</string>
</property>
</widget>
</item>
<item row="5" column="0">
<widget class="QRadioButton" name="rb_massflowrate">
<property name="text">
<string>Mass Flow Rate</string>
</property>
</widget>
</item>
<item row="5" column="1">
<widget class="QRadioButton" name="rb_networkpressure">
<property name="text">
<string>Network Pressure</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="gb_displacement">
<property name="title">
<string>Displacement</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2">
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QCheckBox" name="cb_show_displacement">
<property name="text">
<string>Show</string>
</property>
<property name="checked">
<bool>false</bool>
</property>
</widget>
</item>
<item>
<widget class="QScrollBar" name="hsb_displacement_factor">
<property name="enabled">
<bool>false</bool>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
</layout>
<widget class="QLabel" name="label_4">
<property name="text">
<string>Min:</string>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_3">
<item>
<widget class="QLabel" name="label_3">
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
<string>Factor:</string>
</property>
</widget>
</item>
<item>
<widget class="QSpinBox" name="sb_displacement_factor">
<property name="enabled">
<bool>false</bool>
</property>
<property name="readOnly">
<bool>false</bool>
</property>
<property name="maximum">
<number>99999</number>
</property>
<property name="singleStep">
<number>10</number>
</property>
<property name="value">
<number>1</number>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_4">
<item>
<widget class="QLabel" name="label_7">
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
<string>Slider max:</string>
</property>
</widget>
</item>
<item>
<widget class="QSpinBox" name="sb_displacement_factor_max">
<property name="enabled">
<bool>false</bool>
</property>
<property name="readOnly">
<bool>false</bool>
</property>
<property name="maximum">
<number>99999</number>
</property>
<property name="singleStep">
<number>10</number>
</property>
<property name="value">
<number>100</number>
</property>
</widget>
</item>
</layout>
<widget class="Gui::InputField" name="le_min">
<property name="readOnly">
<bool>true</bool>
</property>
<property name="unit" stdset="0">
<string notr="true">mm</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="gb_displacement_2">
<property name="title">
<string>User defined equation</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_5">
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_5">
<item>
<layout class="QVBoxLayout" name="verticalLayout_6">
<item>
<widget class="QPushButton" name="calculate">
<property name="text">
<string>Calculate and plot</string>
</property>
</widget>
</item>
<item>
<widget class="QTextEdit" name="user_def_eq">
<property name="html">
<string>&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;http://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt;
<widget class="QLabel" name="label_2">
<property name="text">
<string>Avg:</string>
</property>
</widget>
</item>
<item>
<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>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_6">
<item>
<widget class="QLabel" name="label">
<property name="text">
<string>Max:</string>
</property>
</widget>
</item>
<item>
<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>
</layout>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="gb_displacement">
<property name="title">
<string>Displacement</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_4">
<item>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QCheckBox" name="cb_show_displacement">
<property name="text">
<string>Show</string>
</property>
<property name="checked">
<bool>false</bool>
</property>
</widget>
</item>
<item>
<widget class="QScrollBar" name="hsb_displacement_factor">
<property name="enabled">
<bool>false</bool>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_3">
<item>
<widget class="QLabel" name="label_3">
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
<string>Factor:</string>
</property>
</widget>
</item>
<item>
<widget class="QSpinBox" name="sb_displacement_factor">
<property name="enabled">
<bool>false</bool>
</property>
<property name="readOnly">
<bool>false</bool>
</property>
<property name="maximum">
<number>99999</number>
</property>
<property name="singleStep">
<number>10</number>
</property>
<property name="value">
<number>1</number>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_4">
<item>
<widget class="QLabel" name="label_7">
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
<string>Slider max:</string>
</property>
</widget>
</item>
<item>
<widget class="QSpinBox" name="sb_displacement_factor_max">
<property name="enabled">
<bool>false</bool>
</property>
<property name="readOnly">
<bool>false</bool>
</property>
<property name="maximum">
<number>99999</number>
</property>
<property name="singleStep">
<number>10</number>
</property>
<property name="value">
<number>100</number>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="gb_displacement_2">
<property name="title">
<string>User defined equation</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_3">
<item>
<layout class="QVBoxLayout" name="verticalLayout_6">
<item>
<widget class="QPushButton" name="calculate">
<property name="text">
<string>Calculate and plot</string>
</property>
</widget>
</item>
<item>
<widget class="QTextEdit" name="user_def_eq">
<property name="html">
<string>&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;http://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt;
&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
p, li { white-space: pre-wrap; }
&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'DejaVu Sans'; font-size:9pt; font-weight:400; font-style:normal;&quot;&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-family:'Ubuntu'; font-size:11pt;&quot;&gt;P1-P3 # Stress intensity stress equation. Available values are numpy array format. Calculation np.funtion can be used on available values. &lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="user_def_head_1">
<property name="text">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;span style=&quot; text-decoration: underline;&quot;&gt;Available result types:&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="user_def_head_2">
<property name="minimumSize">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>16777215</width>
<height>16777215</height>
</size>
</property>
<property name="lineWidth">
<number>1</number>
</property>
<property name="text">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;displacement (x,y,z) and strain (ex,ey,ez)&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="scaledContents">
<bool>false</bool>
</property>
<property name="alignment">
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
</property>
<property name="wordWrap">
<bool>false</bool>
</property>
<property name="indent">
<number>-1</number>
</property>
<property name="textInteractionFlags">
<set>Qt::NoTextInteraction</set>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="user_def_head_3">
<property name="minimumSize">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>16777215</width>
<height>16777215</height>
</size>
</property>
<property name="lineWidth">
<number>1</number>
</property>
<property name="text">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;stresses (sx,sy,sz) and principal stresses (P1,P2,P3)&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="scaledContents">
<bool>false</bool>
</property>
<property name="alignment">
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
</property>
<property name="wordWrap">
<bool>false</bool>
</property>
<property name="indent">
<number>-1</number>
</property>
<property name="textInteractionFlags">
<set>Qt::NoTextInteraction</set>
</property>
</widget>
</item>
</layout>
&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'Ubuntu'; font-size:11pt; font-weight:400; font-style:normal;&quot;&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;P1-P3 # Stress intensity stress equation. Available values are numpy array format. Calculation np.funtion can be used on available values. &lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="user_def_head_1">
<property name="text">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;span style=&quot; text-decoration: underline;&quot;&gt;Available result types:&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="user_def_head_2">
<property name="minimumSize">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>16777215</width>
<height>16777215</height>
</size>
</property>
<property name="lineWidth">
<number>1</number>
</property>
<property name="text">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;displacement (x,y,z) and strain (ex,ey,ez)&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="scaledContents">
<bool>false</bool>
</property>
<property name="alignment">
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
</property>
<property name="wordWrap">
<bool>false</bool>
</property>
<property name="indent">
<number>-1</number>
</property>
<property name="textInteractionFlags">
<set>Qt::NoTextInteraction</set>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="user_def_head_3">
<property name="minimumSize">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>16777215</width>
<height>16777215</height>
</size>
</property>
<property name="lineWidth">
<number>1</number>
</property>
<property name="text">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;stresses (sx,sy,sz) and principal stresses (P1,P2,P3)&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="scaledContents">
<bool>false</bool>
</property>
<property name="alignment">
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
</property>
<property name="wordWrap">
<bool>false</bool>
</property>
<property name="indent">
<number>-1</number>
</property>
<property name="textInteractionFlags">
<set>Qt::NoTextInteraction</set>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>240</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
</layout>
</widget>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>92</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>

View File

@ -61,6 +61,10 @@ class _TaskPanelShowResult:
QtCore.QObject.connect(self.form.rb_maxprin, QtCore.SIGNAL("toggled(bool)"), self.max_prin_selected)
QtCore.QObject.connect(self.form.rb_minprin, QtCore.SIGNAL("toggled(bool)"), self.min_prin_selected)
QtCore.QObject.connect(self.form.rb_max_shear_stress, QtCore.SIGNAL("toggled(bool)"), self.max_shear_selected)
QtCore.QObject.connect(self.form.rb_massflowrate, QtCore.SIGNAL("toggled(bool)"), self.massflowrate_selected)
QtCore.QObject.connect(self.form.rb_networkpressure, QtCore.SIGNAL("toggled(bool)"), self.networkpressure_selected)
QtCore.QObject.connect(self.form.user_def_eq, QtCore.SIGNAL("textchanged()"), self.user_defined_text)
QtCore.QObject.connect(self.form.calculate, QtCore.SIGNAL("clicked()"), self.calculate)
# displacement
QtCore.QObject.connect(self.form.cb_show_displacement, QtCore.SIGNAL("clicked(bool)"), self.show_displacement)
@ -111,6 +115,12 @@ class _TaskPanelShowResult:
elif rt == "MaxShear":
self.form.rb_max_shear_stress.setChecked(True)
self.max_shear_selected(True)
elif rt == "MFlow":
self.form.rb_massflowrate.setChecked(True)
self.massflowrate_selected(True)
elif rt == "NPress":
self.form.rb_networkpressure.setChecked(True)
self.networkpressure_selected(True)
sd = FreeCAD.FEM_dialog["show_disp"]
self.form.cb_show_displacement.setChecked(sd)
@ -209,6 +219,28 @@ class _TaskPanelShowResult:
self.set_result_stats("K", minm, avg, maxm)
QtGui.qApp.restoreOverrideCursor()
def massflowrate_selected(self, state):
FreeCAD.FEM_dialog["results_type"] = "MFlow"
QApplication.setOverrideCursor(Qt.WaitCursor)
if self.suitable_results:
self.mesh_obj.ViewObject.setNodeColorByScalars(self.result_obj.NodeNumbers, self.result_obj.MassFlowRate)
minm = min(self.result_obj.MassFlowRate)
avg = sum(self.result_obj.MassFlowRate) / len(self.result_obj.MassFlowRate)
maxm = max(self.result_obj.MassFlowRate)
self.set_result_stats("kg/s", minm, avg, maxm)
QtGui.qApp.restoreOverrideCursor()
def networkpressure_selected(self, state):
FreeCAD.FEM_dialog["results_type"] = "NPress"
QApplication.setOverrideCursor(Qt.WaitCursor)
if self.suitable_results:
self.mesh_obj.ViewObject.setNodeColorByScalars(self.result_obj.NodeNumbers, self.result_obj.NetworkPressure)
minm = min(self.result_obj.NetworkPressure)
avg = sum(self.result_obj.NetworkPressure) / len(self.result_obj.NetworkPressure)
maxm = max(self.result_obj.NetworkPressure)
self.set_result_stats("MPa", minm, avg, maxm)
QtGui.qApp.restoreOverrideCursor()
def min_prin_selected(self, state):
FreeCAD.FEM_dialog["results_type"] = "MinPrin"
QApplication.setOverrideCursor(Qt.WaitCursor)
@ -232,6 +264,8 @@ class _TaskPanelShowResult:
P3 = np.array(self.result_obj.PrincipalMin)
Von = np.array(self.result_obj.StressValues)
T = np.array(self.result_obj.Temperature)
MF = np.array(self.result_obj.MassFlowRate)
NP = np.array(self.result_obj.NetworkPressure)
dispvectors = np.array(self.result_obj.DisplacementVectors)
x = np.array(dispvectors[:, 0])
y = np.array(dispvectors[:, 1])
@ -256,7 +290,7 @@ class _TaskPanelShowResult:
self.mesh_obj.ViewObject.setNodeColorByScalars(self.result_obj.NodeNumbers, UserDefinedFormula)
self.set_result_stats("", minm, avg, maxm)
QtGui.qApp.restoreOverrideCursor()
del x, y, z, T, Von, P1, P2, P3, sx, sy, sz, ex, ey, ez # Dummy use to get around flake8, varibles not being used
del x, y, z, T, Von, P1, P2, P3, sx, sy, sz, ex, ey, ez, MF, NP # Dummy use to get around flake8, varibles not being used
def select_displacement_type(self, disp_type):
QApplication.setOverrideCursor(Qt.WaitCursor)
@ -322,7 +356,9 @@ class _TaskPanelShowResult:
StressValues --> rb_vm_stress
PrincipalMax --> rb_maxprin
PrincipalMin --> rb_minprin
MaxShear --> rb_max_shear_stress'''
MaxShear --> rb_max_shear_stress
MassFlowRate --> rb_massflowrate
NetworkPressure --> rb_networkpressure'''
if len(self.result_obj.DisplacementLengths) == 0:
self.form.rb_abs_displacement.setEnabled(0)
if len(self.result_obj.DisplacementVectors) == 0:
@ -339,12 +375,16 @@ class _TaskPanelShowResult:
self.form.rb_minprin.setEnabled(0)
if len(self.result_obj.MaxShear) == 0:
self.form.rb_max_shear_stress.setEnabled(0)
if len(self.result_obj.MassFlowRate) == 0:
self.form.rb_massflowrate.setEnabled(0)
if len(self.result_obj.NetworkPressure) == 0:
self.form.rb_networkpressure.setEnabled(0)
def update(self):
self.suitable_results = False
self.disable_empty_result_buttons()
if (self.mesh_obj.FemMesh.NodeCount == len(self.result_obj.NodeNumbers)):
self.suitable_results = True
self.disable_empty_result_buttons()
self.mesh_obj.ViewObject.Visibility = True
hide_parts_constraints()
else:

View File

@ -67,6 +67,10 @@ class _FemResultMechanical():
obj.addProperty("App::PropertyFloatList", "MaxShear", "Fem", "List of Maximum Shear stress values", True)
obj.addProperty("App::PropertyFloatList", "MassFlowRate", "Fem", "List of mass flow rate values", True)
obj.addProperty("App::PropertyFloatList", "NetworkPressure", "Fem", "List of network pressure values", True)
obj.addProperty("App::PropertyFloatList", "UserDefined", "Fem", "User Defined Results", True)
# temperature field is needed in the thermal stress analysis

View File

@ -114,31 +114,123 @@ def importFrd(filename, analysis=None, result_name_prefix=None):
results.Mesh = m
break
disp = result_set['disp']
stressv = result_set['stressv']
strainv = result_set['strainv']
no_of_values = len(disp)
displacement = []
for k, v in disp.items():
displacement.append(v)
try:
disp = result_set['disp']
stressv = result_set['stressv']
strainv = result_set['strainv']
no_of_values = len(disp)
displacement = []
for k, v in disp.items():
displacement.append(v)
x_max, y_max, z_max = map(max, zip(*displacement))
if eigenmode_number > 0:
max_disp = max(x_max, y_max, z_max)
# Allow for max displacement to be 0.1% of the span
# FIXME - add to Preferences
max_allowed_disp = 0.001 * span
scale = max_allowed_disp / max_disp
else:
scale = 1.0
x_max, y_max, z_max = map(max, zip(*displacement))
if eigenmode_number > 0:
max_disp = max(x_max, y_max, z_max)
# Allow for max displacement to be 0.1% of the span
# FIXME - add to Preferences
max_allowed_disp = 0.001 * span
scale = max_allowed_disp / max_disp
else:
scale = 1.0
if len(disp) > 0:
results.DisplacementVectors = list(map((lambda x: x * scale), disp.values()))
results.StressVectors = list(map((lambda x: x * scale), stressv.values()))
results.StrainVectors = list(map((lambda x: x * scale), strainv.values()))
results.NodeNumbers = list(disp.keys())
if(mesh_object):
results.Mesh = mesh_object
if len(disp) > 0:
results.DisplacementVectors = list(map((lambda x: x * scale), disp.values()))
results.StressVectors = list(map((lambda x: x * scale), stressv.values()))
results.StrainVectors = list(map((lambda x: x * scale), strainv.values()))
results.NodeNumbers = disp.keys()
if(mesh_object):
results.Mesh = mesh_object
stress = result_set['stress']
if len(stress) > 0:
mstress = []
prinstress1 = []
prinstress2 = []
prinstress3 = []
shearstress = []
for i in stress.values():
mstress.append(calculate_von_mises(i))
prin1, prin2, prin3, shear = calculate_principal_stress(i)
prinstress1.append(prin1)
prinstress2.append(prin2)
prinstress3.append(prin3)
shearstress.append(shear)
if eigenmode_number > 0:
results.StressValues = list(map((lambda x: x * scale), mstress))
results.PrincipalMax = list(map((lambda x: x * scale), prinstress1))
results.PrincipalMed = list(map((lambda x: x * scale), prinstress2))
results.PrincipalMin = list(map((lambda x: x * scale), prinstress3))
results.MaxShear = list(map((lambda x: x * scale), shearstress))
results.Eigenmode = eigenmode_number
else:
results.StressValues = mstress
results.PrincipalMax = prinstress1
results.PrincipalMed = prinstress2
results.PrincipalMin = prinstress3
results.MaxShear = shearstress
if (results.NodeNumbers != 0 and results.NodeNumbers != stress.keys()):
print("Inconsistent FEM results: element number for Stress doesn't equal element number for Displacement {} != {}"
.format(results.NodeNumbers, len(results.StressValues)))
results.NodeNumbers = stress.keys()
x_min, y_min, z_min = map(min, zip(*displacement))
sum_list = map(sum, zip(*displacement))
x_avg, y_avg, z_avg = [i / no_of_values for i in sum_list]
s_max = max(results.StressValues)
s_min = min(results.StressValues)
s_avg = sum(results.StressValues) / no_of_values
p1_min = min(results.PrincipalMax)
p1_avg = sum(results.PrincipalMax) / no_of_values
p1_max = max(results.PrincipalMax)
p2_min = min(results.PrincipalMed)
p2_avg = sum(results.PrincipalMed) / no_of_values
p2_max = max(results.PrincipalMed)
p3_min = min(results.PrincipalMin)
p3_avg = sum(results.PrincipalMin) / no_of_values
p3_max = max(results.PrincipalMin)
ms_min = min(results.MaxShear)
ms_avg = sum(results.MaxShear) / no_of_values
ms_max = max(results.MaxShear)
disp_abs = []
for d in displacement:
disp_abs.append(sqrt(pow(d[0], 2) + pow(d[1], 2) + pow(d[2], 2)))
results.DisplacementLengths = disp_abs
a_max = max(disp_abs)
a_min = min(disp_abs)
a_avg = sum(disp_abs) / no_of_values
results.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]
except:
pass
# Read Equivalent Plastic strain if they exist
try:
Peeq = result_set['peeq']
if len(Peeq) > 0:
if len(Peeq.values()) != len(disp.values()):
Pe = []
Pe_extra_nodes = Peeq.values()
nodes = len(disp.values())
for i in range(nodes):
Pe_value = Pe_extra_nodes[i]
Pe.append(Pe_value)
results.Peeq = Pe
else:
results.Peeq = Peeq.values()
except:
pass
# Read temperatures if they exist
try:
@ -158,96 +250,22 @@ def importFrd(filename, analysis=None, result_name_prefix=None):
except:
pass
stress = result_set['stress']
if len(stress) > 0:
mstress = []
prinstress1 = []
prinstress2 = []
prinstress3 = []
shearstress = []
for i in stress.values():
mstress.append(calculate_von_mises(i))
prin1, prin2, prin3, shear = calculate_principal_stress(i)
prinstress1.append(prin1)
prinstress2.append(prin2)
prinstress3.append(prin3)
shearstress.append(shear)
if eigenmode_number > 0:
results.StressValues = list(map((lambda x: x * scale), mstress))
results.PrincipalMax = list(map((lambda x: x * scale), prinstress1))
results.PrincipalMed = list(map((lambda x: x * scale), prinstress2))
results.PrincipalMin = list(map((lambda x: x * scale), prinstress3))
results.MaxShear = list(map((lambda x: x * scale), shearstress))
results.Eigenmode = eigenmode_number
else:
results.StressValues = mstress
results.PrincipalMax = prinstress1
results.PrincipalMed = prinstress2
results.PrincipalMin = prinstress3
results.MaxShear = shearstress
if (results.NodeNumbers != 0 and results.NodeNumbers != list(stress.keys())):
print("Inconsistent FEM results: element number for Stress doesn't equal element number for Displacement {} != {}"
.format(results.NodeNumbers, len(results.StressValues)))
results.NodeNumbers = list(stress.keys())
# Read Equivalent Plastic strain if they exist
try:
Peeq = result_set['peeq']
if len(Peeq) > 0:
if len(Peeq.values()) != len(disp.values()):
Pe = []
Pe_extra_nodes = Peeq.values()
nodes = len(disp.values())
for i in range(nodes):
Pe_value = Pe_extra_nodes[i]
Pe.append(Pe_value)
results.Peeq = Pe
else:
results.Peeq = Peeq.values()
MassFlow = result_set['mflow']
if len(MassFlow) > 0:
results.MassFlowRate = list(map((lambda x: x), MassFlow.values()))
results.Time = step_time
except:
pass
x_min, y_min, z_min = map(min, zip(*displacement))
sum_list = map(sum, zip(*displacement))
x_avg, y_avg, z_avg = [i / no_of_values for i in sum_list]
try:
NetworkPressure = result_set['npressure']
if len(NetworkPressure) > 0:
results.NetworkPressure = list(map((lambda x: x), NetworkPressure.values()))
results.Time = step_time
except:
pass
s_max = max(results.StressValues)
s_min = min(results.StressValues)
s_avg = sum(results.StressValues) / no_of_values
p1_min = min(results.PrincipalMax)
p1_avg = sum(results.PrincipalMax) / no_of_values
p1_max = max(results.PrincipalMax)
p2_min = min(results.PrincipalMed)
p2_avg = sum(results.PrincipalMed) / no_of_values
p2_max = max(results.PrincipalMed)
p3_min = min(results.PrincipalMin)
p3_avg = sum(results.PrincipalMin) / no_of_values
p3_max = max(results.PrincipalMin)
ms_min = min(results.MaxShear)
ms_avg = sum(results.MaxShear) / no_of_values
ms_max = max(results.MaxShear)
disp_abs = []
for d in displacement:
disp_abs.append(sqrt(pow(d[0], 2) + pow(d[1], 2) + pow(d[2], 2)))
results.DisplacementLengths = disp_abs
a_max = max(disp_abs)
a_min = min(disp_abs)
a_avg = sum(disp_abs) / no_of_values
results.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]
analysis_object.Member = analysis_object.Member + [results]
if(FreeCAD.GuiUp):
@ -257,6 +275,18 @@ def importFrd(filename, analysis=None, result_name_prefix=None):
# read a calculix result file and extract the nodes, displacement vectores and stress values.
def readResult(frd_input):
inout_nodes_exist = False
if os.path.exists("inout_nodes.txt"):
inout_nodes = []
f = pyopen("inout_nodes.txt", "r")
lines = f.readlines()
for line in lines:
a = line.split(',')
inout_nodes.append(a)
if len(inout_nodes) > 0:
inout_nodes_exist = True
f.close()
os.remove("inout_nodes.txt")
frd_file = pyopen(frd_input, "r")
nodes = {}
elements_hexa8 = {}
@ -279,6 +309,8 @@ def readResult(frd_input):
mode_strain = {}
mode_peeq = {}
mode_temp = {}
mode_massflow = {}
mode_networkpressure = {}
mode_disp_found = False
nodes_found = False
@ -286,6 +318,8 @@ def readResult(frd_input):
mode_strain_found = False
mode_peeq_found = False
mode_temp_found = False
mode_massflow_found = False
mode_networkpressure_found = False
mode_time_found = False
elements_found = False
input_continues = False
@ -479,7 +513,14 @@ def readResult(frd_input):
nd1 = int(line[3:13])
nd3 = int(line[13:23])
nd2 = int(line[23:33])
elements_seg3[elem] = (nd1, nd2, nd3)
if inout_nodes_exist:
for i in range(len(inout_nodes)):
if nd1 == int(inout_nodes[i][1]):
elements_seg3[elem] = (int(inout_nodes[i][2]), nd3, nd1) # fluid inlet node numbering
elif nd3 == int(inout_nodes[i][1]):
elements_seg3[elem] = (nd1, int(inout_nodes[i][2]), nd3) # fluid outlet node numbering
else:
elements_seg3[elem] = (nd1, nd2, nd3) # normal node numbering for D, B32 elements
# Check if we found new eigenmode
if line[5:10] == "PMODE":
@ -541,6 +582,30 @@ def readResult(frd_input):
elem = int(line[4:13])
temperature = float(line[13:25])
mode_temp[elem] = (temperature)
if line[5:11] == "MAFLOW":
mode_massflow_found = True
# we found a mass flow line in the frd file
if mode_massflow_found and (line[1:3] == "-1"):
elem = int(line[4:13])
massflow = float(line[13:25])
mode_massflow[elem] = (massflow * 1000) # convert units to kg/s from t/s
if inout_nodes_exist:
for i in range(len(inout_nodes)):
if elem == int(inout_nodes[i][1]):
node = int(inout_nodes[i][2])
mode_massflow[node] = (massflow * 1000) # convert units to kg/s from t/s
if line[5:11] == "STPRES":
mode_networkpressure_found = True
# we found a network pressure line in the frd file
if mode_networkpressure_found and (line[1:3] == "-1"):
elem = int(line[4:13])
networkpressure = float(line[13:25])
mode_networkpressure[elem] = (networkpressure)
if inout_nodes_exist:
for i in range(len(inout_nodes)):
if elem == int(inout_nodes[i][1]):
node = int(inout_nodes[i][2])
mode_networkpressure[node] = (networkpressure)
# Check for the end of a section
if line[1:3] == "-3":
if mode_disp_found:
@ -561,6 +626,12 @@ def readResult(frd_input):
if mode_time_found:
mode_time_found = False
if mode_massflow_found:
mode_massflow_found = False
if mode_networkpressure_found:
mode_networkpressure_found = False
if mode_disp and mode_stress and mode_temp:
mode_results = {}
mode_results['number'] = eigenmode
@ -590,6 +661,17 @@ def readResult(frd_input):
mode_disp = {}
mode_stress = {}
eigenmode = 0
if mode_massflow and mode_networkpressure:
mode_results = {}
mode_results['number'] = eigenmode
mode_results['mflow'] = mode_massflow
mode_results['npressure'] = mode_networkpressure
mode_results['time'] = timestep
results.append(mode_results)
mode_massflow = {}
mode_networkpressure = {}
eigenmode = 0
nodes_found = False
elements_found = False