Skip to content

Commit 5d1d58b

Browse files
authored
Merge pull request #32 from dragos-ana/enable_vtu_support
feat: enable vtu file support, improve testing suite, improve design condition rendering
2 parents bb5d38a + 7daf4ba commit 5d1d58b

18 files changed

+12904
-778
lines changed

requirements.txt

Lines changed: 42 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -2,25 +2,25 @@
22
# This file is autogenerated by pip-compile with Python 3.12
33
# by the following command:
44
#
5-
# pip-compile --all-extras --cert=None --client-cert=None --index-url=None --output-file=requirements.txt --pip-args=None requirements.in
5+
# pip-compile --all-extras --output-file=requirements.txt requirements.in
66
#
77
aiohappyeyeballs==2.6.1
88
# via aiohttp
9-
aiohttp==3.12.15
9+
aiohttp==3.13.2
1010
# via wslink
1111
aiosignal==1.4.0
1212
# via aiohttp
13-
attrs==25.3.0
13+
attrs==25.4.0
1414
# via aiohttp
15-
certifi==2025.8.3
15+
certifi==2025.11.12
1616
# via
1717
# netcdf4
1818
# requests
19-
cfgv==3.4.0
19+
cfgv==3.5.0
2020
# via pre-commit
21-
cftime==1.6.4.post1
21+
cftime==1.6.5
2222
# via netcdf4
23-
charset-normalizer==3.4.3
23+
charset-normalizer==3.4.4
2424
# via requests
2525
contourpy==1.3.3
2626
# via matplotlib
@@ -30,25 +30,25 @@ deprecation==2.1.0
3030
# via rapidyaml
3131
distlib==0.4.0
3232
# via virtualenv
33-
filelock==3.19.1
33+
filelock==3.20.0
3434
# via virtualenv
35-
fonttools==4.60.0
35+
fonttools==4.60.1
3636
# via matplotlib
37-
fourcipp==1.18.0
37+
fourcipp==1.39.0
3838
# via -r requirements.in
39-
frozenlist==1.7.0
39+
frozenlist==1.8.0
4040
# via
4141
# aiohttp
4242
# aiosignal
43-
identify==2.6.14
43+
identify==2.6.15
4444
# via pre-commit
45-
idna==3.10
45+
idna==3.11
4646
# via
4747
# requests
4848
# yarl
49-
iniconfig==2.1.0
49+
iniconfig==2.3.0
5050
# via pytest
51-
jsonschema-rs==0.33.0
51+
jsonschema-rs==0.37.1
5252
# via fourcipp
5353
kiwisolver==1.4.9
5454
# via matplotlib
@@ -60,7 +60,7 @@ loguru==0.7.3
6060
# lnmmeshio
6161
markdown-it-py==4.0.0
6262
# via rich
63-
matplotlib==3.10.6
63+
matplotlib==3.10.7
6464
# via
6565
# pyvista
6666
# vtk
@@ -70,21 +70,21 @@ meshio==5.3.5
7070
# via lnmmeshio
7171
more-itertools==10.8.0
7272
# via trame-server
73-
msgpack==1.1.1
73+
msgpack==1.1.2
7474
# via wslink
75-
multidict==6.6.4
75+
multidict==6.7.0
7676
# via
7777
# aiohttp
7878
# yarl
79-
narwhals==2.5.0
79+
narwhals==2.12.0
8080
# via plotly
81-
netcdf4==1.7.2
81+
netcdf4==1.7.3
8282
# via -r requirements.in
8383
nodeenv==1.9.1
8484
# via pre-commit
85-
numexpr==2.13.0
85+
numexpr==2.14.1
8686
# via -r requirements.in
87-
numpy==2.3.3
87+
numpy==2.3.5
8888
# via
8989
# -r requirements.in
9090
# cftime
@@ -104,27 +104,27 @@ packaging==25.0
104104
# plotly
105105
# pooch
106106
# pytest
107-
pandas==2.3.2
107+
pandas==2.3.3
108108
# via -r requirements.in
109-
pillow==11.3.0
109+
pillow==12.0.0
110110
# via
111111
# matplotlib
112112
# pyvista
113-
platformdirs==4.4.0
113+
platformdirs==4.5.0
114114
# via
115115
# pooch
116116
# virtualenv
117-
plotly==6.3.0
117+
plotly==6.5.0
118118
# via
119119
# -r requirements.in
120120
# trame-plotly
121121
pluggy==1.6.0
122122
# via pytest
123123
pooch==1.8.2
124124
# via pyvista
125-
pre-commit==4.3.0
125+
pre-commit==4.5.0
126126
# via -r requirements.in
127-
propcache==0.3.2
127+
propcache==0.4.1
128128
# via
129129
# aiohttp
130130
# yarl
@@ -134,7 +134,7 @@ pygments==2.19.2
134134
# rich
135135
pyparsing==3.2.5
136136
# via matplotlib
137-
pytest==8.4.2
137+
pytest==9.0.1
138138
# via -r requirements.in
139139
python-dateutil==2.9.0.post0
140140
# via
@@ -144,30 +144,30 @@ python-utils==3.9.1
144144
# via lnmmeshio
145145
pytz==2025.2
146146
# via pandas
147-
pyvista==0.46.3
147+
pyvista==0.46.4
148148
# via -r requirements.in
149-
pyyaml==6.0.2
149+
pyyaml==6.0.3
150150
# via
151151
# lnmmeshio
152152
# pre-commit
153153
# trame
154-
rapidyaml==0.9.0
154+
rapidyaml==0.10.0
155155
# via fourcipp
156-
regex==2025.9.18
156+
regex==2025.11.3
157157
# via fourcipp
158158
requests==2.32.5
159159
# via pooch
160-
rich==14.1.0
160+
rich==14.2.0
161161
# via meshio
162-
scooby==0.10.2
162+
scooby==0.11.0
163163
# via pyvista
164164
six==1.17.0
165165
# via python-dateutil
166166
tqdm==4.66.5
167167
# via lnmmeshio
168168
trame==3.12.0
169169
# via -r requirements.in
170-
trame-client==3.10.4
170+
trame-client==3.11.2
171171
# via
172172
# trame
173173
# trame-components
@@ -182,11 +182,11 @@ trame-components==2.5.0
182182
# via -r requirements.in
183183
trame-plotly==3.1.0
184184
# via -r requirements.in
185-
trame-server==3.6.1
185+
trame-server==3.8.1
186186
# via trame
187-
trame-vtk==2.9.1
187+
trame-vtk==2.10.0
188188
# via -r requirements.in
189-
trame-vuetify==3.0.3
189+
trame-vuetify==3.1.0
190190
# via -r requirements.in
191191
typing-extensions==4.15.0
192192
# via
@@ -197,15 +197,15 @@ tzdata==2025.2
197197
# via pandas
198198
urllib3==2.5.0
199199
# via requests
200-
virtualenv==20.34.0
200+
virtualenv==20.35.4
201201
# via pre-commit
202202
vtk==9.4.2
203203
# via
204204
# -r requirements.in
205205
# pyvista
206-
wslink==2.4.0
206+
wslink==2.5.0
207207
# via
208208
# trame
209209
# trame-server
210-
yarl==1.20.1
210+
yarl==1.22.0
211211
# via aiohttp

src/fourc_webviewer/fourc_webserver.py

Lines changed: 16 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,9 @@
99

1010
import numpy as np
1111
import pyvista as pv
12-
import yaml
1312
from fourcipp import CONFIG
1413
from fourcipp.fourc_input import FourCInput, ValidationError
14+
from loguru import logger
1515
from trame.app import get_server
1616
from trame.decorators import TrameApp, change, controller
1717

@@ -30,18 +30,16 @@
3030
from fourc_webviewer.python_utils import (
3131
convert_string2number,
3232
dict_leaves_to_number_if_schema,
33-
dict_number_leaves_to_string,
3433
find_value_recursively,
3534
parse_validation_error_text,
36-
smart_string2number_cast,
3735
)
3836
from fourc_webviewer.read_geometry_from_file import (
3937
FourCGeometry,
4038
)
4139

4240
# Global variable
4341
# factor which scales the spheres used to represent nodal design conditions and result descriptions with respect to the problem length scale
44-
PV_SPHERE_FRAC_SCALE = 1.0 / 45.0
42+
PV_SPHERE_FRAC_SCALE = 1.0 / 75.0
4543

4644
# always set pyvista to plot off screen with Trame
4745
pv.OFF_SCREEN = True
@@ -124,6 +122,7 @@ def __init__(
124122
fourc_geometry = FourCGeometry(
125123
fourc_yaml_file=fourc_yaml_file,
126124
temp_dir=Path(self._server_vars["temp_dir_object"].name),
125+
first_render=True,
127126
)
128127
self.state.vtu_path = fourc_geometry.vtu_file_path
129128

@@ -274,8 +273,10 @@ def init_pyvista_render_objects(self):
274273

275274
self._server_vars["render_window"].clear_actors()
276275

276+
# read problem mesh
277277
problem_mesh = pv.read(self.state.vtu_path)
278-
# get problem mesh
278+
279+
# save problem mesh as actor
279280
self._actors["problem_mesh"] = self._server_vars["render_window"].add_mesh(
280281
problem_mesh, color="bisque", opacity=0.2, render=False
281282
)
@@ -285,6 +286,7 @@ def init_pyvista_render_objects(self):
285286
for material in self.state.materials_section.keys():
286287
# get meshes of materials
287288
master_mat_ind = self.determine_master_mat_ind_for_material(material)
289+
288290
self._actors["material_meshes"][material] = self._server_vars[
289291
"render_window"
290292
].add_mesh(
@@ -305,11 +307,11 @@ def init_pyvista_render_objects(self):
305307
self._actors["dc_geometry_entities"] = {}
306308
# get nodes of the selected condition geometries + entities
307309
for dc_entity in all_dc_entities:
308-
points = problem_mesh.threshold(
309-
value=1.0,
310-
scalars=f"d{dc_entity['geometry_type'].lower()}{dc_entity['entity'].replace('E', '')}",
311-
preference="point",
312-
).points
310+
# get mesh points associated with design condition
311+
condition_array_name = f"d{dc_entity['geometry_type'].lower()}{dc_entity['entity'].replace('E', '')}"
312+
points = problem_mesh.points[
313+
np.where(problem_mesh.point_data[condition_array_name] == 1)[0], :
314+
]
313315

314316
if points.size:
315317
pts = pv.PolyData(points)
@@ -449,7 +451,7 @@ def init_general_sections_state_and_server_vars(self):
449451
].sections.items():
450452
if (
451453
not any(substr in section_name for substr in substr_to_exclude)
452-
and not section_name in sect_to_exclude
454+
and section_name not in sect_to_exclude
453455
): # account for sections to be excluded as defined above
454456
# check if the current section is "SOLVER<number>"
455457
if re.match("^SOLVER [0-9]+", section_name): # yes
@@ -898,7 +900,9 @@ def init_funct_state_and_server_vars(self):
898900

899901
else:
900902
# warning that this function item is not known
901-
print(f"Unknown function item {item_data} for funct {funct_name}!")
903+
logger.warning(
904+
f"Unknown function item {item_data} for funct {funct_name}!"
905+
)
902906

903907
# we don't enable visualization
904908
item_data["VISUALIZATION"] = False
@@ -1175,11 +1179,6 @@ def change_selected_material(self, selected_material, **kwargs):
11751179
# we need to select the material region based on the newly selected
11761180
# material (if we are not in an initial rendering scenario)
11771181
if self._server_vars["render_count"]["change_selected_material"] > 0:
1178-
# first get the master material id
1179-
master_mat_id = self.determine_master_mat_ind_for_material(
1180-
selected_material
1181-
)
1182-
11831182
# update plotter / render objects
11841183
self.update_pyvista_render_objects()
11851184

src/fourc_webviewer/input_file_utils/fourc_yaml_file_visualization.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
import numexpr as ne
99
import numpy as np
1010
import plotly.express as px
11+
from loguru import logger
1112

1213
from fourc_webviewer.input_file_utils.io_utils import (
1314
get_variable_data_by_name_in_funct_item,
@@ -261,6 +262,8 @@ def construct_funct_string_from_variable_data(
261262

262263
case _:
263264
# warning that this variable type is not yet supported for visualization
264-
print(f"Variable with {variable_data} not supported for visualization!")
265+
logger.warning(
266+
f"Variable with {variable_data} not supported for visualization!"
267+
)
265268

266269
return funct_string

src/fourc_webviewer/input_file_utils/io_utils.py

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
from pathlib import Path
88

99
from fourcipp.fourc_input import FourCInput
10+
from loguru import logger
1011

1112
from fourc_webviewer.python_utils import flatten_list
1213

@@ -39,7 +40,7 @@ def read_fourc_yaml_file(fourc_yaml_file):
3940
# validate 4C yaml file
4041
fourc_yaml_content.validate()
4142
except Exception as exc:
42-
print(exc) # currently, we throw the exception as terminal output
43+
logger.error(exc) # currently, we throw the exception as terminal output
4344
return (FourCInput({}), [], 0, 0, False)
4445

4546
with open(fourc_yaml_file, "r") as input_file:
@@ -78,7 +79,7 @@ def write_fourc_yaml_file(fourc_yaml_content, new_fourc_yaml_file):
7879
try:
7980
fourc_yaml_content.validate()
8081
except Exception as exc:
81-
print(exc) # currently, we throw the exception as terminal output
82+
logger.error(exc) # currently, we throw the exception as terminal output
8283
return False
8384

8485
# check if the output file suffix is supported
@@ -251,6 +252,11 @@ def mat_specifiers():
251252
"VISCOPLAST_LAW_ID",
252253
"FIBER_READER_ID",
253254
"STR_TENS_ID",
255+
"MATIDSCONST",
256+
"MATIDMIXTURERULE",
257+
"GROWTH_STRATEGY",
258+
"FIBER_MATERIAL_ID",
259+
"PRESTRESS_STRATEGY",
254260
]
255261

256262

0 commit comments

Comments
 (0)