pyvale 2025.4.1__py3-none-any.whl → 2025.5.1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of pyvale might be problematic. Click here for more details.
- pyvale/__init__.py +18 -3
- pyvale/analyticmeshgen.py +1 -0
- pyvale/analyticsimdatafactory.py +18 -13
- pyvale/analyticsimdatagenerator.py +105 -72
- pyvale/blendercalibrationdata.py +15 -0
- pyvale/blenderlightdata.py +26 -0
- pyvale/blendermaterialdata.py +15 -0
- pyvale/blenderrenderdata.py +30 -0
- pyvale/blenderscene.py +488 -0
- pyvale/blendertools.py +420 -0
- pyvale/camera.py +6 -5
- pyvale/cameradata.py +25 -7
- pyvale/cameradata2d.py +6 -4
- pyvale/camerastereo.py +217 -0
- pyvale/cameratools.py +206 -11
- pyvale/cython/rastercyth.py +6 -2
- pyvale/data/cal_target.tiff +0 -0
- pyvale/dataset.py +73 -14
- pyvale/errorcalculator.py +8 -10
- pyvale/errordriftcalc.py +10 -9
- pyvale/errorintegrator.py +19 -21
- pyvale/errorrand.py +33 -39
- pyvale/errorsyscalib.py +134 -0
- pyvale/errorsysdep.py +19 -22
- pyvale/errorsysfield.py +49 -41
- pyvale/errorsysindep.py +79 -175
- pyvale/examples/basics/ex1_1_basicscalars_therm2d.py +131 -0
- pyvale/examples/basics/ex1_2_sensormodel_therm2d.py +158 -0
- pyvale/examples/basics/ex1_3_customsens_therm3d.py +216 -0
- pyvale/examples/basics/ex1_4_basicerrors_therm3d.py +153 -0
- pyvale/examples/basics/ex1_5_fielderrs_therm3d.py +168 -0
- pyvale/examples/basics/ex1_6_caliberrs_therm2d.py +133 -0
- pyvale/examples/basics/ex1_7_spatavg_therm2d.py +123 -0
- pyvale/examples/basics/ex2_1_basicvectors_disp2d.py +112 -0
- pyvale/examples/basics/ex2_2_vectorsens_disp2d.py +111 -0
- pyvale/examples/basics/ex2_3_sensangle_disp2d.py +139 -0
- pyvale/examples/basics/ex2_4_chainfielderrs_disp2d.py +196 -0
- pyvale/examples/basics/ex2_5_vectorfields3d_disp3d.py +109 -0
- pyvale/examples/basics/ex3_1_basictensors_strain2d.py +114 -0
- pyvale/examples/basics/ex3_2_tensorsens2d_strain2d.py +111 -0
- pyvale/examples/basics/ex3_3_tensorsens3d_strain3d.py +182 -0
- pyvale/examples/basics/ex4_1_expsim2d_thermmech2d.py +171 -0
- pyvale/examples/basics/ex4_2_expsim3d_thermmech3d.py +252 -0
- pyvale/examples/{analyticdatagen → genanalyticdata}/ex1_1_scalarvisualisation.py +6 -9
- pyvale/examples/{analyticdatagen → genanalyticdata}/ex1_2_scalarcasebuild.py +8 -11
- pyvale/examples/{analyticdatagen → genanalyticdata}/ex2_1_analyticsensors.py +9 -12
- pyvale/examples/imagedef2d/ex_imagedef2d_todisk.py +8 -15
- pyvale/examples/renderblender/ex1_1_blenderscene.py +121 -0
- pyvale/examples/renderblender/ex1_2_blenderdeformed.py +119 -0
- pyvale/examples/renderblender/ex2_1_stereoscene.py +128 -0
- pyvale/examples/renderblender/ex2_2_stereodeformed.py +131 -0
- pyvale/examples/renderblender/ex3_1_blendercalibration.py +120 -0
- pyvale/examples/{rasterisation → renderrasterisation}/ex_rastenp.py +3 -2
- pyvale/examples/{rasterisation → renderrasterisation}/ex_rastercyth_oneframe.py +2 -2
- pyvale/examples/{rasterisation → renderrasterisation}/ex_rastercyth_static_cypara.py +3 -8
- pyvale/examples/{rasterisation → renderrasterisation}/ex_rastercyth_static_pypara.py +6 -7
- pyvale/examples/{ex1_4_thermal2d.py → visualisation/ex1_1_plot_traces.py} +32 -16
- pyvale/examples/{features/ex_animation_tools_3dmonoblock.py → visualisation/ex2_1_animate_sim.py} +37 -31
- pyvale/experimentsimulator.py +107 -30
- pyvale/field.py +2 -9
- pyvale/fieldconverter.py +98 -22
- pyvale/fieldsampler.py +2 -2
- pyvale/fieldscalar.py +10 -10
- pyvale/fieldtensor.py +15 -17
- pyvale/fieldtransform.py +7 -2
- pyvale/fieldvector.py +6 -7
- pyvale/generatorsrandom.py +25 -47
- pyvale/imagedef2d.py +6 -2
- pyvale/integratorfactory.py +2 -2
- pyvale/integratorquadrature.py +50 -24
- pyvale/integratorrectangle.py +85 -7
- pyvale/integratorspatial.py +4 -4
- pyvale/integratortype.py +3 -3
- pyvale/output.py +17 -0
- pyvale/pyvaleexceptions.py +11 -0
- pyvale/raster.py +6 -5
- pyvale/rastercy.py +6 -4
- pyvale/rasternp.py +6 -4
- pyvale/rendermesh.py +6 -2
- pyvale/sensorarray.py +2 -2
- pyvale/sensorarrayfactory.py +52 -65
- pyvale/sensorarraypoint.py +29 -30
- pyvale/sensordata.py +2 -2
- pyvale/sensordescriptor.py +138 -25
- pyvale/sensortools.py +3 -3
- pyvale/simtools.py +67 -0
- pyvale/visualexpplotter.py +99 -57
- pyvale/visualimagedef.py +11 -7
- pyvale/visualimages.py +6 -4
- pyvale/visualopts.py +372 -58
- pyvale/visualsimanimator.py +42 -13
- pyvale/visualsimsensors.py +318 -0
- pyvale/visualtools.py +69 -13
- pyvale/visualtraceplotter.py +52 -165
- {pyvale-2025.4.1.dist-info → pyvale-2025.5.1.dist-info}/METADATA +17 -14
- pyvale-2025.5.1.dist-info/RECORD +172 -0
- {pyvale-2025.4.1.dist-info → pyvale-2025.5.1.dist-info}/WHEEL +1 -1
- pyvale/examples/analyticdatagen/__init__.py +0 -5
- pyvale/examples/ex1_1_thermal2d.py +0 -86
- pyvale/examples/ex1_2_thermal2d.py +0 -108
- pyvale/examples/ex1_3_thermal2d.py +0 -110
- pyvale/examples/ex1_5_thermal2d.py +0 -102
- pyvale/examples/ex2_1_thermal3d .py +0 -84
- pyvale/examples/ex2_2_thermal3d.py +0 -51
- pyvale/examples/ex2_3_thermal3d.py +0 -106
- pyvale/examples/ex3_1_displacement2d.py +0 -44
- pyvale/examples/ex3_2_displacement2d.py +0 -76
- pyvale/examples/ex3_3_displacement2d.py +0 -101
- pyvale/examples/ex3_4_displacement2d.py +0 -102
- pyvale/examples/ex4_1_strain2d.py +0 -54
- pyvale/examples/ex4_2_strain2d.py +0 -76
- pyvale/examples/ex4_3_strain2d.py +0 -97
- pyvale/examples/ex5_1_multiphysics2d.py +0 -75
- pyvale/examples/ex6_1_multiphysics2d_expsim.py +0 -115
- pyvale/examples/ex6_2_multiphysics3d_expsim.py +0 -160
- pyvale/examples/features/__init__.py +0 -5
- pyvale/examples/features/ex_area_avg.py +0 -89
- pyvale/examples/features/ex_calibration_error.py +0 -108
- pyvale/examples/features/ex_chain_field_errs.py +0 -141
- pyvale/examples/features/ex_field_errs.py +0 -78
- pyvale/examples/features/ex_sensor_single_angle_batch.py +0 -110
- pyvale/optimcheckfuncs.py +0 -153
- pyvale/visualsimplotter.py +0 -182
- pyvale-2025.4.1.dist-info/RECORD +0 -163
- {pyvale-2025.4.1.dist-info → pyvale-2025.5.1.dist-info}/licenses/LICENSE +0 -0
- {pyvale-2025.4.1.dist-info → pyvale-2025.5.1.dist-info}/top_level.txt +0 -0
pyvale/fieldconverter.py
CHANGED
|
@@ -1,16 +1,19 @@
|
|
|
1
|
-
#
|
|
1
|
+
# ==============================================================================
|
|
2
2
|
# pyvale: the python validation engine
|
|
3
3
|
# License: MIT
|
|
4
4
|
# Copyright (C) 2025 The Computer Aided Validation Team
|
|
5
|
-
#
|
|
5
|
+
# ==============================================================================
|
|
6
|
+
|
|
7
|
+
"""
|
|
8
|
+
This module provides functions for manipulating simulation data objects to be
|
|
9
|
+
compatible with the underlying machinery of pyvale.
|
|
10
|
+
"""
|
|
6
11
|
|
|
7
|
-
import warnings
|
|
8
12
|
import numpy as np
|
|
9
13
|
import pyvista as pv
|
|
10
14
|
from pyvista import CellType
|
|
11
15
|
import mooseherder as mh
|
|
12
16
|
|
|
13
|
-
|
|
14
17
|
def simdata_to_pyvista(sim_data: mh.SimData,
|
|
15
18
|
components: tuple[str,...] | None,
|
|
16
19
|
elem_dims: int
|
|
@@ -44,6 +47,8 @@ def simdata_to_pyvista(sim_data: mh.SimData,
|
|
|
44
47
|
(nodes_per_elem,n_elems) = this_connect.shape
|
|
45
48
|
|
|
46
49
|
this_cell_type = _get_pyvista_cell_type(nodes_per_elem,elem_dims)
|
|
50
|
+
assert this_cell_type is not None, ("Cell type with dimension " +
|
|
51
|
+
f"{elem_dims} and {nodes_per_elem} nodes per element not recognised.")
|
|
47
52
|
|
|
48
53
|
# VTK and exodus have different winding for 3D higher order quads
|
|
49
54
|
this_connect = _exodus_to_pyvista_connect(this_cell_type,this_connect)
|
|
@@ -69,19 +74,61 @@ def simdata_to_pyvista(sim_data: mh.SimData,
|
|
|
69
74
|
return (pv_grid,pv_grid_vis)
|
|
70
75
|
|
|
71
76
|
|
|
72
|
-
def scale_length_units(
|
|
73
|
-
|
|
74
|
-
|
|
77
|
+
def scale_length_units(scale: float,
|
|
78
|
+
sim_data: mh.SimData,
|
|
79
|
+
disp_comps: tuple[str,...] | None = None,
|
|
80
|
+
) -> mh.SimData:
|
|
81
|
+
"""Used to scale the length units of a simulation. Commonly used to convert
|
|
82
|
+
SI units to mm for use with visualisation tools and rendering algorithms.
|
|
75
83
|
|
|
84
|
+
Parameters
|
|
85
|
+
----------
|
|
86
|
+
scale : float
|
|
87
|
+
Scale multiplier used to scale the coordinates and displacement fields
|
|
88
|
+
if specified.
|
|
89
|
+
sim_data : mh.SimData
|
|
90
|
+
Simulation dataclass that will be scaled.
|
|
91
|
+
disp_comps : tuple[str,...] | None, optional
|
|
92
|
+
Tuple of string keys for the displacement keys to be scaled, by default
|
|
93
|
+
None. If None then the displacements are not scaled.
|
|
94
|
+
|
|
95
|
+
Returns
|
|
96
|
+
-------
|
|
97
|
+
mh.SimData
|
|
98
|
+
Simulation dataclass with scaled length units.
|
|
99
|
+
"""
|
|
76
100
|
sim_data.coords = sim_data.coords*scale
|
|
77
|
-
|
|
78
|
-
|
|
101
|
+
|
|
102
|
+
if disp_comps is not None:
|
|
103
|
+
for cc in disp_comps:
|
|
104
|
+
sim_data.node_vars[cc] = sim_data.node_vars[cc]*scale
|
|
79
105
|
|
|
80
106
|
return sim_data
|
|
81
107
|
|
|
82
108
|
|
|
83
109
|
# TODO: make this work for sim_data with multiple connectivity
|
|
84
110
|
def extract_surf_mesh(sim_data: mh.SimData) -> mh.SimData:
|
|
111
|
+
"""Extracts a surface mesh from a 3D simulation dataclass. Useful for
|
|
112
|
+
limiting the memory required for analysing sensors that only measure surface
|
|
113
|
+
fields. This function currently supports:
|
|
114
|
+
- A single connectivity table
|
|
115
|
+
- Higher order retrahedral and hexahedral elements (but not wedges or
|
|
116
|
+
pyramids)
|
|
117
|
+
|
|
118
|
+
NOTE: this function returns the surface mesh with element nodal winding
|
|
119
|
+
consistent with th exodus output format.
|
|
120
|
+
|
|
121
|
+
Parameters
|
|
122
|
+
----------
|
|
123
|
+
sim_data : mh.SimData
|
|
124
|
+
Simulation dataclass containing the 3D mesh from which the surface mesh
|
|
125
|
+
is to be extracted.
|
|
126
|
+
|
|
127
|
+
Returns
|
|
128
|
+
-------
|
|
129
|
+
mh.SimData
|
|
130
|
+
Simulation data class containing the data for the surface mesh.
|
|
131
|
+
"""
|
|
85
132
|
|
|
86
133
|
# NOTE: need to fix exodus 1 indexing for now and put it back at the end
|
|
87
134
|
# shape=(nodes_per_elem,num_elems)
|
|
@@ -162,7 +209,7 @@ def extract_surf_mesh(sim_data: mh.SimData) -> mh.SimData:
|
|
|
162
209
|
return face_data
|
|
163
210
|
|
|
164
211
|
|
|
165
|
-
def _get_pyvista_cell_type(nodes_per_elem: int, spat_dim: int) -> CellType:
|
|
212
|
+
def _get_pyvista_cell_type(nodes_per_elem: int, spat_dim: int) -> CellType | None:
|
|
166
213
|
"""Helper function to identify the pyvista element type in the mesh.
|
|
167
214
|
|
|
168
215
|
Parameters
|
|
@@ -174,10 +221,10 @@ def _get_pyvista_cell_type(nodes_per_elem: int, spat_dim: int) -> CellType:
|
|
|
174
221
|
|
|
175
222
|
Returns
|
|
176
223
|
-------
|
|
177
|
-
CellType
|
|
224
|
+
CellType | None
|
|
178
225
|
Enumeration describing the element type in pyvista.
|
|
179
226
|
"""
|
|
180
|
-
cell_type =
|
|
227
|
+
cell_type = None
|
|
181
228
|
|
|
182
229
|
if spat_dim == 2:
|
|
183
230
|
if nodes_per_elem == 4:
|
|
@@ -192,10 +239,6 @@ def _get_pyvista_cell_type(nodes_per_elem: int, spat_dim: int) -> CellType:
|
|
|
192
239
|
cell_type = CellType.QUADRATIC_QUAD
|
|
193
240
|
elif nodes_per_elem == 9:
|
|
194
241
|
cell_type = CellType.BIQUADRATIC_QUAD
|
|
195
|
-
else:
|
|
196
|
-
warnings.warn(f"Cell type 2D with {nodes_per_elem} "
|
|
197
|
-
+ "nodes not recognised. Defaulting to 4 node QUAD")
|
|
198
|
-
cell_type = CellType.QUAD
|
|
199
242
|
else:
|
|
200
243
|
if nodes_per_elem == 8:
|
|
201
244
|
cell_type = CellType.HEXAHEDRON
|
|
@@ -207,15 +250,29 @@ def _get_pyvista_cell_type(nodes_per_elem: int, spat_dim: int) -> CellType:
|
|
|
207
250
|
cell_type = CellType.QUADRATIC_HEXAHEDRON
|
|
208
251
|
elif nodes_per_elem == 27:
|
|
209
252
|
cell_type = CellType.TRIQUADRATIC_HEXAHEDRON
|
|
210
|
-
else:
|
|
211
|
-
warnings.warn(f"Cell type 3D with {nodes_per_elem} "
|
|
212
|
-
+ "nodes not recognised. Defaulting to 8 node HEX")
|
|
213
|
-
cell_type = CellType.HEXAHEDRON
|
|
214
253
|
|
|
215
254
|
return cell_type
|
|
216
255
|
|
|
217
256
|
|
|
218
|
-
def _exodus_to_pyvista_connect(cell_type: CellType,
|
|
257
|
+
def _exodus_to_pyvista_connect(cell_type: CellType,
|
|
258
|
+
connect: np.ndarray) -> np.ndarray:
|
|
259
|
+
"""Helper function that specifies the nodal winding map for higher order
|
|
260
|
+
tet and hex elements between the exodus output format and pyvista (VTK).
|
|
261
|
+
|
|
262
|
+
Parameters
|
|
263
|
+
----------
|
|
264
|
+
cell_type : CellType
|
|
265
|
+
pyvista (VTK) cell type enumeration.
|
|
266
|
+
connect : np.ndarray
|
|
267
|
+
Input connectivity table in exodus winding format.
|
|
268
|
+
shape=(nodes_per_elem,num_elems)
|
|
269
|
+
|
|
270
|
+
Returns
|
|
271
|
+
-------
|
|
272
|
+
np.ndarray
|
|
273
|
+
Output connectivity table in pyvista (VTK) format.
|
|
274
|
+
shape=(nodes_per_elem,num_elems)
|
|
275
|
+
"""
|
|
219
276
|
copy_connect = np.copy(connect)
|
|
220
277
|
|
|
221
278
|
# NOTE: it looks like VTK does not support TET14
|
|
@@ -235,7 +292,25 @@ def _exodus_to_pyvista_connect(cell_type: CellType, connect: np.ndarray) -> np.n
|
|
|
235
292
|
|
|
236
293
|
|
|
237
294
|
def _get_surf_map(nodes_per_elem: int) -> np.ndarray:
|
|
295
|
+
"""Helper function specifying the mapping from 3D tet and hex elements to
|
|
296
|
+
the individual faces consistent with the exodus output format.
|
|
238
297
|
|
|
298
|
+
Parameters
|
|
299
|
+
----------
|
|
300
|
+
nodes_per_elem : int
|
|
301
|
+
Number of nodes per element.
|
|
302
|
+
|
|
303
|
+
Returns
|
|
304
|
+
-------
|
|
305
|
+
np.ndarray
|
|
306
|
+
Array of indices mapping the nodes to faces with shape=(num_faces,n
|
|
307
|
+
odes_per_face)
|
|
308
|
+
|
|
309
|
+
Raises
|
|
310
|
+
------
|
|
311
|
+
ValueError
|
|
312
|
+
Element type is not supported.
|
|
313
|
+
"""
|
|
239
314
|
if nodes_per_elem == 4: # TET4
|
|
240
315
|
return np.array(((0,1,2),
|
|
241
316
|
(0,3,1),
|
|
@@ -272,4 +347,5 @@ def _get_surf_map(nodes_per_elem: int) -> np.ndarray:
|
|
|
272
347
|
(0,4,5,1,12,16,13,8,25),
|
|
273
348
|
(2,6,7,3,14,18,15,10,26)))
|
|
274
349
|
|
|
275
|
-
raise ValueError("Number of nodes does not match a 3D element type for
|
|
350
|
+
raise ValueError("Number of nodes does not match a 3D element type for " \
|
|
351
|
+
"surface extraction.")
|
pyvale/fieldsampler.py
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
#
|
|
1
|
+
# ==============================================================================
|
|
2
2
|
# pyvale: the python validation engine
|
|
3
3
|
# License: MIT
|
|
4
4
|
# Copyright (C) 2025 The Computer Aided Validation Team
|
|
5
|
-
#
|
|
5
|
+
# ==============================================================================
|
|
6
6
|
|
|
7
7
|
import numpy as np
|
|
8
8
|
import pyvista as pv
|
pyvale/fieldscalar.py
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
#
|
|
1
|
+
# ==============================================================================
|
|
2
2
|
# pyvale: the python validation engine
|
|
3
3
|
# License: MIT
|
|
4
4
|
# Copyright (C) 2025 The Computer Aided Validation Team
|
|
5
|
-
#
|
|
5
|
+
# ==============================================================================
|
|
6
6
|
|
|
7
7
|
import numpy as np
|
|
8
8
|
import pyvista as pv
|
|
@@ -13,40 +13,40 @@ from pyvale.field import IField
|
|
|
13
13
|
from pyvale.fieldconverter import simdata_to_pyvista
|
|
14
14
|
from pyvale.fieldsampler import sample_pyvista_grid
|
|
15
15
|
|
|
16
|
+
|
|
16
17
|
class FieldScalar(IField):
|
|
17
18
|
"""Class for sampling (interpolating) scalar fields from simulations to
|
|
18
19
|
provide sensor values at specified locations and times.
|
|
19
20
|
|
|
20
21
|
Implements the `IField` interface.
|
|
21
22
|
"""
|
|
22
|
-
__slots__ = ("_field_key","
|
|
23
|
+
__slots__ = ("_field_key","_elem_dims","_sim_data","_pyvista_grid",
|
|
23
24
|
"_pyvista_vis")
|
|
24
25
|
|
|
25
26
|
def __init__(self,
|
|
26
27
|
sim_data: mh.SimData,
|
|
27
28
|
field_key: str,
|
|
28
|
-
|
|
29
|
-
"""
|
|
30
|
-
|
|
29
|
+
elem_dims: int) -> None:
|
|
30
|
+
"""
|
|
31
31
|
Parameters
|
|
32
32
|
----------
|
|
33
33
|
sim_data : mh.SimData
|
|
34
34
|
Simulation data object containing the mesh and field to interpolate.
|
|
35
35
|
field_key : str
|
|
36
36
|
String key for the scalar field component in the `SimData` object.
|
|
37
|
-
|
|
37
|
+
elem_dims : int
|
|
38
38
|
Number of spatial dimensions (2 or 3) used for identifying element
|
|
39
39
|
types.
|
|
40
40
|
"""
|
|
41
41
|
|
|
42
42
|
self._field_key = field_key
|
|
43
|
-
self.
|
|
43
|
+
self._elem_dims = elem_dims
|
|
44
44
|
|
|
45
45
|
self._sim_data = sim_data
|
|
46
46
|
(self._pyvista_grid,self._pyvista_vis) = simdata_to_pyvista(
|
|
47
47
|
self._sim_data,
|
|
48
48
|
(self._field_key,),
|
|
49
|
-
self.
|
|
49
|
+
self._elem_dims
|
|
50
50
|
)
|
|
51
51
|
|
|
52
52
|
def set_sim_data(self, sim_data: mh.SimData) -> None:
|
|
@@ -64,7 +64,7 @@ class FieldScalar(IField):
|
|
|
64
64
|
(self._pyvista_grid,self._pyvista_vis) = simdata_to_pyvista(
|
|
65
65
|
sim_data,
|
|
66
66
|
(self._field_key,),
|
|
67
|
-
self.
|
|
67
|
+
self._elem_dims
|
|
68
68
|
)
|
|
69
69
|
|
|
70
70
|
def get_sim_data(self) -> mh.SimData:
|
pyvale/fieldtensor.py
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
#
|
|
1
|
+
# ==============================================================================
|
|
2
2
|
# pyvale: the python validation engine
|
|
3
3
|
# License: MIT
|
|
4
4
|
# Copyright (C) 2025 The Computer Aided Validation Team
|
|
5
|
-
#
|
|
5
|
+
# ==============================================================================
|
|
6
6
|
|
|
7
7
|
import numpy as np
|
|
8
8
|
import pyvista as pv
|
|
@@ -17,6 +17,8 @@ from pyvale.fieldtransform import (transform_tensor_2d,
|
|
|
17
17
|
transform_tensor_3d,
|
|
18
18
|
transform_tensor_3d_batch)
|
|
19
19
|
|
|
20
|
+
# TODO:
|
|
21
|
+
# - Checking to ensure normal and dev components are consistent
|
|
20
22
|
|
|
21
23
|
class FieldTensor(IField):
|
|
22
24
|
"""Class for sampling (interpolating) tensor fields from simulations to
|
|
@@ -29,32 +31,28 @@ class FieldTensor(IField):
|
|
|
29
31
|
|
|
30
32
|
def __init__(self,
|
|
31
33
|
sim_data: mh.SimData,
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
"""
|
|
37
|
-
|
|
34
|
+
field_name: str,
|
|
35
|
+
norm_comps: tuple[str,...],
|
|
36
|
+
dev_comps: tuple[str,...],
|
|
37
|
+
elem_dims: int) -> None:
|
|
38
|
+
"""
|
|
38
39
|
Parameters
|
|
39
40
|
----------
|
|
40
41
|
sim_data : mh.SimData
|
|
41
42
|
Simulation data object containing the mesh and field to interpolate.
|
|
42
|
-
|
|
43
|
+
field_name : str
|
|
43
44
|
String describing the tensor field. For example: 'strain'.
|
|
44
45
|
components : tuple[str,...]
|
|
45
46
|
String keys to the field components in the `SimData` object. For
|
|
46
47
|
example ('stain_xx','strain_yy','strain_xy').
|
|
47
|
-
|
|
48
|
+
elem_dims : int
|
|
48
49
|
Number of spatial dimensions (2 or 3) used for identifying element
|
|
49
50
|
types.
|
|
50
51
|
"""
|
|
51
|
-
self._field_key =
|
|
52
|
-
self._norm_components =
|
|
53
|
-
self._dev_components =
|
|
54
|
-
self._spat_dims =
|
|
55
|
-
|
|
56
|
-
#TODO: do some checking to make sure norm/dev components are consistent
|
|
57
|
-
# based on the spatial dimensions
|
|
52
|
+
self._field_key = field_name
|
|
53
|
+
self._norm_components = norm_comps
|
|
54
|
+
self._dev_components = dev_comps
|
|
55
|
+
self._spat_dims = elem_dims
|
|
58
56
|
|
|
59
57
|
self._sim_data = sim_data
|
|
60
58
|
(self._pyvista_grid,self._pyvista_vis) = simdata_to_pyvista(
|
pyvale/fieldtransform.py
CHANGED
|
@@ -1,8 +1,13 @@
|
|
|
1
|
-
#
|
|
1
|
+
# ==============================================================================
|
|
2
2
|
# pyvale: the python validation engine
|
|
3
3
|
# License: MIT
|
|
4
4
|
# Copyright (C) 2025 The Computer Aided Validation Team
|
|
5
|
-
#
|
|
5
|
+
# ==============================================================================
|
|
6
|
+
|
|
7
|
+
"""
|
|
8
|
+
This module contains a set of functions for transforming vector and tensor
|
|
9
|
+
fields based on an input transformation matrix.
|
|
10
|
+
"""
|
|
6
11
|
|
|
7
12
|
import numpy as np
|
|
8
13
|
|
pyvale/fieldvector.py
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
#
|
|
1
|
+
# ==============================================================================
|
|
2
2
|
# pyvale: the python validation engine
|
|
3
3
|
# License: MIT
|
|
4
4
|
# Copyright (C) 2025 The Computer Aided Validation Team
|
|
5
|
-
#
|
|
5
|
+
# ==============================================================================
|
|
6
6
|
|
|
7
7
|
import numpy as np
|
|
8
8
|
import pyvista as pv
|
|
@@ -30,9 +30,8 @@ class FieldVector(IField):
|
|
|
30
30
|
sim_data: mh.SimData,
|
|
31
31
|
field_key: str,
|
|
32
32
|
components: tuple[str,...],
|
|
33
|
-
|
|
34
|
-
"""
|
|
35
|
-
|
|
33
|
+
elem_dims: int) -> None:
|
|
34
|
+
"""
|
|
36
35
|
Parameters
|
|
37
36
|
----------
|
|
38
37
|
sim_data : mh.SimData
|
|
@@ -42,13 +41,13 @@ class FieldVector(IField):
|
|
|
42
41
|
components : tuple[str,...]
|
|
43
42
|
String keys to the field components in the `SimData` object. For
|
|
44
43
|
example ('disp_x','disp_y').
|
|
45
|
-
|
|
44
|
+
elem_dims : int
|
|
46
45
|
Number of spatial dimensions (2 or 3) used for identifying element
|
|
47
46
|
types.
|
|
48
47
|
"""
|
|
49
48
|
self._field_key = field_key
|
|
50
49
|
self._components = components
|
|
51
|
-
self._spat_dims =
|
|
50
|
+
self._spat_dims = elem_dims
|
|
52
51
|
|
|
53
52
|
self._sim_data = sim_data
|
|
54
53
|
(self._pyvista_grid,self._pyvista_vis) = simdata_to_pyvista(
|
pyvale/generatorsrandom.py
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
|
-
#
|
|
1
|
+
# ==============================================================================
|
|
2
2
|
# pyvale: the python validation engine
|
|
3
3
|
# License: MIT
|
|
4
4
|
# Copyright (C) 2025 The Computer Aided Validation Team
|
|
5
|
-
#
|
|
5
|
+
# ==============================================================================
|
|
6
6
|
|
|
7
7
|
from abc import ABC, abstractmethod
|
|
8
8
|
import numpy as np
|
|
9
9
|
|
|
10
10
|
|
|
11
|
-
class
|
|
11
|
+
class IGenRandom(ABC):
|
|
12
12
|
"""Interface (abstract base class) for wrapping numpy random number
|
|
13
13
|
generation to allow probability distribution parameters to be specified in
|
|
14
14
|
the initialiser whereas the generation of random numbers has a common
|
|
@@ -34,7 +34,7 @@ class IGeneratorRandom(ABC):
|
|
|
34
34
|
pass
|
|
35
35
|
|
|
36
36
|
|
|
37
|
-
class
|
|
37
|
+
class GenNormal(IGenRandom):
|
|
38
38
|
"""Class wrapping the numpy normal random number generator. Implements the
|
|
39
39
|
IGeneratorRandom interface to allow for interchangeability with other random
|
|
40
40
|
number generators.
|
|
@@ -45,9 +45,7 @@ class GeneratorNormal(IGeneratorRandom):
|
|
|
45
45
|
std: float = 1.0,
|
|
46
46
|
mean: float = 0.0,
|
|
47
47
|
seed: int | None = None) -> None:
|
|
48
|
-
"""
|
|
49
|
-
an optional seed for the random generator to allow for reproducibility.
|
|
50
|
-
|
|
48
|
+
"""
|
|
51
49
|
Parameters
|
|
52
50
|
----------
|
|
53
51
|
std : float, optional
|
|
@@ -82,7 +80,7 @@ class GeneratorNormal(IGeneratorRandom):
|
|
|
82
80
|
size = shape)
|
|
83
81
|
|
|
84
82
|
|
|
85
|
-
class
|
|
83
|
+
class GenLogNormal(IGenRandom):
|
|
86
84
|
"""Class wrapping the numpy lognormal random generator. Implements the
|
|
87
85
|
IGeneratorRandom interface to allow for interchangeability with other random
|
|
88
86
|
number generators.
|
|
@@ -93,9 +91,7 @@ class GeneratorLogNormal(IGeneratorRandom):
|
|
|
93
91
|
std: float = 1.0,
|
|
94
92
|
mean: float = 0.0,
|
|
95
93
|
seed: int | None = None) -> None:
|
|
96
|
-
"""
|
|
97
|
-
an optional seed for the random generator to allow for reproducibility.
|
|
98
|
-
|
|
94
|
+
"""
|
|
99
95
|
Parameters
|
|
100
96
|
----------
|
|
101
97
|
std : float, optional
|
|
@@ -129,7 +125,7 @@ class GeneratorLogNormal(IGeneratorRandom):
|
|
|
129
125
|
size = shape)
|
|
130
126
|
|
|
131
127
|
|
|
132
|
-
class
|
|
128
|
+
class GenUniform(IGenRandom):
|
|
133
129
|
"""Class wrapping the numpy uniform random number generator. Implements the
|
|
134
130
|
IGeneratorRandom interface to allow for interchangeability with other random
|
|
135
131
|
number generators.
|
|
@@ -140,9 +136,7 @@ class GeneratorUniform(IGeneratorRandom):
|
|
|
140
136
|
low: float = -1.0,
|
|
141
137
|
high: float = 1.0,
|
|
142
138
|
seed: int | None = None) -> None:
|
|
143
|
-
"""
|
|
144
|
-
an optional seed for the random generator to allow for reproducibility.
|
|
145
|
-
|
|
139
|
+
"""
|
|
146
140
|
Parameters
|
|
147
141
|
----------
|
|
148
142
|
low : float, optional
|
|
@@ -176,7 +170,7 @@ class GeneratorUniform(IGeneratorRandom):
|
|
|
176
170
|
size = shape)
|
|
177
171
|
|
|
178
172
|
|
|
179
|
-
class
|
|
173
|
+
class GenExponential(IGenRandom):
|
|
180
174
|
"""Class wrapping the numpy exponential random generator. Implements the
|
|
181
175
|
IGeneratorRandom interface to allow for interchangeability with other random
|
|
182
176
|
number generators.
|
|
@@ -186,9 +180,7 @@ class GeneratorExponential(IGeneratorRandom):
|
|
|
186
180
|
def __init__(self,
|
|
187
181
|
scale: float = 1.0,
|
|
188
182
|
seed: int | None = None) -> None:
|
|
189
|
-
"""
|
|
190
|
-
an optional seed for the random generator to allow for reproducibility.
|
|
191
|
-
|
|
183
|
+
"""
|
|
192
184
|
Parameters
|
|
193
185
|
----------
|
|
194
186
|
scale : float, optional
|
|
@@ -218,7 +210,7 @@ class GeneratorExponential(IGeneratorRandom):
|
|
|
218
210
|
size = shape)
|
|
219
211
|
|
|
220
212
|
|
|
221
|
-
class
|
|
213
|
+
class GenChiSquare(IGenRandom):
|
|
222
214
|
"""Class wrapping the numpy chi square random generator. Implements the
|
|
223
215
|
IGeneratorRandom interface to allow for interchangeability with other random
|
|
224
216
|
number generators.
|
|
@@ -228,9 +220,7 @@ class GeneratorChiSquare(IGeneratorRandom):
|
|
|
228
220
|
def __init__(self,
|
|
229
221
|
dofs: float,
|
|
230
222
|
seed: int | None = None) -> None:
|
|
231
|
-
"""
|
|
232
|
-
an optional seed for the random generator to allow for reproducibility.
|
|
233
|
-
|
|
223
|
+
"""
|
|
234
224
|
Parameters
|
|
235
225
|
----------
|
|
236
226
|
dofs : float
|
|
@@ -260,7 +250,7 @@ class GeneratorChiSquare(IGeneratorRandom):
|
|
|
260
250
|
size = shape)
|
|
261
251
|
|
|
262
252
|
|
|
263
|
-
class
|
|
253
|
+
class GenDirichlet(IGenRandom):
|
|
264
254
|
"""Class wrapping the numpy dirichlet random generator. Implements the
|
|
265
255
|
IGeneratorRandom interface to allow for interchangeability with other random
|
|
266
256
|
number generators.
|
|
@@ -270,9 +260,7 @@ class GeneratorDirichlet(IGeneratorRandom):
|
|
|
270
260
|
def __init__(self,
|
|
271
261
|
alpha: float,
|
|
272
262
|
seed: int | None = None) -> None:
|
|
273
|
-
"""
|
|
274
|
-
an optional seed for the random generator to allow for reproducibility.
|
|
275
|
-
|
|
263
|
+
"""
|
|
276
264
|
Parameters
|
|
277
265
|
----------
|
|
278
266
|
alpha : float
|
|
@@ -300,7 +288,7 @@ class GeneratorDirichlet(IGeneratorRandom):
|
|
|
300
288
|
return self._rng.dirichlet(alpha = self._alpha, size = shape)
|
|
301
289
|
|
|
302
290
|
|
|
303
|
-
class
|
|
291
|
+
class GenF(IGenRandom):
|
|
304
292
|
"""Class wrapping the numpy F distribution random generator. Implements the
|
|
305
293
|
IGeneratorRandom interface to allow for interchangeability with other random
|
|
306
294
|
number generators.
|
|
@@ -310,9 +298,7 @@ class GeneratorF(IGeneratorRandom):
|
|
|
310
298
|
def __init__(self,
|
|
311
299
|
dofs: float,
|
|
312
300
|
seed: int | None = None) -> None:
|
|
313
|
-
"""
|
|
314
|
-
an optional seed for the random generator to allow for reproducibility.
|
|
315
|
-
|
|
301
|
+
"""
|
|
316
302
|
Parameters
|
|
317
303
|
----------
|
|
318
304
|
dofs : float
|
|
@@ -341,7 +327,7 @@ class GeneratorF(IGeneratorRandom):
|
|
|
341
327
|
return self._rng.f(dfnum = self._dofs, size = shape)
|
|
342
328
|
|
|
343
329
|
|
|
344
|
-
class
|
|
330
|
+
class GenGamma(IGenRandom):
|
|
345
331
|
"""Class wrapping the numpy gamma random generator. Implements the
|
|
346
332
|
IGeneratorRandom interface to allow for interchangeability with other random
|
|
347
333
|
number generators.
|
|
@@ -352,9 +338,7 @@ class GeneratorGamma(IGeneratorRandom):
|
|
|
352
338
|
shape: float,
|
|
353
339
|
scale: float = 1.0,
|
|
354
340
|
seed: int | None = None) -> None:
|
|
355
|
-
"""
|
|
356
|
-
an optional seed for the random generator to allow for reproducibility.
|
|
357
|
-
|
|
341
|
+
"""
|
|
358
342
|
Parameters
|
|
359
343
|
----------
|
|
360
344
|
shape : float
|
|
@@ -387,7 +371,7 @@ class GeneratorGamma(IGeneratorRandom):
|
|
|
387
371
|
size = shape)
|
|
388
372
|
|
|
389
373
|
|
|
390
|
-
class
|
|
374
|
+
class GenStandardT(IGenRandom):
|
|
391
375
|
"""Class wrapping the numpy t distribution random generator. Implements the
|
|
392
376
|
IGeneratorRandom interface to allow for interchangeability with other random
|
|
393
377
|
number generators.
|
|
@@ -397,9 +381,7 @@ class GeneratorStandardT(IGeneratorRandom):
|
|
|
397
381
|
def __init__(self,
|
|
398
382
|
dofs: float,
|
|
399
383
|
seed: int | None = None) -> None:
|
|
400
|
-
"""
|
|
401
|
-
an optional seed for the random generator to allow for reproducibility.
|
|
402
|
-
|
|
384
|
+
"""
|
|
403
385
|
Parameters
|
|
404
386
|
----------
|
|
405
387
|
dofs : float
|
|
@@ -429,7 +411,7 @@ class GeneratorStandardT(IGeneratorRandom):
|
|
|
429
411
|
size = shape)
|
|
430
412
|
|
|
431
413
|
|
|
432
|
-
class
|
|
414
|
+
class GenBeta(IGenRandom):
|
|
433
415
|
"""Class wrapping the numpy beta distribution random generator. Implements
|
|
434
416
|
the IGeneratorRandom interface to allow for interchangeability with other
|
|
435
417
|
random number generators.
|
|
@@ -440,9 +422,7 @@ class GeneratorBeta(IGeneratorRandom):
|
|
|
440
422
|
a: float,
|
|
441
423
|
b: float,
|
|
442
424
|
seed: int | None = None) -> None:
|
|
443
|
-
"""
|
|
444
|
-
an optional seed for the random generator to allow for reproducibility.
|
|
445
|
-
|
|
425
|
+
"""
|
|
446
426
|
Parameters
|
|
447
427
|
----------
|
|
448
428
|
a : float
|
|
@@ -475,7 +455,7 @@ class GeneratorBeta(IGeneratorRandom):
|
|
|
475
455
|
size = shape)
|
|
476
456
|
|
|
477
457
|
|
|
478
|
-
class
|
|
458
|
+
class GenTriangular(IGenRandom):
|
|
479
459
|
"""Class wrapping the numpy triangular random generator. Implements the
|
|
480
460
|
IGeneratorRandom interface to allow for interchangeability with other random
|
|
481
461
|
number generators.
|
|
@@ -487,9 +467,7 @@ class GeneratorTriangular(IGeneratorRandom):
|
|
|
487
467
|
mode: float = 0.0,
|
|
488
468
|
right: float = 1.0,
|
|
489
469
|
seed: int | None = None) -> None:
|
|
490
|
-
"""
|
|
491
|
-
an optional seed for the random generator to allow for reproducibility.
|
|
492
|
-
|
|
470
|
+
"""
|
|
493
471
|
Parameters
|
|
494
472
|
----------
|
|
495
473
|
left : float, optional
|
pyvale/imagedef2d.py
CHANGED
|
@@ -1,8 +1,12 @@
|
|
|
1
|
-
#
|
|
1
|
+
# ==============================================================================
|
|
2
2
|
# pyvale: the python validation engine
|
|
3
3
|
# License: MIT
|
|
4
4
|
# Copyright (C) 2025 The Computer Aided Validation Team
|
|
5
|
-
#
|
|
5
|
+
# ==============================================================================
|
|
6
|
+
|
|
7
|
+
"""
|
|
8
|
+
NOTE: This module is a feature under developement.
|
|
9
|
+
"""
|
|
6
10
|
|
|
7
11
|
import time
|
|
8
12
|
import warnings
|
pyvale/integratorfactory.py
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
#
|
|
1
|
+
# ==============================================================================
|
|
2
2
|
# pyvale: the python validation engine
|
|
3
3
|
# License: MIT
|
|
4
4
|
# Copyright (C) 2025 The Computer Aided Validation Team
|
|
5
|
-
#
|
|
5
|
+
# ==============================================================================
|
|
6
6
|
|
|
7
7
|
import numpy as np
|
|
8
8
|
from pyvale.field import IField
|