Fem: Fix Elmer preferences file chooser

This commit is contained in:
marioalexis
2025-09-06 17:28:50 -03:00
parent 69cd8957f1
commit ffb24062d0
3 changed files with 69 additions and 295 deletions

View File

@@ -33,17 +33,20 @@
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<widget class="QLabel" name="l_grid_binary_std">
<widget class="QLabel" name="l_elmer_binary_path">
<property name="minimumSize">
<size>
<width>100</width>
<height>0</height>
</size>
</property>
<property name="text">
<string>ElmerGrid</string>
<string>ElmerSolver 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>
<item row="0" column="1">
<widget class="Gui::PrefFileChooser" name="fc_elmer_binary_path" native="true">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
@@ -69,7 +72,7 @@
</size>
</property>
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Leave blank to use default Elmer elmer binary file&lt;/p&gt;&lt;p&gt;&lt;span style=&quot; font-weight:600;&quot;&gt;Note:&lt;/span&gt; To use multithreading you must specify here&lt;br&gt; the executable variant with the suffix &amp;quot;_mpi&amp;quot;.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
<string>Leave blank to use default ElmerSolver binary file</string>
</property>
<property name="prefEntry" stdset="0">
<cstring>elmerBinaryPath</cstring>
@@ -79,27 +82,21 @@
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="Gui::PrefCheckBox" name="cb_grid_binary_std">
<item row="1" column="0">
<widget class="QLabel" name="l_grid_binary_path">
<property name="minimumSize">
<size>
<width>100</width>
<height>0</height>
</size>
</property>
<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>
<string>ElmerGrid 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>
<widget class="Gui::PrefFileChooser" name="fc_grid_binary_path" native="true">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
@@ -135,61 +132,6 @@
</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="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="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>
</layout>
</widget>
</item>
@@ -198,40 +140,27 @@
<property name="title">
<string>Options</string>
</property>
<layout class="QGridLayout" name="gridLayout_2">
<item row="0" column="0">
<widget class="QLabel" name="l_elmer_multithreading">
<property name="text">
<string>Multithreading</string>
</property>
</widget>
</item>
<item row="0" column="1">
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QLabel" name="label_cores">
<property name="enabled">
<bool>true</bool>
</property>
<layout class="QHBoxLayout" name="hbl_otions">
<item>
<layout class="QGridLayout" name="gridLayout_2">
<item row="0" column="0">
<widget class="QLabel" name="l_num_processes">
<property name="text">
<string>CPU cores to be used</string>
<string>Number of processes</string>
</property>
</widget>
</item>
<item>
<widget class="Gui::PrefSpinBox" name="sb_elmer_num_cores">
<property name="enabled">
<bool>true</bool>
<item row="0" column="1">
<widget class="Gui::PrefSpinBox" name="sb_num_processes">
<property name="alignment">
<set>Qt::AlignLeft|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;span style=&quot; font-weight:600;&quot;&gt;Note:&lt;/span&gt; It is recommended to use an even number of cores to benefit from mesh symmetries. (Using 8 cores can be faster than 9 cores.)&lt;br/&gt;&lt;span style=&quot; font-weight:600;&quot;&gt;Note too:&lt;/span&gt; In extreme cases ElmerSolver might not converge if the core number is too high.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
<string>Number of parallel tasks. Set to `1` if Elmer does not use MPI.&lt;br&gt;It is recommended to use an even number of cores to benefit from mesh symmetries&lt;br&gt;(Using 8 cores can be faster than 9 cores).&lt;br&gt;In extreme cases ElmerSolver might not converge if the core number is too high.</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>
@@ -240,48 +169,27 @@
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
<item row="2" column="0">
<widget class="Gui::PrefCheckBox" name="cb_filtering">
<property name="toolTip">
<string>Merge mesh volume regions processed by each CPU core to make boundaries invisible.</string>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
<property name="text">
<string>Filter results</string>
</property>
</spacer>
<property name="checked">
<bool>true</bool>
</property>
<property name="prefEntry" stdset="0">
<cstring>FilterMultiCPUResults</cstring>
</property>
<property name="prefPath" stdset="0">
<cstring>Mod/Fem/Elmer</cstring>
</property>
</widget>
</item>
</layout>
</item>
<item row="1" column="0">
<widget class="QLabel" name="l_elmer_multiCPU">
<property name="text">
<string>Multi-core CPU support</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="Gui::PrefCheckBox" name="cb_elmer_filtering">
<property name="toolTip">
<string>The mesh volume regions processed by each CPU core
will be merged to make the volume boundaries invisible.</string>
</property>
<property name="text">
<string>Filter results</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
<property name="prefEntry" stdset="0">
<cstring>FilterMultiCPUResults</cstring>
</property>
<property name="prefPath" stdset="0">
<cstring>Mod/Fem/Elmer</cstring>
</property>
</widget>
</item>
</layout>
</widget>
</item>
@@ -292,7 +200,7 @@ will be merged to make the volume boundaries invisible.</string>
</property>
<layout class="QGridLayout" name="gdl_results">
<item row="0" column="0">
<widget class="Gui::PrefCheckBox" name="ckb_elmer_format">
<widget class="Gui::PrefCheckBox" name="ckb_binary_format">
<property name="toolTip">
<string>Save result in binary format</string>
</property>
@@ -311,7 +219,7 @@ will be merged to make the volume boundaries invisible.</string>
</widget>
</item>
<item row="1" column="0">
<widget class="Gui::PrefCheckBox" name="ckb_elmer_geom_id">
<widget class="Gui::PrefCheckBox" name="ckb_geom_id">
<property name="toolTip">
<string>Save the index of geometric entities</string>
</property>
@@ -352,11 +260,6 @@ will be merged to make the volume boundaries invisible.</string>
</widget>
<layoutdefault spacing="6" margin="11"/>
<customwidgets>
<customwidget>
<class>Gui::FileChooser</class>
<extends>QWidget</extends>
<header>Gui/FileDialog.h</header>
</customwidget>
<customwidget>
<class>Gui::PrefFileChooser</class>
<extends>Gui::FileChooser</extends>
@@ -376,70 +279,4 @@ will be merged to make the volume boundaries invisible.</string>
<resources>
<include location="Resources/Fem.qrc"/>
</resources>
<connections>
<connection>
<sender>cb_grid_binary_std</sender>
<signal>toggled(bool)</signal>
<receiver>l_grid_binary_path</receiver>
<slot>setDisabled(bool)</slot>
<hints>
<hint type="sourcelabel">
<x>247</x>
<y>45</y>
</hint>
<hint type="destinationlabel">
<x>71</x>
<y>68</y>
</hint>
</hints>
</connection>
<connection>
<sender>cb_grid_binary_std</sender>
<signal>toggled(bool)</signal>
<receiver>fc_grid_binary_path</receiver>
<slot>setDisabled(bool)</slot>
<hints>
<hint type="sourcelabel">
<x>247</x>
<y>45</y>
</hint>
<hint type="destinationlabel">
<x>247</x>
<y>68</y>
</hint>
</hints>
</connection>
<connection>
<sender>cb_elmer_binary_std</sender>
<signal>toggled(bool)</signal>
<receiver>fc_elmer_binary_path</receiver>
<slot>setDisabled(bool)</slot>
<hints>
<hint type="sourcelabel">
<x>247</x>
<y>91</y>
</hint>
<hint type="destinationlabel">
<x>247</x>
<y>114</y>
</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>

View File

@@ -25,7 +25,7 @@
#include "PreCompiled.h"
#ifndef _PreComp_
#include <QMessageBox>
#include <QThread>
#include <QStandardPaths>
#endif
#include "DlgSettingsFemElmerImp.h"
@@ -40,56 +40,40 @@ DlgSettingsFemElmerImp::DlgSettingsFemElmerImp(QWidget* parent)
{
ui->setupUi(this);
// determine number of CPU cores
processor_count = QThread::idealThreadCount();
ui->sb_elmer_num_cores->setMaximum(processor_count);
connect(ui->fc_grid_binary_path,
&Gui::PrefFileChooser::fileNameChanged,
&Gui::PrefFileChooser::fileNameSelected,
this,
&DlgSettingsFemElmerImp::onfileNameChanged);
&DlgSettingsFemElmerImp::onfileNameSelected);
connect(ui->fc_elmer_binary_path,
&Gui::PrefFileChooser::fileNameChanged,
&Gui::PrefFileChooser::fileNameSelected,
this,
&DlgSettingsFemElmerImp::onfileNameChanged);
connect(ui->fc_elmer_binary_path,
&Gui::PrefFileChooser::fileNameChanged,
this,
&DlgSettingsFemElmerImp::onfileNameChangedMT);
connect(ui->sb_elmer_num_cores,
qOverload<int>(&Gui::PrefSpinBox::valueChanged),
this,
&DlgSettingsFemElmerImp::onCoresValueChanged);
&DlgSettingsFemElmerImp::onfileNameSelected);
}
DlgSettingsFemElmerImp::~DlgSettingsFemElmerImp() = default;
void DlgSettingsFemElmerImp::saveSettings()
{
ui->cb_elmer_binary_std->onSave();
ui->fc_elmer_binary_path->onSave();
ui->cb_grid_binary_std->onSave();
ui->fc_grid_binary_path->onSave();
ui->sb_elmer_num_cores->onSave();
ui->cb_elmer_filtering->onSave();
ui->ckb_elmer_format->onSave();
ui->ckb_elmer_geom_id->onSave();
ui->sb_num_processes->onSave();
ui->cb_filtering->onSave();
ui->ckb_binary_format->onSave();
ui->ckb_geom_id->onSave();
}
void DlgSettingsFemElmerImp::loadSettings()
{
ui->cb_elmer_binary_std->onRestore();
ui->fc_elmer_binary_path->onRestore();
ui->cb_grid_binary_std->onRestore();
ui->fc_grid_binary_path->onRestore();
ui->sb_elmer_num_cores->onRestore();
ui->cb_elmer_filtering->onRestore();
ui->ckb_elmer_format->onRestore();
ui->ckb_elmer_geom_id->onRestore();
ui->sb_num_processes->onRestore();
ui->cb_filtering->onRestore();
ui->ckb_binary_format->onRestore();
ui->ckb_geom_id->onRestore();
}
/**
@@ -105,55 +89,10 @@ void DlgSettingsFemElmerImp::changeEvent(QEvent* e)
}
}
void DlgSettingsFemElmerImp::onfileNameChanged(QString FileName)
void DlgSettingsFemElmerImp::onfileNameSelected(const QString& fileName)
{
if (!QFileInfo::exists(FileName)) {
QMessageBox::critical(this,
tr("File does not exist"),
tr("The specified executable\n'%1'\n does not exist!\n"
"Specify another file.")
.arg(FileName));
}
}
void DlgSettingsFemElmerImp::onfileNameChangedMT(QString FileName)
{
ui->sb_elmer_num_cores->setMaximum(processor_count);
if (ui->sb_elmer_num_cores->value() == 1) {
return;
}
#if defined(FC_OS_WIN32)
// name ends with "_mpi.exe"
if (!FileName.endsWith(QLatin1String("_mpi.exe"))) {
QMessageBox::warning(this,
tr("FEM Elmer: Not suitable for multithreading"),
tr("Wrong Elmer setting: 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 (!FileName.endsWith(QLatin1String("_mpi"))) {
QMessageBox::warning(this,
tr("FEM Elmer: Not suitable for multithreading"),
tr("Wrong Elmer setting: 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());
if (!fileName.isEmpty() && QStandardPaths::findExecutable(fileName).isEmpty()) {
QMessageBox::critical(this, tr("Elmer"), tr("Executable '%1' not found").arg(fileName));
}
}

View File

@@ -41,9 +41,7 @@ public:
~DlgSettingsFemElmerImp() override;
protected Q_SLOTS:
void onfileNameChanged(QString FileName);
void onfileNameChangedMT(QString FileName);
void onCoresValueChanged(int cores);
void onfileNameSelected(const QString& fileName);
protected:
void saveSettings() override;