Skip to content

Commit acb3f4a

Browse files
authored
Merge pull request FreeCAD#24912 from marioalexis84/fem-elmer_solver
2 parents 54d25bc + 428340a commit acb3f4a

30 files changed

+904
-817
lines changed

src/Mod/Fem/App/FemMesh.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2705,3 +2705,11 @@ bool FemMesh::removeGroup(int GroupId)
27052705
{
27062706
return this->getSMesh()->RemoveGroup(GroupId);
27072707
}
2708+
2709+
void FemMesh::renameGroup(int id, const std::string& name)
2710+
{
2711+
SMESH_Group* grp = this->getSMesh()->GetGroup(id);
2712+
if (grp) {
2713+
grp->SetName(name.c_str());
2714+
}
2715+
}

src/Mod/Fem/App/FemMesh.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,8 @@ class FemExport FemMesh: public Data::ComplexGeoData
180180
void addGroupElements(int, const std::set<int>&);
181181
/// Remove group (Name due to similarity to SMESH basis functions)
182182
bool removeGroup(int);
183+
/// Rename group
184+
void renameGroup(int id, const std::string& name);
183185
//@}
184186

185187

src/Mod/Fem/App/FemMesh.pyi

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -239,6 +239,14 @@ class FemMesh(ComplexGeoData):
239239
Returns boolean."""
240240
...
241241

242+
@constmethod
243+
def renameGroup(self) -> Any:
244+
"""Rename a group with a given group ID
245+
renameGroup(id, name)
246+
groupid: int
247+
name: string"""
248+
...
249+
242250
@constmethod
243251
def getElementType(self) -> Any:
244252
"""Return the element type of a given ID"""

src/Mod/Fem/App/FemMeshPyImp.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1718,6 +1718,18 @@ PyObject* FemMeshPy::removeGroup(PyObject* args) const
17181718
return PyBool_FromLong((long)(getFemMeshPtr()->removeGroup(theId)));
17191719
}
17201720

1721+
PyObject* FemMeshPy::renameGroup(PyObject* args) const
1722+
{
1723+
int id;
1724+
const char* name;
1725+
if (!PyArg_ParseTuple(args, "is", &id, &name)) {
1726+
return nullptr;
1727+
}
1728+
1729+
getFemMeshPtr()->renameGroup(id, name);
1730+
1731+
Py_Return;
1732+
}
17211733

17221734
PyObject* FemMeshPy::getElementType(PyObject* args) const
17231735
{

src/Mod/Fem/App/FemPostPipeline.cpp

Lines changed: 48 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@
4444
#include <vtkInformationVector.h>
4545

4646
#include <Base/Console.h>
47+
#include <Base/Reader.h>
4748

4849
#include "FemMesh.h"
4950
#include "FemMeshObject.h"
@@ -130,10 +131,10 @@ bool FemPostPipeline::canRead(Base::FileInfo File)
130131
{
131132

132133
// from FemResult only unstructural mesh is supported in femvtktoools.cpp
133-
return File.hasExtension({"vtk", "vtp", "vts", "vtr", "vti", "vtu", "pvtu", "vtm"});
134+
return File.hasExtension({"vtk", "vtp", "vts", "vtr", "vti", "vtu", "pvtu", "vtm", "pvd"});
134135
}
135136

136-
vtkSmartPointer<vtkDataObject> FemPostPipeline::dataObjectFromFile(Base::FileInfo File)
137+
vtkSmartPointer<vtkDataObject> FemPostPipeline::dataObjectFromFile(const Base::FileInfo& File)
137138
{
138139
// checking on the file
139140
if (!File.isReadable()) {
@@ -164,10 +165,55 @@ vtkSmartPointer<vtkDataObject> FemPostPipeline::dataObjectFromFile(Base::FileInf
164165
else if (File.hasExtension("vtm")) {
165166
return readXMLFile<vtkXMLMultiBlockDataReader>(File.filePath());
166167
}
168+
else if (File.hasExtension("pvd")) {
169+
return readPVD(File);
170+
}
167171

168172
throw Base::FileException("Unknown extension");
169173
}
170174

175+
vtkSmartPointer<vtkDataObject> FemPostPipeline::readPVD(const Base::FileInfo& file)
176+
{
177+
std::string path = file.filePath();
178+
179+
std::ifstream ifstr(path, std::ios::in | std::ios::binary);
180+
Base::XMLReader reader(path.c_str(), ifstr);
181+
reader.readElement("DataSet");
182+
std::map<double, std::string> values;
183+
std::vector<std::string> files;
184+
while (strcmp(reader.localName(), "DataSet") == 0) {
185+
values.emplace(std::make_pair(reader.getAttribute<double>("timestep"),
186+
reader.getAttribute<std::string>("file")));
187+
reader.readNextElement();
188+
}
189+
190+
auto timeInfo = vtkSmartPointer<vtkStringArray>::New();
191+
timeInfo->SetName("TimeInfo");
192+
timeInfo->InsertNextValue("TimeStep");
193+
// set unit to empty string
194+
timeInfo->InsertNextValue("");
195+
196+
auto multiBlock = vtkSmartPointer<vtkMultiBlockDataSet>::New();
197+
multiBlock->GetFieldData()->AddArray(timeInfo);
198+
199+
int i = 0;
200+
std::string dir = file.dirPath();
201+
for (auto v : values) {
202+
Base::FileInfo fi(dir + "/" + v.second);
203+
auto data = dataObjectFromFile(fi);
204+
auto time = vtkSmartPointer<vtkFloatArray>::New();
205+
time->SetName("TimeValue");
206+
time->InsertNextValue(v.first);
207+
data->GetFieldData()->AddArray(time);
208+
data->GetFieldData()->AddArray(timeInfo);
209+
210+
multiBlock->SetBlock(i, data);
211+
++i;
212+
}
213+
214+
return multiBlock;
215+
}
216+
171217
void FemPostPipeline::read(Base::FileInfo File)
172218
{
173219
Data.setValue(dataObjectFromFile(File));

src/Mod/Fem/App/FemPostPipeline.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,9 @@ class FemExport FemPostPipeline: public Fem::FemPostObject, public Fem::FemPostG
129129
reader->Update();
130130
return reader->GetOutput();
131131
}
132-
vtkSmartPointer<vtkDataObject> dataObjectFromFile(Base::FileInfo File);
132+
vtkSmartPointer<vtkDataObject> dataObjectFromFile(const Base::FileInfo& File);
133+
// read .pvd file into multiblock dataset
134+
vtkSmartPointer<vtkDataObject> readPVD(const Base::FileInfo& file);
133135
};
134136

135137
} // namespace Fem

src/Mod/Fem/CMakeLists.txt

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -211,6 +211,7 @@ SET(FemObjects_SRCS
211211
femobjects/result_mechanical.py
212212
femobjects/solver_calculix.py
213213
femobjects/solver_ccxtools.py
214+
femobjects/solver_elmer.py
214215
)
215216

216217
if(BUILD_FEM_VTK_PYTHON)
@@ -285,9 +286,8 @@ SET(FemSolverCalculix_SRCS
285286
SET(FemSolverElmer_SRCS
286287
femsolver/elmer/__init__.py
287288
femsolver/elmer/sifio.py
288-
femsolver/elmer/solver.py
289-
femsolver/elmer/tasks.py
290289
femsolver/elmer/writer.py
290+
femsolver/elmer/elmertools.py
291291
)
292292

293293
SET(FemSolverElmerEquations_SRCS
@@ -631,6 +631,7 @@ SET(FemGuiTaskPanels_SRCS
631631
femtaskpanels/task_result_mechanical.py
632632
femtaskpanels/task_solver_calculix.py
633633
femtaskpanels/task_solver_ccxtools.py
634+
femtaskpanels/task_solver_elmer.py
634635
)
635636

636637
if(BUILD_FEM_VTK_PYTHON)
@@ -701,6 +702,7 @@ SET(FemGuiViewProvider_SRCS
701702
femviewprovider/view_result_mechanical.py
702703
femviewprovider/view_solver_calculix.py
703704
femviewprovider/view_solver_ccxtools.py
705+
femviewprovider/view_solver_elmer.py
704706
)
705707

706708
if(BUILD_FEM_VTK_PYTHON)

src/Mod/Fem/Gui/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -449,6 +449,7 @@ SET(FemGuiPythonUI_SRCS
449449
Resources/ui/ResultShow.ui
450450
Resources/ui/SolverCalculiX.ui
451451
Resources/ui/SolverCcxTools.ui
452+
Resources/ui/SolverElmer.ui
452453
Resources/ui/TaskPostGlyph.ui
453454
Resources/ui/TaskPostExtraction.ui
454455
Resources/ui/TaskPostHistogram.ui

src/Mod/Fem/Gui/DlgSettingsFemElmer.ui

Lines changed: 30 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -144,14 +144,14 @@
144144
<item>
145145
<layout class="QGridLayout" name="gridLayout_2">
146146
<item row="0" column="0">
147-
<widget class="QLabel" name="l_num_processes">
147+
<widget class="QLabel" name="l_num_tasks">
148148
<property name="text">
149-
<string>Number of processes</string>
149+
<string>Number of tasks</string>
150150
</property>
151151
</widget>
152152
</item>
153153
<item row="0" column="1">
154-
<widget class="Gui::PrefSpinBox" name="sb_num_processes">
154+
<widget class="Gui::PrefSpinBox" name="sb_num_tasks">
155155
<property name="alignment">
156156
<set>Qt::AlignLeft|Qt::AlignTrailing|Qt::AlignVCenter</set>
157157
</property>
@@ -162,7 +162,33 @@
162162
<number>1</number>
163163
</property>
164164
<property name="prefEntry" stdset="0">
165-
<cstring>UseNumberOfCores</cstring>
165+
<cstring>NumberOfTasks</cstring>
166+
</property>
167+
<property name="prefPath" stdset="0">
168+
<cstring>Mod/Fem/Elmer</cstring>
169+
</property>
170+
</widget>
171+
</item>
172+
<item row="1" column="0">
173+
<widget class="QLabel" name="l_threads_per_task">
174+
<property name="text">
175+
<string>Threads per task</string>
176+
</property>
177+
</widget>
178+
</item>
179+
<item row="1" column="1">
180+
<widget class="Gui::PrefSpinBox" name="sb_threads_per_task">
181+
<property name="alignment">
182+
<set>Qt::AlignLeft|Qt::AlignTrailing|Qt::AlignVCenter</set>
183+
</property>
184+
<property name="toolTip">
185+
<string>Number of threads per task. Take effect if Elmer uses OpenMP.</string>
186+
</property>
187+
<property name="minimum">
188+
<number>1</number>
189+
</property>
190+
<property name="prefEntry" stdset="0">
191+
<cstring>ThreadsPerTask</cstring>
166192
</property>
167193
<property name="prefPath" stdset="0">
168194
<cstring>Mod/Fem/Elmer</cstring>

src/Mod/Fem/Gui/DlgSettingsFemElmerImp.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,8 @@ void DlgSettingsFemElmerImp::saveSettings()
5454
ui->fc_elmer_binary_path->onSave();
5555
ui->fc_grid_binary_path->onSave();
5656

57-
ui->sb_num_processes->onSave();
57+
ui->sb_num_tasks->onSave();
58+
ui->sb_threads_per_task->onSave();
5859

5960
ui->ckb_binary_format->onSave();
6061
ui->ckb_geom_id->onSave();
@@ -65,7 +66,8 @@ void DlgSettingsFemElmerImp::loadSettings()
6566
ui->fc_elmer_binary_path->onRestore();
6667
ui->fc_grid_binary_path->onRestore();
6768

68-
ui->sb_num_processes->onRestore();
69+
ui->sb_num_tasks->onRestore();
70+
ui->sb_threads_per_task->onRestore();
6971

7072
ui->ckb_binary_format->onRestore();
7173
ui->ckb_geom_id->onRestore();

0 commit comments

Comments
 (0)