Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
fossils
Manage
Activity
Members
Labels
Plan
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Locked files
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Package Registry
Container Registry
Model registry
Operate
Environments
Terraform modules
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Code review analytics
Insights
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
Boman Romain
fossils
Commits
837cc397
Commit
837cc397
authored
1 year ago
by
Boman Romain
Browse files
Options
Downloads
Patches
Plain Diff
add "convert to csv" button
parent
d4f154c0
Branches
devel/bb2024
Branches containing commit
No related tags found
No related merge requests found
Pipeline
#18998
passed
1 year ago
Changes
3
Pipelines
1
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
fossils.py
+106
-49
106 additions, 49 deletions
fossils.py
gui/fossils.ui
+16
-3
16 additions, 3 deletions
gui/fossils.ui
gui/ui_fossils.py
+14
-8
14 additions, 8 deletions
gui/ui_fossils.py
with
136 additions
and
60 deletions
fossils.py
+
106
−
49
View file @
837cc397
...
...
@@ -7,7 +7,7 @@
# if starting Qt fails with
# qt.qpa.plugin: Could not find the Qt platform plugin "windows" in ""
# this means that an application in the PATH provides another version of Qt
# which is incompatible (MikTeX)
# which is incompatible (MikTeX)
# => move MikTeX to the bottom of the user PATH.
from
PyQt5.QtCore
import
*
...
...
@@ -17,10 +17,16 @@ from gui.ui_fossils import Ui_Form
import
sys
import
os
import
gui.resources
import
numpy
as
np
import
gmsh
if
not
gmsh
.
isInitialized
():
gmsh
.
initialize
()
class
Window
(
QWidget
,
Ui_Form
):
"""
Minimal GUI asking for a file and running it
"""
def
__init__
(
self
,
parent
=
None
):
super
(
Window
,
self
).
__init__
(
parent
)
self
.
setupUi
(
self
)
...
...
@@ -40,28 +46,30 @@ class Window(QWidget, Ui_Form):
# read Qt settings for the application
settings
=
QSettings
()
# self.restoreGeometry(settings.value("Geometry", self.saveGeometry()))
self
.
inpFileLineEdit
.
setText
(
settings
.
value
(
"
inpFile
"
,
self
.
default_inputfile
()))
self
.
wrkspLineEdit
.
setText
(
settings
.
value
(
"
workspace
"
,
self
.
default_wrksp
()))
self
.
inpFileLineEdit
.
setText
(
settings
.
value
(
"
inpFile
"
,
self
.
default_inputfile
()))
self
.
wrkspLineEdit
.
setText
(
settings
.
value
(
"
workspace
"
,
self
.
default_wrksp
()))
self
.
action
=
'
cancelled
'
#iconfile = os.path.join('fossils.png')
#
iconfile = os.path.join('fossils.png')
self
.
setWindowIcon
(
QIcon
(
"
:/fossils.png
"
))
def
default_inputfile
(
self
):
testnames
=
[
os
.
path
.
join
(
os
.
path
.
dirname
(
__file__
),
'
models
'
,
'
others
'
,
'
dolicorhynchops
'
,
'
dolicorhynchops_10k.py
'
),
os
.
path
.
join
(
os
.
path
.
dirname
(
__file__
),
'
models
'
,
'
dolicorhynchops
'
,
'
dolicorhynchops_10k.py
'
),
testnames
=
[
os
.
path
.
join
(
os
.
path
.
dirname
(
__file__
),
'
models
'
,
'
others
'
,
'
dolicorhynchops
'
,
'
dolicorhynchops_10k.py
'
),
os
.
path
.
join
(
os
.
path
.
dirname
(
__file__
),
'
models
'
,
'
dolicorhynchops
'
,
'
dolicorhynchops_10k.py
'
),
]
for
name
in
testnames
:
if
os
.
path
.
isfile
(
name
):
return
name
return
""
def
default_wrksp
(
self
):
for
key
in
[
'
USERPROFILE
'
,
'
HOME
'
]:
for
key
in
[
'
USERPROFILE
'
,
'
HOME
'
]:
try
:
folder
=
os
.
environ
[
key
]
if
os
.
path
.
isdir
(
folder
):
...
...
@@ -70,7 +78,6 @@ class Window(QWidget, Ui_Form):
pass
return
""
def
on_runPushButton_pressed
(
self
):
if
not
os
.
path
.
isfile
(
self
.
inpFileLineEdit
.
text
()):
QMessageBox
.
critical
(
self
,
"
Error
"
,
"
Input file does not exist!
"
)
...
...
@@ -78,8 +85,8 @@ class Window(QWidget, Ui_Form):
if
not
os
.
path
.
isdir
(
self
.
wrkspLineEdit
.
text
()):
reply
=
QMessageBox
.
question
(
self
,
'
Message
'
,
"
Workspace does not exist - do you want to continue?
"
,
QMessageBox
.
Yes
|
QMessageBox
.
No
,
QMessageBox
.
Yes
)
"
Workspace does not exist - do you want to continue?
"
,
QMessageBox
.
Yes
|
QMessageBox
.
No
,
QMessageBox
.
Yes
)
if
reply
==
QMessageBox
.
No
:
return
# wdir = build_workspace_name(self.wrkspLineEdit.text(), self.inpFileLineEdit.text())
...
...
@@ -87,15 +94,23 @@ class Window(QWidget, Ui_Form):
self
.
action
=
'
run
'
self
.
close
()
def
on_viewPushButton_pressed
(
self
):
wdir
=
build_workspace_name
(
self
.
wrkspLineEdit
.
text
(),
self
.
inpFileLineEdit
.
text
())
wdir
=
build_workspace_name
(
self
.
wrkspLineEdit
.
text
(),
self
.
inpFileLineEdit
.
text
())
if
not
os
.
path
.
isdir
(
wdir
):
QMessageBox
.
critical
(
self
,
"
Error
"
,
f
"
No results in
{
wdir
}
!
"
)
return
self
.
action
=
'
post
'
self
.
close
()
def
on_toCSVPushButton_pressed
(
self
):
wdir
=
build_workspace_name
(
self
.
wrkspLineEdit
.
text
(),
self
.
inpFileLineEdit
.
text
())
if
not
os
.
path
.
isdir
(
wdir
):
QMessageBox
.
critical
(
self
,
"
Error
"
,
f
"
No results in
{
wdir
}
!
"
)
return
self
.
action
=
'
csv
'
self
.
close
()
def
on_inpFilePushButton_pressed
(
self
):
# try to set a relevant starting folder
...
...
@@ -107,11 +122,10 @@ class Window(QWidget, Ui_Form):
default
=
curfolder
fname
=
QFileDialog
.
getOpenFileName
(
self
,
'
Select input file
'
,
default
,
filter
=
'
Python File (*.py)
'
)
self
,
'
Select input file
'
,
default
,
filter
=
'
Python File (*.py)
'
)
pyfile
=
fname
[
0
]
if
pyfile
:
self
.
inpFileLineEdit
.
setText
(
QDir
.
toNativeSeparators
(
pyfile
))
self
.
inpFileLineEdit
.
setText
(
QDir
.
toNativeSeparators
(
pyfile
))
def
on_inpFileEditPushButton_pressed
(
self
):
"""
Open input file with a text editor
...
...
@@ -119,35 +133,30 @@ class Window(QWidget, Ui_Form):
editors
=
[
"
C:/Program Files/Just Great Software/EditPad Pro 8/EditPadPro8.exe
"
,
"
C:/Windows/notepad.exe
"
]
]
for
editor
in
editors
:
if
os
.
path
.
isfile
(
editor
):
import
subprocess
subprocess
.
Popen
([
editor
,
self
.
inpFileLineEdit
.
text
()
])
subprocess
.
Popen
([
editor
,
self
.
inpFileLineEdit
.
text
()])
break
def
on_inpFileResetPushButton_pressed
(
self
):
self
.
inpFileLineEdit
.
setText
(
self
.
default_inputfile
())
def
on_wrkspExplorePushButton_pressed
(
self
):
"""
Browse workspace folder with system explorer
"""
os
.
startfile
(
self
.
wrkspLineEdit
.
text
())
def
on_wrkspPushButton_pressed
(
self
):
dir
=
QFileDialog
.
getExistingDirectory
(
self
,
"
Select output folder
"
,
self
.
wrkspLineEdit
.
text
())
if
dir
:
self
.
wrkspLineEdit
.
setText
(
QDir
.
toNativeSeparators
(
dir
))
self
.
wrkspLineEdit
.
setText
(
QDir
.
toNativeSeparators
(
dir
))
def
on_wrkspResetPushButton_pressed
(
self
):
self
.
wrkspLineEdit
.
setText
(
self
.
default_wrksp
())
def
closeEvent
(
self
,
event
):
"""
save settings to registry and quit
"""
...
...
@@ -163,20 +172,18 @@ def run_simulation(testname):
"""
# thanks to the "compile" command, the filename appears in the stack
# trace in case of errors
script
=
open
(
testname
,
encoding
=
'
utf-8
'
).
read
()
exec
(
compile
(
script
,
testname
,
'
exec
'
),
{
'
__file__
'
:
testname
,
'
__name__
'
:
'
__main__
'
})
script
=
open
(
testname
,
encoding
=
'
utf-8
'
).
read
()
exec
(
compile
(
script
,
testname
,
'
exec
'
),
{
'
__file__
'
:
testname
,
'
__name__
'
:
'
__main__
'
})
def
view
_results
():
"""
Load
/display
results
in
the current folder
def
load_previous
_results
():
"""
Load
previously computed
results
from
the current folder
"""
import
gmsh
if
not
gmsh
.
isInitialized
():
gmsh
.
initialize
()
# load empty mesh
gmsh
.
merge
(
'
mesh.msh
'
)
gmsh
.
option
.
setNumber
(
"
General.Verbosity
"
,
3
)
# load views from the option file
views
=
[]
with
open
(
'
post.opt
'
)
as
f
:
...
...
@@ -192,12 +199,57 @@ def view_results():
gmsh
.
merge
(
v
[
1
])
print
(
'
loading options...
'
)
gmsh
.
merge
(
'
post.opt
'
)
return
views
def
view_results
():
"""
Load/display results in the current folder
"""
views
=
load_previous_results
()
print
(
'
starting Gmsh GUI, please wait...
'
)
gmsh
.
fltk
.
run
()
def
convert_results_to_csv
():
"""
Converts results to CSV files
"""
views
=
load_previous_results
()
# export results to csv
for
v
in
views
:
csvfile
=
v
[
1
].
replace
(
'
.msh
'
,
'
.csv
'
)
dataType
,
tags
,
data
,
time
,
numComp
=
gmsh
.
view
.
getModelData
(
tag
=
int
(
v
[
0
])
+
1
,
step
=
0
)
# assume tag=index+1
print
(
f
'
exporting
"
{
csvfile
}
"
(
{
dataType
}
)
'
)
# export raw "data" to csv
# np.savetxt(csvfile, data, delimiter=',')
# if tensor => compute j2 for each node
if
numComp
==
9
:
ndata
=
np
.
array
(
data
)
data
=
np
.
array
([])
ncols
=
ndata
.
shape
[
1
]
nnods
=
ncols
/
9
for
i
in
range
(
int
(
nnods
)):
xx
,
xy
,
xz
,
yx
,
yy
,
yz
,
zx
,
zy
,
zz
=
ndata
[:,
i
*
9
:(
i
+
1
)
*
9
].
T
j2
=
np
.
sqrt
(
((
xx
-
yy
)
**
2
+
(
yy
-
zz
)
**
2
+
(
zz
-
xx
)
**
2
)
/
2
+
3
*
(
xy
*
xy
+
yz
*
yz
+
zx
*
zx
)
)
if
data
.
any
():
data
=
np
.
vstack
([
data
,
j2
])
else
:
data
=
j2
if
nnods
==
1
:
data
=
data
.
reshape
(
1
,
-
1
)
data
=
data
.
T
# export "data" to csv with tags
f
=
open
(
csvfile
,
"
w
"
)
for
x
,
y
in
zip
(
tags
,
data
):
f
.
write
(
"
{}, {}
\n
"
.
format
(
x
,
'
,
'
.
join
(
map
(
str
,
y
))))
f
.
close
()
def
rm_folder_from_pypath
(
folder
):
sys
.
path
=
[
p
for
p
in
sys
.
path
if
not
folder
in
p
]
sys
.
path
=
[
p
for
p
in
sys
.
path
if
not
folder
in
p
]
def
add_folder2pypath
(
folder
):
...
...
@@ -209,10 +261,10 @@ def add_folder2pypath(folder):
def
rm_folder_from_path
(
folder
):
import
platform
if
'
Windows
'
in
platform
.
uname
():
path
=
[
p
for
p
in
os
.
environ
[
'
PATH
'
].
split
(
'
;
'
)
if
not
folder
in
p
]
path
=
[
p
for
p
in
os
.
environ
[
'
PATH
'
].
split
(
'
;
'
)
if
not
folder
in
p
]
os
.
environ
[
'
PATH
'
]
=
'
;
'
.
join
(
path
)
# print(f'{folder} added to PATH')
# print(f"os.environ['PATH']={os.environ['PATH']}")
# print(f"os.environ['PATH']={os.environ['PATH']}")
def
add_folder2path
(
folder
):
...
...
@@ -240,15 +292,15 @@ def setup_pythonpath():
pyexe
=
os
.
path
.
basename
(
sys
.
executable
)
print
(
f
'
pyexe =
{
pyexe
}
'
)
add_folder2pypath
(
os
.
path
.
join
(
this_script_dir
,
'
cxxfem
'
,
'
build
'
,
'
bin
'
))
# gcc/mingw
'
build
'
,
'
bin
'
))
# gcc/mingw
add_folder2pypath
(
os
.
path
.
join
(
this_script_dir
,
'
cxxfem
'
,
'
build
'
,
'
bin
'
,
'
Release
'
))
# msvc
'
build
'
,
'
bin
'
,
'
Release
'
))
# msvc
# allows this script to be run without setting env
# rm_folder_from_path('gmsh')
# rm_folder_from_pypath('gmsh')
# add_folder2pypath(os.path.join(this_script_dir, 'lib',
# 'gmsh-sdk', 'lib')) # msvc
# 'gmsh-sdk', 'lib')) # msvc
# add_folder2path(os.path.join(this_script_dir, 'lib',
# 'gmsh-sdk', 'bin')) # gmsh
# print(f'sys.path={sys.path}')
...
...
@@ -260,6 +312,7 @@ def setup_pythonpath():
if
os
.
path
.
exists
(
v
):
os
.
add_dll_directory
(
v
)
def
build_workspace_name
(
workspace
,
testname
):
"""
create workspace folder and chdir into it
"""
...
...
@@ -268,7 +321,7 @@ def build_workspace_name(workspace, testname):
# => workspace + testname
common
=
os
.
path
.
basename
(
testname
)
resdir
=
common
.
replace
(
os
.
sep
,
"
_
"
)
resdir
,
ext
=
os
.
path
.
splitext
(
resdir
)
resdir
,
ext
=
os
.
path
.
splitext
(
resdir
)
wdir
=
os
.
path
.
join
(
workspace
,
resdir
)
else
:
# workspace is not given:
...
...
@@ -283,7 +336,6 @@ def build_workspace_name(workspace, testname):
wdir
=
os
.
path
.
abspath
(
os
.
path
.
join
(
'
workspace
'
,
resdir
))
return
wdir
if
__name__
==
"
__main__
"
:
...
...
@@ -302,7 +354,8 @@ if __name__ == "__main__":
os
.
environ
[
'
OMP_NUM_THREADS
'
]
=
str
(
args
.
k
)
cxxfem
.
set_num_threads
(
args
.
k
)
__file__
=
os
.
path
.
abspath
(
__file__
)
# relative path on Linux with python <=3.8
# relative path on Linux with python <=3.8
__file__
=
os
.
path
.
abspath
(
__file__
)
# display env variables
try
:
...
...
@@ -310,7 +363,6 @@ if __name__ == "__main__":
except
:
print
(
f
"
OMP_NUM_THREADS=[not set]
"
)
# ask for a file if not given => starts the GUI
if
not
args
.
file
:
# QApplication.setAttribute(Qt.AA_EnableHighDpiScaling)
...
...
@@ -320,7 +372,8 @@ if __name__ == "__main__":
win
=
Window
()
win
.
setWindowTitle
(
"
Fossils
"
)
win
.
show
()
win
.
setWindowState
(
Qt
.
WindowActive
)
# try to make it appear above any other window (and particularly the console window)
# try to make it appear above any other window (and particularly the console window)
win
.
setWindowState
(
Qt
.
WindowActive
)
app
.
lastWindowClosed
.
connect
(
app
.
quit
)
app
.
exec_
()
...
...
@@ -329,7 +382,7 @@ if __name__ == "__main__":
testname
=
win
.
inpFileLineEdit
.
text
()
gui
=
True
else
:
workspace
=
None
# use default
workspace
=
None
# use default
if
args
.
post
:
action
=
'
post
'
else
:
...
...
@@ -340,10 +393,10 @@ if __name__ == "__main__":
# run the simulation or display results
print
(
f
'
action =
{
action
}
'
)
if
action
==
'
run
'
or
action
==
'
post
'
:
if
action
in
[
'
run
'
,
'
post
'
,
'
csv
'
]
:
testname
=
os
.
path
.
normcase
(
testname
)
# F:/ => f:/ on Windows
print
(
f
'
testname =
{
testname
}
'
)
wdir
=
build_workspace_name
(
workspace
,
testname
)
print
(
'
workspace =
'
,
wdir
)
# sys.exit()
...
...
@@ -353,11 +406,15 @@ if __name__ == "__main__":
try
:
if
action
==
'
run
'
:
tee
=
cxxfem
.
Tee
(
'
stdout.txt
'
)
# split streams (stdout + logfile)
# split streams (stdout + logfile)
tee
=
cxxfem
.
Tee
(
'
stdout.txt
'
)
run_simulation
(
testname
)
elif
action
==
'
post
'
:
tee
=
cxxfem
.
Tee
(
'
post.txt
'
)
view_results
()
elif
action
==
'
csv
'
:
tee
=
cxxfem
.
Tee
(
'
tocsv.txt
'
)
convert_results_to_csv
()
except
Exception
as
err
:
print
(
f
'
\n
** ERROR:
{
err
}
\n
'
)
import
traceback
...
...
This diff is collapsed.
Click to expand it.
gui/fossils.ui
+
16
−
3
View file @
837cc397
...
...
@@ -6,8 +6,8 @@
<rect>
<x>
0
</x>
<y>
0
</y>
<width>
7
4
5
</width>
<height>
1
54
</height>
<width>
75
6
</width>
<height>
1
16
</height>
</rect>
</property>
<property
name=
"windowTitle"
>
...
...
@@ -129,7 +129,7 @@
</layout>
</item>
<item>
<layout
class=
"QHBoxLayout"
name=
"horizontalLayout
_2
"
>
<layout
class=
"QHBoxLayout"
name=
"horizontalLayout"
>
<item>
<spacer
name=
"horizontalSpacer_2"
>
<property
name=
"orientation"
>
...
...
@@ -169,6 +169,19 @@
</property>
</widget>
</item>
<item>
<widget
class=
"QPushButton"
name=
"toCSVPushButton"
>
<property
name=
"toolTip"
>
<string>
read/display the results stored in the folder of the workspace
</string>
</property>
<property
name=
"statusTip"
>
<string/>
</property>
<property
name=
"text"
>
<string>
to CSV
</string>
</property>
</widget>
</item>
<item>
<spacer
name=
"horizontalSpacer"
>
<property
name=
"orientation"
>
...
...
This diff is collapsed.
Click to expand it.
gui/ui_fossils.py
+
14
−
8
View file @
837cc397
...
...
@@ -14,7 +14,7 @@ from PyQt5 import QtCore, QtGui, QtWidgets
class
Ui_Form
(
object
):
def
setupUi
(
self
,
Form
):
Form
.
setObjectName
(
"
Form
"
)
Form
.
resize
(
7
4
5
,
1
54
)
Form
.
resize
(
75
6
,
1
16
)
self
.
verticalLayout
=
QtWidgets
.
QVBoxLayout
(
Form
)
self
.
verticalLayout
.
setObjectName
(
"
verticalLayout
"
)
self
.
gridLayout
=
QtWidgets
.
QGridLayout
()
...
...
@@ -58,21 +58,25 @@ class Ui_Form(object):
self
.
wrkspResetPushButton
.
setObjectName
(
"
wrkspResetPushButton
"
)
self
.
gridLayout
.
addWidget
(
self
.
wrkspResetPushButton
,
1
,
4
,
1
,
1
)
self
.
verticalLayout
.
addLayout
(
self
.
gridLayout
)
self
.
horizontalLayout
_2
=
QtWidgets
.
QHBoxLayout
()
self
.
horizontalLayout
_2
.
setObjectName
(
"
horizontalLayout
_2
"
)
self
.
horizontalLayout
=
QtWidgets
.
QHBoxLayout
()
self
.
horizontalLayout
.
setObjectName
(
"
horizontalLayout
"
)
spacerItem
=
QtWidgets
.
QSpacerItem
(
40
,
20
,
QtWidgets
.
QSizePolicy
.
Expanding
,
QtWidgets
.
QSizePolicy
.
Minimum
)
self
.
horizontalLayout
_2
.
addItem
(
spacerItem
)
self
.
horizontalLayout
.
addItem
(
spacerItem
)
self
.
runPushButton
=
QtWidgets
.
QPushButton
(
Form
)
self
.
runPushButton
.
setStatusTip
(
""
)
self
.
runPushButton
.
setObjectName
(
"
runPushButton
"
)
self
.
horizontalLayout
_2
.
addWidget
(
self
.
runPushButton
)
self
.
horizontalLayout
.
addWidget
(
self
.
runPushButton
)
self
.
viewPushButton
=
QtWidgets
.
QPushButton
(
Form
)
self
.
viewPushButton
.
setStatusTip
(
""
)
self
.
viewPushButton
.
setObjectName
(
"
viewPushButton
"
)
self
.
horizontalLayout_2
.
addWidget
(
self
.
viewPushButton
)
self
.
horizontalLayout
.
addWidget
(
self
.
viewPushButton
)
self
.
toCSVPushButton
=
QtWidgets
.
QPushButton
(
Form
)
self
.
toCSVPushButton
.
setStatusTip
(
""
)
self
.
toCSVPushButton
.
setObjectName
(
"
toCSVPushButton
"
)
self
.
horizontalLayout
.
addWidget
(
self
.
toCSVPushButton
)
spacerItem1
=
QtWidgets
.
QSpacerItem
(
40
,
20
,
QtWidgets
.
QSizePolicy
.
Expanding
,
QtWidgets
.
QSizePolicy
.
Minimum
)
self
.
horizontalLayout
_2
.
addItem
(
spacerItem1
)
self
.
verticalLayout
.
addLayout
(
self
.
horizontalLayout
_2
)
self
.
horizontalLayout
.
addItem
(
spacerItem1
)
self
.
verticalLayout
.
addLayout
(
self
.
horizontalLayout
)
self
.
retranslateUi
(
Form
)
QtCore
.
QMetaObject
.
connectSlotsByName
(
Form
)
...
...
@@ -100,3 +104,5 @@ class Ui_Form(object):
self
.
runPushButton
.
setText
(
_translate
(
"
Form
"
,
"
Run
"
))
self
.
viewPushButton
.
setToolTip
(
_translate
(
"
Form
"
,
"
read/display the results stored in the folder of the workspace
"
))
self
.
viewPushButton
.
setText
(
_translate
(
"
Form
"
,
"
View
"
))
self
.
toCSVPushButton
.
setToolTip
(
_translate
(
"
Form
"
,
"
read/display the results stored in the folder of the workspace
"
))
self
.
toCSVPushButton
.
setText
(
_translate
(
"
Form
"
,
"
to CSV
"
))
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment