[FEM] enable to run Elmer multi-threaded
- this needs proper testing, especially on a non-Windows system - note that for some tasks multi-threading requires non-standard additional solvers like MUMPS. Ideally the user should be informed about this, depending on the equations he uses. But this should not block this PR, meaning to use multi-threading in general.
This commit is contained in:
@@ -1879,7 +1879,7 @@ void FemMesh::read(const char *FileName)
|
||||
readNastran(File.filePath());
|
||||
}
|
||||
#ifdef FC_USE_VTK
|
||||
else if (File.hasExtension("vtk") || File.hasExtension("vtu")) {
|
||||
else if (File.hasExtension("vtk") || File.hasExtension("vtu") || File.hasExtension("pvtu")) {
|
||||
// read *.vtk legacy format or *.vtu XML unstructure Mesh
|
||||
FemVTKTools::readVTKMesh(File.filePath().c_str(), this);
|
||||
}
|
||||
|
||||
@@ -33,6 +33,7 @@
|
||||
# include <vtkRectilinearGrid.h>
|
||||
# include <vtkAppendFilter.h>
|
||||
# include <vtkXMLUnstructuredGridReader.h>
|
||||
# include <vtkXMLPUnstructuredGridReader.h>
|
||||
# include <vtkXMLPolyDataReader.h>
|
||||
# include <vtkXMLStructuredGridReader.h>
|
||||
# include <vtkXMLRectilinearGridReader.h>
|
||||
@@ -121,7 +122,8 @@ bool FemPostPipeline::canRead(Base::FileInfo File) {
|
||||
File.hasExtension("vts") ||
|
||||
File.hasExtension("vtr") ||
|
||||
File.hasExtension("vti") ||
|
||||
File.hasExtension("vtu"))
|
||||
File.hasExtension("vtu") ||
|
||||
File.hasExtension("pvtu"))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
@@ -135,6 +137,8 @@ void FemPostPipeline::read(Base::FileInfo File) {
|
||||
|
||||
if (File.hasExtension("vtu"))
|
||||
readXMLFile<vtkXMLUnstructuredGridReader>(File.filePath());
|
||||
else if (File.hasExtension("pvtu"))
|
||||
readXMLFile<vtkXMLPUnstructuredGridReader>(File.filePath());
|
||||
else if (File.hasExtension("vtp"))
|
||||
readXMLFile<vtkXMLPolyDataReader>(File.filePath());
|
||||
else if (File.hasExtension("vts"))
|
||||
|
||||
@@ -53,6 +53,7 @@
|
||||
# include <vtkRectilinearGrid.h>
|
||||
# include <vtkUnstructuredGrid.h>
|
||||
# include <vtkXMLUnstructuredGridReader.h>
|
||||
# include <vtkXMLPUnstructuredGridReader.h>
|
||||
# include <vtkXMLUnstructuredGridWriter.h>
|
||||
# include <vtkPointData.h>
|
||||
# include <vtkCellData.h>
|
||||
@@ -215,6 +216,14 @@ FemMesh* FemVTKTools::readVTKMesh(const char* filename, FemMesh* mesh)
|
||||
}
|
||||
importVTKMesh(dataset, mesh);
|
||||
}
|
||||
else if (f.hasExtension("pvtu")) {
|
||||
vtkSmartPointer<vtkDataSet> dataset = readVTKFile<vtkXMLPUnstructuredGridReader>(filename);
|
||||
if (!dataset.Get()) {
|
||||
Base::Console().Error("Failed to load file %s\n", filename);
|
||||
return nullptr;
|
||||
}
|
||||
importVTKMesh(dataset, mesh);
|
||||
}
|
||||
else if(f.hasExtension("vtk"))
|
||||
{
|
||||
vtkSmartPointer<vtkDataSet> dataset = readVTKFile<vtkDataSetReader>(filename);
|
||||
|
||||
@@ -202,6 +202,7 @@
|
||||
#include <vtkXMLPolyDataReader.h>
|
||||
#include <vtkXMLStructuredGridReader.h>
|
||||
#include <vtkXMLUnstructuredGridReader.h>
|
||||
#include <vtkXMLPUnstructuredGridReader.h>
|
||||
#include <vtkXMLRectilinearGridReader.h>
|
||||
#include <vtkXMLImageDataReader.h>
|
||||
|
||||
|
||||
@@ -7,205 +7,247 @@
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>400</width>
|
||||
<height>199</height>
|
||||
<height>203</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Elmer</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<property name="spacing">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<item>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||
<item>
|
||||
<widget class="QGroupBox" name="gb_gmsh_param">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="layoutDirection">
|
||||
<enum>Qt::LeftToRight</enum>
|
||||
</property>
|
||||
<property name="title">
|
||||
<string>Elmer binaries</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
|
||||
</property>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||
<property name="sizeConstraint">
|
||||
<enum>QLayout::SetNoConstraint</enum>
|
||||
<widget class="QGroupBox" name="gb_gmsh_param">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="layoutDirection">
|
||||
<enum>Qt::LeftToRight</enum>
|
||||
</property>
|
||||
<property name="title">
|
||||
<string>Elmer binaries</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="l_grid_binary_std">
|
||||
<property name="text">
|
||||
<string>ElmerGrid:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="Gui::PrefCheckBox" name="cb_grid_binary_std">
|
||||
<property name="text">
|
||||
<string>Search in known binary directories</string>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="prefEntry" stdset="0">
|
||||
<cstring>UseStandardGridLocation</cstring>
|
||||
</property>
|
||||
<property name="prefPath" stdset="0">
|
||||
<cstring>Mod/Fem/Elmer</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="l_grid_binary_path">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>100</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>ElmerGrid binary path</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="Gui::PrefFileChooser" name="fc_grid_binary_path">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="sizeIncrement">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="baseSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Leave blank to use default ElmerGrid binary file</string>
|
||||
</property>
|
||||
<property name="prefEntry" stdset="0">
|
||||
<cstring>gridBinaryPath</cstring>
|
||||
</property>
|
||||
<property name="prefPath" stdset="0">
|
||||
<cstring>Mod/Fem/Elmer</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="l_elmer_binary_std">
|
||||
<property name="text">
|
||||
<string>ElmerSolver:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="Gui::PrefCheckBox" name="cb_elmer_binary_std">
|
||||
<property name="text">
|
||||
<string>Search in known binary directories</string>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="prefEntry" stdset="0">
|
||||
<cstring>UseStandardElmerLocation</cstring>
|
||||
</property>
|
||||
<property name="prefPath" stdset="0">
|
||||
<cstring>Mod/Fem/Elmer</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="QLabel" name="l_elmer_binary_path">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>100</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>ElmerSolver binary path</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="1">
|
||||
<widget class="Gui::PrefFileChooser" name="fc_elmer_binary_path">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="sizeIncrement">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="baseSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>Leave blank to use default Elmer elmer binary file</p><p><span style=" font-weight:600;">Note:</span> To use multithreading you must specify here<br> the executable variant with the suffix &quot;_mpi&quot;.</p></body></html></string>
|
||||
</property>
|
||||
<property name="prefEntry" stdset="0">
|
||||
<cstring>elmerBinaryPath</cstring>
|
||||
</property>
|
||||
<property name="prefPath" stdset="0">
|
||||
<cstring>Mod/Fem/Elmer</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="0">
|
||||
<widget class="QLabel" name="l_elmer_binary_std_2">
|
||||
<property name="text">
|
||||
<string>Multithreading:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="1">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<layout class="QGridLayout" name="gl_01">
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="l_grid_binary_std">
|
||||
<property name="text">
|
||||
<string>ElmerGrid:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="Gui::PrefCheckBox" name="cb_grid_binary_std">
|
||||
<property name="text">
|
||||
<string>Search in known binary directories</string>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="prefEntry" stdset="0">
|
||||
<cstring>UseStandardGridLocation</cstring>
|
||||
</property>
|
||||
<property name="prefPath" stdset="0">
|
||||
<cstring>Mod/Fem/Elmer</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="l_grid_binary_path">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>100</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>ElmerGrid binary path</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="Gui::PrefFileChooser" name="fc_grid_binary_path">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="sizeIncrement">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="baseSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Leave blank to use default ElmerGrid binary file</string>
|
||||
</property>
|
||||
<property name="prefEntry" stdset="0">
|
||||
<cstring>gridBinaryPath</cstring>
|
||||
</property>
|
||||
<property name="prefPath" stdset="0">
|
||||
<cstring>Mod/Fem/Elmer</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="QLabel" name="l_elmer_binary_std">
|
||||
<property name="text">
|
||||
<string>ElmerSolver:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="1">
|
||||
<widget class="Gui::PrefCheckBox" name="cb_elmer_binary_std">
|
||||
<property name="text">
|
||||
<string>Search in known binary directories</string>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="prefEntry" stdset="0">
|
||||
<cstring>UseStandardElmerLocation</cstring>
|
||||
</property>
|
||||
<property name="prefPath" stdset="0">
|
||||
<cstring>Mod/Fem/Elmer</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="0">
|
||||
<widget class="QLabel" name="l_elmer_binary_path">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>100</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>ElmerSolver binary path</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="1">
|
||||
<widget class="Gui::PrefFileChooser" name="fc_elmer_binary_path">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="sizeIncrement">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="baseSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Leave blank to use default Elmer elmer binary file</string>
|
||||
</property>
|
||||
<property name="prefEntry" stdset="0">
|
||||
<cstring>elmerBinaryPath</cstring>
|
||||
</property>
|
||||
<property name="prefPath" stdset="0">
|
||||
<cstring>Mod/Fem/Elmer</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
<widget class="QLabel" name="label_cores">
|
||||
<property name="enabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>CPU cores to be used:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="Gui::PrefSpinBox" name="sb_elmer_num_cores">
|
||||
<property name="enabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p><span style=" font-weight:600;">Note:</span> It is recommended to use an even number of cores to benefit from mesh symmetries. (Using 8 cores can be faster than 9 cores.)<br/><span style=" font-weight:600;">Note too:</span> In extreme cases ElmerSolver might not converge if the core number is too high.</p></body></html></string>
|
||||
</property>
|
||||
<property name="minimum">
|
||||
<number>1</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>32</number>
|
||||
</property>
|
||||
<property name="prefEntry" stdset="0">
|
||||
<cstring>UseNumberOfCores</cstring>
|
||||
</property>
|
||||
<property name="prefPath" stdset="0">
|
||||
<cstring>Mod/Fem/Elmer</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="verticalSpacer">
|
||||
@@ -218,7 +260,7 @@
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>40</height>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
@@ -237,6 +279,11 @@
|
||||
<extends>Gui::FileChooser</extends>
|
||||
<header>Gui/PrefWidgets.h</header>
|
||||
</customwidget>
|
||||
<customwidget>
|
||||
<class>Gui::PrefSpinBox</class>
|
||||
<extends>QSpinBox</extends>
|
||||
<header>Gui/PrefWidgets.h</header>
|
||||
</customwidget>
|
||||
<customwidget>
|
||||
<class>Gui::PrefCheckBox</class>
|
||||
<extends>QCheckBox</extends>
|
||||
@@ -279,22 +326,6 @@
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>cb_elmer_binary_std</sender>
|
||||
<signal>toggled(bool)</signal>
|
||||
<receiver>l_elmer_binary_path</receiver>
|
||||
<slot>setDisabled(bool)</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>247</x>
|
||||
<y>91</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>71</x>
|
||||
<y>114</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>cb_elmer_binary_std</sender>
|
||||
<signal>toggled(bool)</signal>
|
||||
@@ -311,5 +342,21 @@
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>cb_elmer_binary_std</sender>
|
||||
<signal>toggled(bool)</signal>
|
||||
<receiver>l_elmer_binary_path</receiver>
|
||||
<slot>setDisabled(bool)</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>247</x>
|
||||
<y>91</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>71</x>
|
||||
<y>114</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
</connections>
|
||||
</ui>
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
|
||||
#include "PreCompiled.h"
|
||||
#ifndef _PreComp_
|
||||
# include <thread>
|
||||
# include <QMessageBox>
|
||||
#endif
|
||||
|
||||
@@ -39,10 +40,20 @@ DlgSettingsFemElmerImp::DlgSettingsFemElmerImp(QWidget* parent)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
|
||||
// determine number of CPU cores
|
||||
processor_count = std::thread::hardware_concurrency();
|
||||
// hardware check might fail and then returns 0
|
||||
if (processor_count > 0)
|
||||
ui->sb_elmer_num_cores->setMaximum(processor_count);
|
||||
|
||||
connect(ui->fc_grid_binary_path, &Gui::PrefFileChooser::fileNameChanged,
|
||||
this, &DlgSettingsFemElmerImp::onfileNameChanged);
|
||||
connect(ui->fc_elmer_binary_path, &Gui::PrefFileChooser::fileNameChanged,
|
||||
this, &DlgSettingsFemElmerImp::onfileNameChanged);
|
||||
connect(ui->fc_elmer_binary_path, &Gui::PrefFileChooser::fileNameChanged,
|
||||
this, &DlgSettingsFemElmerImp::onfileNameChanged);
|
||||
this, &DlgSettingsFemElmerImp::onfileNameChangedMT);
|
||||
connect(ui->sb_elmer_num_cores, qOverload<int>(&Gui::PrefSpinBox::valueChanged),
|
||||
this, &DlgSettingsFemElmerImp::onCoresValueChanged);
|
||||
}
|
||||
|
||||
DlgSettingsFemElmerImp::~DlgSettingsFemElmerImp()
|
||||
@@ -57,6 +68,8 @@ void DlgSettingsFemElmerImp::saveSettings()
|
||||
|
||||
ui->cb_grid_binary_std->onSave();
|
||||
ui->fc_grid_binary_path->onSave();
|
||||
|
||||
ui->sb_elmer_num_cores->onSave();
|
||||
}
|
||||
|
||||
void DlgSettingsFemElmerImp::loadSettings()
|
||||
@@ -66,6 +79,8 @@ void DlgSettingsFemElmerImp::loadSettings()
|
||||
|
||||
ui->cb_grid_binary_std->onRestore();
|
||||
ui->fc_grid_binary_path->onRestore();
|
||||
|
||||
ui->sb_elmer_num_cores->onRestore();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -91,4 +106,44 @@ void DlgSettingsFemElmerImp::onfileNameChanged(QString FileName)
|
||||
}
|
||||
}
|
||||
|
||||
void DlgSettingsFemElmerImp::onfileNameChangedMT(QString FileName)
|
||||
{
|
||||
// reset in case it was prevoisly set to 1
|
||||
ui->sb_elmer_num_cores->setMaximum(processor_count);
|
||||
|
||||
if (ui->sb_elmer_num_cores->value() == 1)
|
||||
return;
|
||||
|
||||
auto strName = FileName.toStdString();
|
||||
#if defined(FC_OS_WIN32)
|
||||
// name ends with "_mpi.exe"
|
||||
if (strName.substr(strName.length() - 8) != "_mpi.exe") {
|
||||
QMessageBox::warning(this, tr("Not suitable for mulithreading"),
|
||||
tr("You use more than one CPU core.\n"
|
||||
"Therefore an executable with the suffix '_mpi.exe' is required."));
|
||||
ui->sb_elmer_num_cores->setValue(1);
|
||||
ui->sb_elmer_num_cores->setMaximum(1);
|
||||
return;
|
||||
}
|
||||
#elif defined(FC_OS_LINUX) || defined(FC_OS_CYGWIN) || defined(FC_OS_MACOSX) || defined(FC_OS_BSD)
|
||||
// name ends with "_mpi"
|
||||
if (strName.substr(strName.length() - 4) != "_mpi") {
|
||||
QMessageBox::warning(this, tr("Not suitable for mulithreading"),
|
||||
tr("You use more than one CPU core.\n"
|
||||
"Therefore an executable with the suffix '_mpi' is required."));
|
||||
ui->sb_elmer_num_cores->setValue(1);
|
||||
ui->sb_elmer_num_cores->setMaximum(1);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void DlgSettingsFemElmerImp::onCoresValueChanged(int cores)
|
||||
{
|
||||
if (cores > 1) {
|
||||
// check if the right executable is loaded
|
||||
onfileNameChangedMT(ui->fc_elmer_binary_path->fileName());
|
||||
}
|
||||
}
|
||||
|
||||
#include "moc_DlgSettingsFemElmerImp.cpp"
|
||||
|
||||
@@ -41,6 +41,8 @@ public:
|
||||
|
||||
protected Q_SLOTS:
|
||||
void onfileNameChanged(QString FileName);
|
||||
void onfileNameChangedMT(QString FileName);
|
||||
void onCoresValueChanged(int cores);
|
||||
|
||||
protected:
|
||||
void saveSettings();
|
||||
@@ -49,6 +51,7 @@ protected:
|
||||
|
||||
private:
|
||||
std::unique_ptr<Ui_DlgSettingsFemElmerImp> ui;
|
||||
unsigned int processor_count;
|
||||
};
|
||||
|
||||
} // namespace FemGui
|
||||
|
||||
@@ -63,7 +63,7 @@ FreeCAD.addExportType("FEM mesh Python (*.meshpy)", "feminout.importPyMesh")
|
||||
FreeCAD.addExportType("FEM mesh TetGen (*.poly)", "feminout.convert2TetGen")
|
||||
|
||||
# see FemMesh::read() and FemMesh::write() methods in src/Mod/Fem/App/FemMesh.cpp
|
||||
FreeCAD.addImportType("FEM mesh formats (*.bdf *.dat *.inp *.med *.unv *.vtk *.vtu *.z88)", "Fem")
|
||||
FreeCAD.addImportType("FEM mesh formats (*.bdf *.dat *.inp *.med *.unv *.vtk *.vtu *.pvtu *.z88)", "Fem")
|
||||
FreeCAD.addExportType("FEM mesh formats (*.dat *.inp *.med *.stl *.unv *.vtk *.vtu *.z88)", "Fem")
|
||||
|
||||
FreeCAD.addExportType("FEM mesh Nastran (*.bdf)", "feminout.exportNastranMesh")
|
||||
@@ -86,5 +86,5 @@ FreeCAD.addExportType("FEM mesh Z88 (*i1.txt)", "feminout.importZ88Mesh")
|
||||
FreeCAD.addImportType("FEM result Z88 displacements (*o2.txt)", "feminout.importZ88O2Results")
|
||||
|
||||
if "BUILD_FEM_VTK" in FreeCAD.__cmake__:
|
||||
FreeCAD.addImportType("FEM result VTK (*.vtk *.vtu)", "feminout.importVTKResults")
|
||||
FreeCAD.addImportType("FEM result VTK (*.vtk *.vtu *.pvtu)", "feminout.importVTKResults")
|
||||
FreeCAD.addExportType("FEM result VTK (*.vtk *.vtu)", "feminout.importVTKResults")
|
||||
|
||||
@@ -121,10 +121,19 @@ class Solve(run.Solve):
|
||||
if os.path.isdir(solvpath):
|
||||
os.environ["ELMER_HOME"] = solvpath
|
||||
os.environ["LD_LIBRARY_PATH"] = "$LD_LIBRARY_PATH:{}/modules".format(solvpath)
|
||||
# hide the popups on Windows
|
||||
# different call depending if with multithreading or not
|
||||
num_cores = settings.get_cores("ElmerSolver")
|
||||
args = []
|
||||
if int(num_cores) > 1:
|
||||
if system() != "Windows":
|
||||
args.extend(["mpirun"])
|
||||
else:
|
||||
args.extend(["mpiexec"])
|
||||
args.extend(["-np", num_cores])
|
||||
args.extend([binary])
|
||||
if system() == "Windows":
|
||||
self._process = subprocess.Popen(
|
||||
[binary],
|
||||
args,
|
||||
cwd=self.directory,
|
||||
stdout=subprocess.PIPE,
|
||||
stderr=subprocess.PIPE,
|
||||
@@ -132,7 +141,7 @@ class Solve(run.Solve):
|
||||
)
|
||||
else:
|
||||
self._process = subprocess.Popen(
|
||||
[binary],
|
||||
args,
|
||||
cwd=self.directory,
|
||||
stdout=subprocess.PIPE,
|
||||
stderr=subprocess.PIPE
|
||||
@@ -190,12 +199,16 @@ class Results(run.Results):
|
||||
# elmer post file path changed with version x.x
|
||||
# see https://forum.freecadweb.org/viewtopic.php?f=18&t=42732
|
||||
# workaround
|
||||
possible_post_file_0 = os.path.join(self.directory, "case0001.vtu")
|
||||
possible_post_file_t = os.path.join(self.directory, "case_t0001.vtu")
|
||||
if os.path.isfile(possible_post_file_0):
|
||||
postPath = possible_post_file_0
|
||||
elif os.path.isfile(possible_post_file_t):
|
||||
postPath = possible_post_file_t
|
||||
possible_post_file_old = os.path.join(self.directory, "case0001.vtu")
|
||||
possible_post_file_single = os.path.join(self.directory, "case_t0001.vtu")
|
||||
possible_post_file_multi = os.path.join(self.directory, "case_t0001.pvtu")
|
||||
# first try the multi-thread result, then single then old name
|
||||
if os.path.isfile(possible_post_file_multi):
|
||||
postPath = possible_post_file_multi
|
||||
elif os.path.isfile(possible_post_file_single):
|
||||
postPath = possible_post_file_single
|
||||
elif os.path.isfile(possible_post_file_old):
|
||||
postPath = possible_post_file_old
|
||||
else:
|
||||
self.report.error("Result file not found.")
|
||||
self.fail()
|
||||
|
||||
@@ -216,23 +216,38 @@ class Writer(object):
|
||||
)
|
||||
else:
|
||||
binary = settings.get_binary("ElmerGrid")
|
||||
num_cores = settings.get_cores("ElmerGrid")
|
||||
if binary is None:
|
||||
raise WriteError("Could not find ElmerGrid binary.")
|
||||
args = [binary,
|
||||
_ELMERGRID_IFORMAT,
|
||||
_ELMERGRID_OFORMAT,
|
||||
unvPath,
|
||||
"-scale", "0.001", "0.001", "0.001",
|
||||
"-out", self.directory]
|
||||
# hide the popups on Windows
|
||||
# for multithreading we first need a normal mesh creation run
|
||||
# then a second to split the mesh into the number of used cores
|
||||
argsBasic = [binary,
|
||||
_ELMERGRID_IFORMAT,
|
||||
_ELMERGRID_OFORMAT,
|
||||
unvPath,
|
||||
"-scale", "0.001", "0.001", "0.001"]
|
||||
args = argsBasic
|
||||
args.extend(["-out", self.directory])
|
||||
if system() == "Windows":
|
||||
subprocess.call(
|
||||
args,
|
||||
stdout=subprocess.DEVNULL,
|
||||
stdout=subprocess.DEVNULL,
|
||||
startupinfo=femutils.startProgramInfo("hide")
|
||||
)
|
||||
else:
|
||||
subprocess.call(args, stdout=subprocess.DEVNULL)
|
||||
if int(num_cores) > 1:
|
||||
args = argsBasic
|
||||
args.extend(["-partdual", "-metiskway", num_cores,
|
||||
"-out", self.directory])
|
||||
if system() == "Windows":
|
||||
subprocess.call(
|
||||
args,
|
||||
stdout=subprocess.DEVNULL,
|
||||
startupinfo=femutils.startProgramInfo("hide")
|
||||
)
|
||||
else:
|
||||
subprocess.call(args, stdout=subprocess.DEVNULL)
|
||||
|
||||
def _writeStartinfo(self):
|
||||
path = os.path.join(self.directory, _STARTINFO_NAME)
|
||||
|
||||
@@ -94,10 +94,7 @@ def get_binary(name):
|
||||
"""
|
||||
if name in _SOLVER_PARAM:
|
||||
binary = _SOLVER_PARAM[name].get_binary()
|
||||
FreeCAD.Console.PrintMessage(
|
||||
'Solver binary path (returned from binary getter): {} \n'
|
||||
.format(binary)
|
||||
)
|
||||
FreeCAD.Console.PrintMessage('Solver binary path: {} \n'.format(binary))
|
||||
return binary
|
||||
else:
|
||||
FreeCAD.Console.PrintError(
|
||||
@@ -107,6 +104,28 @@ def get_binary(name):
|
||||
)
|
||||
return None
|
||||
|
||||
def get_cores(name):
|
||||
""" Read number of CPU cores for solver *name* honoring user settings.
|
||||
|
||||
Returns number of CPU cores to be used for the solvier run
|
||||
|
||||
:param name: solver id as a ``str`` (see :mod:`femsolver.settings`)
|
||||
"""
|
||||
if name in _SOLVER_PARAM:
|
||||
cores = _SOLVER_PARAM[name].get_cores()
|
||||
FreeCAD.Console.PrintMessage(
|
||||
'Number of CPU cores to be used for the solvier run: {} \n'
|
||||
.format(cores)
|
||||
)
|
||||
return cores
|
||||
else:
|
||||
FreeCAD.Console.PrintError(
|
||||
"Settings solver name: {} not found in "
|
||||
"solver settings modules _SOLVER_PARAM dirctionary.\n"
|
||||
.format(name)
|
||||
)
|
||||
return None
|
||||
|
||||
|
||||
def get_write_comments(name):
|
||||
""" Check whether "write_comments" is set for solver.
|
||||
@@ -220,6 +239,10 @@ class _SolverDlg(object):
|
||||
FreeCAD.Console.PrintLog("Solver binary found path: {}\n".format(the_found_binary))
|
||||
return the_found_binary
|
||||
|
||||
def get_cores(self):
|
||||
cores = str(self.param_group.GetInt("UseNumberOfCores"))
|
||||
return cores
|
||||
|
||||
def get_write_comments(self):
|
||||
return self.param_group.GetBool(self.WRITE_COMMENTS_PARAM, True)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user