pyvale 2025.5.3__cp311-cp311-musllinux_1_2_i686.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 +89 -0
- pyvale/analyticmeshgen.py +102 -0
- pyvale/analyticsimdatafactory.py +91 -0
- pyvale/analyticsimdatagenerator.py +323 -0
- 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 +146 -0
- pyvale/cameradata.py +69 -0
- pyvale/cameradata2d.py +84 -0
- pyvale/camerastereo.py +217 -0
- pyvale/cameratools.py +522 -0
- pyvale/cython/rastercyth.c +32211 -0
- pyvale/cython/rastercyth.cpython-311-i386-linux-musl.so +0 -0
- pyvale/cython/rastercyth.py +640 -0
- pyvale/data/__init__.py +5 -0
- pyvale/data/cal_target.tiff +0 -0
- pyvale/data/case00_HEX20_out.e +0 -0
- pyvale/data/case00_HEX27_out.e +0 -0
- pyvale/data/case00_HEX8_out.e +0 -0
- pyvale/data/case00_TET10_out.e +0 -0
- pyvale/data/case00_TET14_out.e +0 -0
- pyvale/data/case00_TET4_out.e +0 -0
- pyvale/data/case13_out.e +0 -0
- pyvale/data/case16_out.e +0 -0
- pyvale/data/case17_out.e +0 -0
- pyvale/data/case18_1_out.e +0 -0
- pyvale/data/case18_2_out.e +0 -0
- pyvale/data/case18_3_out.e +0 -0
- pyvale/data/case25_out.e +0 -0
- pyvale/data/case26_out.e +0 -0
- pyvale/data/optspeckle_2464x2056px_spec5px_8bit_gblur1px.tiff +0 -0
- pyvale/dataset.py +325 -0
- pyvale/errorcalculator.py +109 -0
- pyvale/errordriftcalc.py +146 -0
- pyvale/errorintegrator.py +336 -0
- pyvale/errorrand.py +607 -0
- pyvale/errorsyscalib.py +134 -0
- pyvale/errorsysdep.py +327 -0
- pyvale/errorsysfield.py +414 -0
- pyvale/errorsysindep.py +808 -0
- pyvale/examples/__init__.py +5 -0
- 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/genanalyticdata/ex1_1_scalarvisualisation.py +35 -0
- pyvale/examples/genanalyticdata/ex1_2_scalarcasebuild.py +43 -0
- pyvale/examples/genanalyticdata/ex2_1_analyticsensors.py +80 -0
- pyvale/examples/imagedef2d/ex_imagedef2d_todisk.py +79 -0
- 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/renderrasterisation/ex_rastenp.py +153 -0
- pyvale/examples/renderrasterisation/ex_rastercyth_oneframe.py +218 -0
- pyvale/examples/renderrasterisation/ex_rastercyth_static_cypara.py +187 -0
- pyvale/examples/renderrasterisation/ex_rastercyth_static_pypara.py +190 -0
- pyvale/examples/visualisation/ex1_1_plot_traces.py +102 -0
- pyvale/examples/visualisation/ex2_1_animate_sim.py +89 -0
- pyvale/experimentsimulator.py +175 -0
- pyvale/field.py +128 -0
- pyvale/fieldconverter.py +351 -0
- pyvale/fieldsampler.py +111 -0
- pyvale/fieldscalar.py +166 -0
- pyvale/fieldtensor.py +218 -0
- pyvale/fieldtransform.py +388 -0
- pyvale/fieldvector.py +213 -0
- pyvale/generatorsrandom.py +505 -0
- pyvale/imagedef2d.py +569 -0
- pyvale/integratorfactory.py +240 -0
- pyvale/integratorquadrature.py +217 -0
- pyvale/integratorrectangle.py +165 -0
- pyvale/integratorspatial.py +89 -0
- pyvale/integratortype.py +43 -0
- pyvale/output.py +17 -0
- pyvale/pyvaleexceptions.py +11 -0
- pyvale/raster.py +31 -0
- pyvale/rastercy.py +77 -0
- pyvale/rasternp.py +603 -0
- pyvale/rendermesh.py +147 -0
- pyvale/sensorarray.py +178 -0
- pyvale/sensorarrayfactory.py +196 -0
- pyvale/sensorarraypoint.py +278 -0
- pyvale/sensordata.py +71 -0
- pyvale/sensordescriptor.py +213 -0
- pyvale/sensortools.py +142 -0
- pyvale/simcases/case00_HEX20.i +242 -0
- pyvale/simcases/case00_HEX27.i +242 -0
- pyvale/simcases/case00_HEX8.i +242 -0
- pyvale/simcases/case00_TET10.i +242 -0
- pyvale/simcases/case00_TET14.i +242 -0
- pyvale/simcases/case00_TET4.i +242 -0
- pyvale/simcases/case01.i +101 -0
- pyvale/simcases/case02.i +156 -0
- pyvale/simcases/case03.i +136 -0
- pyvale/simcases/case04.i +181 -0
- pyvale/simcases/case05.i +234 -0
- pyvale/simcases/case06.i +305 -0
- pyvale/simcases/case07.geo +135 -0
- pyvale/simcases/case07.i +87 -0
- pyvale/simcases/case08.geo +144 -0
- pyvale/simcases/case08.i +153 -0
- pyvale/simcases/case09.geo +204 -0
- pyvale/simcases/case09.i +87 -0
- pyvale/simcases/case10.geo +204 -0
- pyvale/simcases/case10.i +257 -0
- pyvale/simcases/case11.geo +337 -0
- pyvale/simcases/case11.i +147 -0
- pyvale/simcases/case12.geo +388 -0
- pyvale/simcases/case12.i +329 -0
- pyvale/simcases/case13.i +140 -0
- pyvale/simcases/case14.i +159 -0
- pyvale/simcases/case15.geo +337 -0
- pyvale/simcases/case15.i +150 -0
- pyvale/simcases/case16.geo +391 -0
- pyvale/simcases/case16.i +357 -0
- pyvale/simcases/case17.geo +135 -0
- pyvale/simcases/case17.i +144 -0
- pyvale/simcases/case18.i +254 -0
- pyvale/simcases/case18_1.i +254 -0
- pyvale/simcases/case18_2.i +254 -0
- pyvale/simcases/case18_3.i +254 -0
- pyvale/simcases/case19.geo +252 -0
- pyvale/simcases/case19.i +99 -0
- pyvale/simcases/case20.geo +252 -0
- pyvale/simcases/case20.i +250 -0
- pyvale/simcases/case21.geo +74 -0
- pyvale/simcases/case21.i +155 -0
- pyvale/simcases/case22.geo +82 -0
- pyvale/simcases/case22.i +140 -0
- pyvale/simcases/case23.geo +164 -0
- pyvale/simcases/case23.i +140 -0
- pyvale/simcases/case24.geo +79 -0
- pyvale/simcases/case24.i +123 -0
- pyvale/simcases/case25.geo +82 -0
- pyvale/simcases/case25.i +140 -0
- pyvale/simcases/case26.geo +166 -0
- pyvale/simcases/case26.i +140 -0
- pyvale/simcases/run_1case.py +61 -0
- pyvale/simcases/run_all_cases.py +69 -0
- pyvale/simcases/run_build_case.py +64 -0
- pyvale/simcases/run_example_cases.py +69 -0
- pyvale/simtools.py +67 -0
- pyvale/visualexpplotter.py +191 -0
- pyvale/visualimagedef.py +74 -0
- pyvale/visualimages.py +76 -0
- pyvale/visualopts.py +493 -0
- pyvale/visualsimanimator.py +111 -0
- pyvale/visualsimsensors.py +318 -0
- pyvale/visualtools.py +136 -0
- pyvale/visualtraceplotter.py +142 -0
- pyvale-2025.5.3.dist-info/METADATA +144 -0
- pyvale-2025.5.3.dist-info/RECORD +174 -0
- pyvale-2025.5.3.dist-info/WHEEL +5 -0
- pyvale-2025.5.3.dist-info/licenses/LICENSE +21 -0
- pyvale-2025.5.3.dist-info/top_level.txt +1 -0
pyvale/fieldvector.py
ADDED
|
@@ -0,0 +1,213 @@
|
|
|
1
|
+
# ==============================================================================
|
|
2
|
+
# pyvale: the python validation engine
|
|
3
|
+
# License: MIT
|
|
4
|
+
# Copyright (C) 2025 The Computer Aided Validation Team
|
|
5
|
+
# ==============================================================================
|
|
6
|
+
|
|
7
|
+
import numpy as np
|
|
8
|
+
import pyvista as pv
|
|
9
|
+
from scipy.spatial.transform import Rotation
|
|
10
|
+
import mooseherder as mh
|
|
11
|
+
|
|
12
|
+
from pyvale.field import IField
|
|
13
|
+
from pyvale.fieldconverter import simdata_to_pyvista
|
|
14
|
+
from pyvale.fieldsampler import sample_pyvista_grid
|
|
15
|
+
from pyvale.fieldtransform import (transform_vector_2d,
|
|
16
|
+
transform_vector_2d_batch,
|
|
17
|
+
transform_vector_3d,
|
|
18
|
+
transform_vector_3d_batch)
|
|
19
|
+
|
|
20
|
+
class FieldVector(IField):
|
|
21
|
+
"""Class for sampling (interpolating) vector fields from simulations to
|
|
22
|
+
provide sensor values at specified locations and times.
|
|
23
|
+
|
|
24
|
+
Implements the `IField` interface.
|
|
25
|
+
"""
|
|
26
|
+
__slots__ = ("_field_key","_components","_spat_dims","_sim_data",
|
|
27
|
+
"_pyvista_grid","_pyvista_vis")
|
|
28
|
+
|
|
29
|
+
def __init__(self,
|
|
30
|
+
sim_data: mh.SimData,
|
|
31
|
+
field_key: str,
|
|
32
|
+
components: tuple[str,...],
|
|
33
|
+
elem_dims: int) -> None:
|
|
34
|
+
"""
|
|
35
|
+
Parameters
|
|
36
|
+
----------
|
|
37
|
+
sim_data : mh.SimData
|
|
38
|
+
Simulation data object containing the mesh and field to interpolate.
|
|
39
|
+
field_key : str
|
|
40
|
+
String describing the vector field. For example: 'disp'.
|
|
41
|
+
components : tuple[str,...]
|
|
42
|
+
String keys to the field components in the `SimData` object. For
|
|
43
|
+
example ('disp_x','disp_y').
|
|
44
|
+
elem_dims : int
|
|
45
|
+
Number of spatial dimensions (2 or 3) used for identifying element
|
|
46
|
+
types.
|
|
47
|
+
"""
|
|
48
|
+
self._field_key = field_key
|
|
49
|
+
self._components = components
|
|
50
|
+
self._spat_dims = elem_dims
|
|
51
|
+
|
|
52
|
+
self._sim_data = sim_data
|
|
53
|
+
(self._pyvista_grid,self._pyvista_vis) = simdata_to_pyvista(
|
|
54
|
+
self._sim_data,
|
|
55
|
+
self._components,
|
|
56
|
+
self._spat_dims
|
|
57
|
+
)
|
|
58
|
+
|
|
59
|
+
def set_sim_data(self, sim_data: mh.SimData) -> None:
|
|
60
|
+
"""Sets the `SimData` object that will be interpolated to obtain sensor
|
|
61
|
+
values. The purpose of this is to be able to apply the same sensor array
|
|
62
|
+
to an array of different simulations by setting a different `SimData`.
|
|
63
|
+
|
|
64
|
+
Parameters
|
|
65
|
+
----------
|
|
66
|
+
sim_data : mh.SimData
|
|
67
|
+
Mooseherder SimData object. Contains a mesh and a simulated
|
|
68
|
+
physical field.
|
|
69
|
+
"""
|
|
70
|
+
self._sim_data = sim_data
|
|
71
|
+
(self._pyvista_grid,self._pyvista_vis) = simdata_to_pyvista(
|
|
72
|
+
sim_data,
|
|
73
|
+
self._components,
|
|
74
|
+
self._spat_dims
|
|
75
|
+
)
|
|
76
|
+
|
|
77
|
+
def get_sim_data(self) -> mh.SimData:
|
|
78
|
+
"""Gets the simulation data object associated with this field. Used by
|
|
79
|
+
pyvale visualisation tools to display simulation data with simulated
|
|
80
|
+
sensor values.
|
|
81
|
+
|
|
82
|
+
Returns
|
|
83
|
+
-------
|
|
84
|
+
mh.SimData
|
|
85
|
+
Mooseherder SimData object. Contains a mesh and a simulated
|
|
86
|
+
physical field.
|
|
87
|
+
"""
|
|
88
|
+
return self._sim_data
|
|
89
|
+
|
|
90
|
+
def get_time_steps(self) -> np.ndarray:
|
|
91
|
+
"""Gets a 1D array of time steps from the simulation data.
|
|
92
|
+
|
|
93
|
+
Returns
|
|
94
|
+
-------
|
|
95
|
+
np.ndarray
|
|
96
|
+
1D array of simulation time steps. shape=(num_time_steps,)
|
|
97
|
+
"""
|
|
98
|
+
return self._sim_data.time
|
|
99
|
+
|
|
100
|
+
def get_visualiser(self) -> pv.UnstructuredGrid:
|
|
101
|
+
"""Gets a pyvista unstructured grid object for visualisation purposes.
|
|
102
|
+
|
|
103
|
+
Returns
|
|
104
|
+
-------
|
|
105
|
+
pv.UnstructuredGrid
|
|
106
|
+
Pyvista unstructured grid object containing only a mesh without any
|
|
107
|
+
physical field data attached.
|
|
108
|
+
"""
|
|
109
|
+
return self._pyvista_vis
|
|
110
|
+
|
|
111
|
+
def get_all_components(self) -> tuple[str, ...]:
|
|
112
|
+
"""Gets the string keys for the component of the physical field. For
|
|
113
|
+
example: a vector field might have ('disp_x','disp_y','disp_z') in 3D
|
|
114
|
+
and just ('disp_x','disp_y') in 2D.
|
|
115
|
+
|
|
116
|
+
Returns
|
|
117
|
+
-------
|
|
118
|
+
tuple[str,...]
|
|
119
|
+
Tuple containing the string keys for all components of the physical
|
|
120
|
+
field.
|
|
121
|
+
"""
|
|
122
|
+
return self._components
|
|
123
|
+
|
|
124
|
+
def get_component_index(self,comp: str) -> int:
|
|
125
|
+
"""Gets the index for a component of the physical field. Used for
|
|
126
|
+
getting the index of a component in the sensor measurement array.
|
|
127
|
+
|
|
128
|
+
Parameters
|
|
129
|
+
----------
|
|
130
|
+
component : str
|
|
131
|
+
String key for the field component (e.g. 'temperature' or 'disp_x').
|
|
132
|
+
|
|
133
|
+
Returns
|
|
134
|
+
-------
|
|
135
|
+
int
|
|
136
|
+
Index for the selected field component
|
|
137
|
+
"""
|
|
138
|
+
return self._components.index(comp)
|
|
139
|
+
|
|
140
|
+
def sample_field(self,
|
|
141
|
+
points: np.ndarray,
|
|
142
|
+
times: np.ndarray | None = None,
|
|
143
|
+
angles: tuple[Rotation,...] | None = None,
|
|
144
|
+
) -> np.ndarray:
|
|
145
|
+
"""Samples (interpolates) the simulation field at the specified
|
|
146
|
+
positions, times, and angles.
|
|
147
|
+
|
|
148
|
+
Parameters
|
|
149
|
+
----------
|
|
150
|
+
points : np.ndarray
|
|
151
|
+
Spatial points to be sampled with the rows indicating the point
|
|
152
|
+
number of the columns indicating the X,Y and Z coordinates.
|
|
153
|
+
times : np.ndarray | None, optional
|
|
154
|
+
Times to sample the underlying simulation. If None then the
|
|
155
|
+
simulation time steps are used and no temporal interpolation is
|
|
156
|
+
performed, by default None.
|
|
157
|
+
angles : tuple[Rotation,...] | None, optional
|
|
158
|
+
Angles to rotate the sampled values into with rotations specified
|
|
159
|
+
with respect to the simulation world coordinates. If a single
|
|
160
|
+
rotation is specified then all points are assumed to have the same
|
|
161
|
+
angle and are batch processed for speed. If None then no rotation is
|
|
162
|
+
performed, by default None.
|
|
163
|
+
|
|
164
|
+
Returns
|
|
165
|
+
-------
|
|
166
|
+
np.ndarray
|
|
167
|
+
An array of sampled (interpolated) values with the following
|
|
168
|
+
dimensions: shape=(num_points,num_components,num_time_steps).
|
|
169
|
+
"""
|
|
170
|
+
|
|
171
|
+
field_data = sample_pyvista_grid(self._components,
|
|
172
|
+
self._pyvista_grid,
|
|
173
|
+
self._sim_data.time,
|
|
174
|
+
points,
|
|
175
|
+
times)
|
|
176
|
+
|
|
177
|
+
if angles is None:
|
|
178
|
+
return field_data
|
|
179
|
+
|
|
180
|
+
# NOTE:
|
|
181
|
+
# ROTATION= object rotates with coords fixed
|
|
182
|
+
# For Z rotation: sin negative in row 1.
|
|
183
|
+
# TRANSFORMATION= coords rotate with object fixed
|
|
184
|
+
# For Z transformation: sin negative in row 2, transpose scipy mat.
|
|
185
|
+
|
|
186
|
+
# If we only have one angle we assume all sensors have the same angle
|
|
187
|
+
# and we can batch process the rotations
|
|
188
|
+
if len(angles) == 1:
|
|
189
|
+
rmat = angles[0].as_matrix().T
|
|
190
|
+
|
|
191
|
+
#TODO: assumes 2D in the x-y plane
|
|
192
|
+
if self._spat_dims == 2:
|
|
193
|
+
rmat = rmat[:2,:2]
|
|
194
|
+
field_data = transform_vector_2d_batch(rmat,field_data)
|
|
195
|
+
else:
|
|
196
|
+
field_data = transform_vector_3d_batch(rmat,field_data)
|
|
197
|
+
|
|
198
|
+
else: # Need to rotate each sensor using individual rotation = loop :(
|
|
199
|
+
#TODO: assumes 2D in the x-y plane
|
|
200
|
+
if self._spat_dims == 2:
|
|
201
|
+
for ii,rr in enumerate(angles):
|
|
202
|
+
rmat = rr.as_matrix().T
|
|
203
|
+
rmat = rmat[:2,:2]
|
|
204
|
+
field_data[ii,:,:] = transform_vector_2d(rmat,field_data[ii,:,:])
|
|
205
|
+
|
|
206
|
+
else:
|
|
207
|
+
for ii,rr in enumerate(angles):
|
|
208
|
+
rmat = rr.as_matrix().T
|
|
209
|
+
field_data[ii,:,:] = transform_vector_3d(rmat,field_data[ii,:,:])
|
|
210
|
+
|
|
211
|
+
#field_data[ii,:,:] = np.matmul(rmat,field_data[ii,:,:])
|
|
212
|
+
return field_data
|
|
213
|
+
|