pyvale 2025.4.0__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.

Files changed (157) hide show
  1. pyvale/__init__.py +75 -0
  2. pyvale/core/__init__.py +7 -0
  3. pyvale/core/analyticmeshgen.py +59 -0
  4. pyvale/core/analyticsimdatafactory.py +63 -0
  5. pyvale/core/analyticsimdatagenerator.py +160 -0
  6. pyvale/core/camera.py +146 -0
  7. pyvale/core/cameradata.py +64 -0
  8. pyvale/core/cameradata2d.py +82 -0
  9. pyvale/core/cameratools.py +328 -0
  10. pyvale/core/cython/rastercyth.c +32267 -0
  11. pyvale/core/cython/rastercyth.py +636 -0
  12. pyvale/core/dataset.py +250 -0
  13. pyvale/core/errorcalculator.py +112 -0
  14. pyvale/core/errordriftcalc.py +146 -0
  15. pyvale/core/errorintegrator.py +339 -0
  16. pyvale/core/errorrand.py +614 -0
  17. pyvale/core/errorsysdep.py +331 -0
  18. pyvale/core/errorsysfield.py +407 -0
  19. pyvale/core/errorsysindep.py +905 -0
  20. pyvale/core/experimentsimulator.py +99 -0
  21. pyvale/core/field.py +136 -0
  22. pyvale/core/fieldconverter.py +154 -0
  23. pyvale/core/fieldsampler.py +112 -0
  24. pyvale/core/fieldscalar.py +167 -0
  25. pyvale/core/fieldtensor.py +221 -0
  26. pyvale/core/fieldtransform.py +384 -0
  27. pyvale/core/fieldvector.py +215 -0
  28. pyvale/core/generatorsrandom.py +528 -0
  29. pyvale/core/imagedef2d.py +566 -0
  30. pyvale/core/integratorfactory.py +241 -0
  31. pyvale/core/integratorquadrature.py +192 -0
  32. pyvale/core/integratorrectangle.py +88 -0
  33. pyvale/core/integratorspatial.py +90 -0
  34. pyvale/core/integratortype.py +44 -0
  35. pyvale/core/optimcheckfuncs.py +153 -0
  36. pyvale/core/raster.py +31 -0
  37. pyvale/core/rastercy.py +76 -0
  38. pyvale/core/rasternp.py +604 -0
  39. pyvale/core/rendermesh.py +156 -0
  40. pyvale/core/sensorarray.py +179 -0
  41. pyvale/core/sensorarrayfactory.py +210 -0
  42. pyvale/core/sensorarraypoint.py +280 -0
  43. pyvale/core/sensordata.py +72 -0
  44. pyvale/core/sensordescriptor.py +101 -0
  45. pyvale/core/sensortools.py +143 -0
  46. pyvale/core/visualexpplotter.py +151 -0
  47. pyvale/core/visualimagedef.py +71 -0
  48. pyvale/core/visualimages.py +75 -0
  49. pyvale/core/visualopts.py +180 -0
  50. pyvale/core/visualsimanimator.py +83 -0
  51. pyvale/core/visualsimplotter.py +182 -0
  52. pyvale/core/visualtools.py +81 -0
  53. pyvale/core/visualtraceplotter.py +256 -0
  54. pyvale/data/__init__.py +7 -0
  55. pyvale/data/case13_out.e +0 -0
  56. pyvale/data/case16_out.e +0 -0
  57. pyvale/data/case17_out.e +0 -0
  58. pyvale/data/case18_1_out.e +0 -0
  59. pyvale/data/case18_2_out.e +0 -0
  60. pyvale/data/case18_3_out.e +0 -0
  61. pyvale/data/case25_out.e +0 -0
  62. pyvale/data/case26_out.e +0 -0
  63. pyvale/data/optspeckle_2464x2056px_spec5px_8bit_gblur1px.tiff +0 -0
  64. pyvale/examples/__init__.py +7 -0
  65. pyvale/examples/analyticdatagen/__init__.py +7 -0
  66. pyvale/examples/analyticdatagen/ex1_1_scalarvisualisation.py +38 -0
  67. pyvale/examples/analyticdatagen/ex1_2_scalarcasebuild.py +46 -0
  68. pyvale/examples/analyticdatagen/ex2_1_analyticsensors.py +83 -0
  69. pyvale/examples/ex1_1_thermal2d.py +89 -0
  70. pyvale/examples/ex1_2_thermal2d.py +111 -0
  71. pyvale/examples/ex1_3_thermal2d.py +113 -0
  72. pyvale/examples/ex1_4_thermal2d.py +89 -0
  73. pyvale/examples/ex1_5_thermal2d.py +105 -0
  74. pyvale/examples/ex2_1_thermal3d .py +87 -0
  75. pyvale/examples/ex2_2_thermal3d.py +51 -0
  76. pyvale/examples/ex2_3_thermal3d.py +109 -0
  77. pyvale/examples/ex3_1_displacement2d.py +47 -0
  78. pyvale/examples/ex3_2_displacement2d.py +79 -0
  79. pyvale/examples/ex3_3_displacement2d.py +104 -0
  80. pyvale/examples/ex3_4_displacement2d.py +105 -0
  81. pyvale/examples/ex4_1_strain2d.py +57 -0
  82. pyvale/examples/ex4_2_strain2d.py +79 -0
  83. pyvale/examples/ex4_3_strain2d.py +100 -0
  84. pyvale/examples/ex5_1_multiphysics2d.py +78 -0
  85. pyvale/examples/ex6_1_multiphysics2d_expsim.py +118 -0
  86. pyvale/examples/ex6_2_multiphysics3d_expsim.py +158 -0
  87. pyvale/examples/features/__init__.py +7 -0
  88. pyvale/examples/features/ex_animation_tools_3dmonoblock.py +83 -0
  89. pyvale/examples/features/ex_area_avg.py +89 -0
  90. pyvale/examples/features/ex_calibration_error.py +108 -0
  91. pyvale/examples/features/ex_chain_field_errs.py +141 -0
  92. pyvale/examples/features/ex_field_errs.py +78 -0
  93. pyvale/examples/features/ex_sensor_single_angle_batch.py +110 -0
  94. pyvale/examples/imagedef2d/ex_imagedef2d_todisk.py +86 -0
  95. pyvale/examples/rasterisation/ex_rastenp.py +154 -0
  96. pyvale/examples/rasterisation/ex_rastercyth_oneframe.py +220 -0
  97. pyvale/examples/rasterisation/ex_rastercyth_static_cypara.py +194 -0
  98. pyvale/examples/rasterisation/ex_rastercyth_static_pypara.py +193 -0
  99. pyvale/simcases/case00_HEX20.i +242 -0
  100. pyvale/simcases/case00_HEX27.i +242 -0
  101. pyvale/simcases/case00_TET10.i +242 -0
  102. pyvale/simcases/case00_TET14.i +242 -0
  103. pyvale/simcases/case01.i +101 -0
  104. pyvale/simcases/case02.i +156 -0
  105. pyvale/simcases/case03.i +136 -0
  106. pyvale/simcases/case04.i +181 -0
  107. pyvale/simcases/case05.i +234 -0
  108. pyvale/simcases/case06.i +305 -0
  109. pyvale/simcases/case07.geo +135 -0
  110. pyvale/simcases/case07.i +87 -0
  111. pyvale/simcases/case08.geo +144 -0
  112. pyvale/simcases/case08.i +153 -0
  113. pyvale/simcases/case09.geo +204 -0
  114. pyvale/simcases/case09.i +87 -0
  115. pyvale/simcases/case10.geo +204 -0
  116. pyvale/simcases/case10.i +257 -0
  117. pyvale/simcases/case11.geo +337 -0
  118. pyvale/simcases/case11.i +147 -0
  119. pyvale/simcases/case12.geo +388 -0
  120. pyvale/simcases/case12.i +329 -0
  121. pyvale/simcases/case13.i +140 -0
  122. pyvale/simcases/case14.i +159 -0
  123. pyvale/simcases/case15.geo +337 -0
  124. pyvale/simcases/case15.i +150 -0
  125. pyvale/simcases/case16.geo +391 -0
  126. pyvale/simcases/case16.i +357 -0
  127. pyvale/simcases/case17.geo +135 -0
  128. pyvale/simcases/case17.i +144 -0
  129. pyvale/simcases/case18.i +254 -0
  130. pyvale/simcases/case18_1.i +254 -0
  131. pyvale/simcases/case18_2.i +254 -0
  132. pyvale/simcases/case18_3.i +254 -0
  133. pyvale/simcases/case19.geo +252 -0
  134. pyvale/simcases/case19.i +99 -0
  135. pyvale/simcases/case20.geo +252 -0
  136. pyvale/simcases/case20.i +250 -0
  137. pyvale/simcases/case21.geo +74 -0
  138. pyvale/simcases/case21.i +155 -0
  139. pyvale/simcases/case22.geo +82 -0
  140. pyvale/simcases/case22.i +140 -0
  141. pyvale/simcases/case23.geo +164 -0
  142. pyvale/simcases/case23.i +140 -0
  143. pyvale/simcases/case24.geo +79 -0
  144. pyvale/simcases/case24.i +123 -0
  145. pyvale/simcases/case25.geo +82 -0
  146. pyvale/simcases/case25.i +140 -0
  147. pyvale/simcases/case26.geo +166 -0
  148. pyvale/simcases/case26.i +140 -0
  149. pyvale/simcases/run_1case.py +61 -0
  150. pyvale/simcases/run_all_cases.py +69 -0
  151. pyvale/simcases/run_build_case.py +64 -0
  152. pyvale/simcases/run_example_cases.py +69 -0
  153. pyvale-2025.4.0.dist-info/METADATA +140 -0
  154. pyvale-2025.4.0.dist-info/RECORD +157 -0
  155. pyvale-2025.4.0.dist-info/WHEEL +5 -0
  156. pyvale-2025.4.0.dist-info/licenses/LICENSE +21 -0
  157. pyvale-2025.4.0.dist-info/top_level.txt +1 -0
@@ -0,0 +1,331 @@
1
+ """
2
+ ================================================================================
3
+ pyvale: the python validation engine
4
+ License: MIT
5
+ Copyright (C) 2025 The Computer Aided Validation Team
6
+ ================================================================================
7
+ """
8
+ import enum
9
+ from typing import Callable
10
+ import numpy as np
11
+ from pyvale.core.sensordata import SensorData
12
+ from pyvale.core.errorcalculator import (IErrCalculator,
13
+ EErrType,
14
+ EErrDependence)
15
+
16
+
17
+ class ERoundMethod(enum.Enum):
18
+ """Enumeration used to specify the method for rounding floats to integers.
19
+ """
20
+ ROUND = enum.auto()
21
+ FLOOR = enum.auto()
22
+ CEIL = enum.auto()
23
+
24
+
25
+ def _select_round_method(method: ERoundMethod) -> Callable:
26
+ """Helper function for selecting the rounding method based on the user
27
+ specified enumeration. Returns a numpy function for rounding.
28
+
29
+ Parameters
30
+ ----------
31
+ method : ERoundMethod
32
+ Enumeration specifying the rounding method.
33
+
34
+ Returns
35
+ -------
36
+ Callable
37
+ numpy rounding method as np.floor, np.ceil or np.round.
38
+ """
39
+ if method == ERoundMethod.FLOOR:
40
+ return np.floor
41
+ if method == ERoundMethod.CEIL:
42
+ return np.ceil
43
+ return np.round
44
+
45
+
46
+ class ErrSysRoundOff(IErrCalculator):
47
+ """Systematic error calculator for round off error. The user can specify the
48
+ floor, ceiling or nearest integer method for rounding. The user can also
49
+ specify a base to round to that defaults 1. Implements the `IErrCalculator`
50
+ interface.
51
+ """
52
+ __slots__ = ("_base","_method","_err_dep")
53
+
54
+ def __init__(self,
55
+ method: ERoundMethod = ERoundMethod.ROUND,
56
+ base: float = 1.0,
57
+ err_dep: EErrDependence = EErrDependence.DEPENDENT) -> None:
58
+ """Initialiser for the `ErrSysRoundOff` class.
59
+
60
+ Parameters
61
+ ----------
62
+ method : ERoundMethod, optional
63
+ Enumeration specifying the rounding method, by default
64
+ ERoundMethod.ROUND.
65
+ base : float, optional
66
+ Base to round to, by default 1.0.
67
+ err_dep : EErrDependence, optional
68
+ Error calculation dependence, by default EErrDependence.DEPENDENT.
69
+ """
70
+ self._base = base
71
+ self._method = _select_round_method(method)
72
+ self._err_dep = err_dep
73
+
74
+ def get_error_dep(self) -> EErrDependence:
75
+ """Gets the error dependence state for this error calculator. An
76
+ independent error is calculated based on the input truth values as the
77
+ error basis. A dependent error is calculated based on the accumulated
78
+ sensor reading from all preceeding errors in the chain.
79
+
80
+ Returns
81
+ -------
82
+ EErrDependence
83
+ Enumeration defining INDEPENDENT or DEPENDENT behaviour.
84
+ """
85
+ return self._err_dep
86
+
87
+ def set_error_dep(self, dependence: EErrDependence) -> None:
88
+ """Sets the error dependence state for this error calculator. An
89
+ independent error is calculated based on the input truth values as the
90
+ error basis. A dependent error is calculated based on the accumulated
91
+ sensor reading from all preceeding errors in the chain.
92
+
93
+ Parameters
94
+ ----------
95
+ dependence : EErrDependence
96
+ Enumeration defining INDEPENDENT or DEPENDENT behaviour.
97
+ """
98
+ self._err_dep = dependence
99
+
100
+ def get_error_type(self) -> EErrType:
101
+ """Gets the error type.
102
+
103
+ Returns
104
+ -------
105
+ EErrType
106
+ Enumeration definining RANDOM or SYSTEMATIC error types.
107
+ """
108
+ return EErrType.SYSTEMATIC
109
+
110
+ def calc_errs(self,
111
+ err_basis: np.ndarray,
112
+ sens_data: SensorData,
113
+ ) -> tuple[np.ndarray, SensorData]:
114
+ """Calculates the error array based on the size of the input.
115
+
116
+ Parameters
117
+ ----------
118
+ err_basis : np.ndarray
119
+ Array of values with the same dimensions as the sensor measurement
120
+ matrix.
121
+ sens_data : SensorData
122
+ The accumulated sensor state data for all errors prior to this one.
123
+
124
+ Returns
125
+ -------
126
+ tuple[np.ndarray, SensorData]
127
+ Tuple containing the calculated error array and pass through of the
128
+ sensor data object as it is not modified by this class. The returned
129
+ error array has the same shape as the input error basis.
130
+ """
131
+ rounded_measurements = self._base*self._method(err_basis/self._base)
132
+
133
+ return (rounded_measurements - err_basis,sens_data)
134
+
135
+
136
+ class ErrSysDigitisation(IErrCalculator):
137
+ """Systematic error calculator for digitisation error base on a user
138
+ specified number of bits per physical unit and rounding method. Implements
139
+ the `IErrCalculator` interface.
140
+ """
141
+ __slots__ = ("_units_per_bit","_method","_err_dep")
142
+
143
+ def __init__(self,
144
+ bits_per_unit: float,
145
+ method: ERoundMethod = ERoundMethod.ROUND,
146
+ err_dep: EErrDependence = EErrDependence.DEPENDENT) -> None:
147
+ """Initialiser for the `ErrSysDigitisation` class.
148
+
149
+ Parameters
150
+ ----------
151
+ bits_per_unit : float
152
+ The number of bits per physical unit used to determine the
153
+ digitisation error.
154
+ method : ERoundMethod, optional
155
+ User specified rounding method, by default ERoundMethod.ROUND.
156
+ err_dep : EErrDependence, optional
157
+ Error calculation dependence, by default EErrDependence.DEPENDENT.
158
+ """
159
+ self._units_per_bit = 1/float(bits_per_unit)
160
+ self._method = _select_round_method(method)
161
+ self._err_dep = err_dep
162
+
163
+ def get_error_dep(self) -> EErrDependence:
164
+ """Gets the error dependence state for this error calculator. An
165
+ independent error is calculated based on the input truth values as the
166
+ error basis. A dependent error is calculated based on the accumulated
167
+ sensor reading from all preceeding errors in the chain.
168
+
169
+ Returns
170
+ -------
171
+ EErrDependence
172
+ Enumeration defining INDEPENDENT or DEPENDENT behaviour.
173
+ """
174
+ return self._err_dep
175
+
176
+ def set_error_dep(self, dependence: EErrDependence) -> None:
177
+ """Sets the error dependence state for this error calculator. An
178
+ independent error is calculated based on the input truth values as the
179
+ error basis. A dependent error is calculated based on the accumulated
180
+ sensor reading from all preceeding errors in the chain.
181
+
182
+ Parameters
183
+ ----------
184
+ dependence : EErrDependence
185
+ Enumeration defining INDEPENDENT or DEPENDENT behaviour.
186
+ """
187
+ self._err_dep = dependence
188
+
189
+ def get_error_type(self) -> EErrType:
190
+ """Gets the error type.
191
+
192
+ Returns
193
+ -------
194
+ EErrType
195
+ Enumeration definining RANDOM or SYSTEMATIC error types.
196
+ """
197
+ return EErrType.SYSTEMATIC
198
+
199
+ def calc_errs(self,
200
+ err_basis: np.ndarray,
201
+ sens_data: SensorData,
202
+ ) -> tuple[np.ndarray, SensorData]:
203
+ """Calculates the error array based on the size of the input.
204
+
205
+ Parameters
206
+ ----------
207
+ err_basis : np.ndarray
208
+ Array of values with the same dimensions as the sensor measurement
209
+ matrix.
210
+ sens_data : SensorData
211
+ The accumulated sensor state data for all errors prior to this one.
212
+
213
+ Returns
214
+ -------
215
+ tuple[np.ndarray, SensorData]
216
+ Tuple containing the calculated error array and pass through of the
217
+ sensor data object as it is not modified by this class. The returned
218
+ error array has the same shape as the input error basis.
219
+ """
220
+ rounded_measurements = self._units_per_bit*self._method(
221
+ err_basis/self._units_per_bit)
222
+
223
+ return (rounded_measurements - err_basis,sens_data)
224
+
225
+
226
+ class ErrSysSaturation(IErrCalculator):
227
+ """Systematic error calculator for saturation error base on user specified
228
+ minimum and maximum measurement values. Implements the `IErrCalculator`
229
+ interface.
230
+ """
231
+ __slots__ = ("_min","_max","_err_dep")
232
+
233
+ def __init__(self,
234
+ meas_min: float,
235
+ meas_max: float) -> None:
236
+ """Initialiser for the `ErrSysSaturation` class.
237
+
238
+ NOTE: For this error to function as expected and clamp the measurement
239
+ within the specified range it must be placed last in the error chain and
240
+ the behaviour must be set to: EErrDependence.DEPENDENT.
241
+
242
+ Parameters
243
+ ----------
244
+ meas_min : float
245
+ Minimum value to saturate the measurement to.
246
+ meas_max : float
247
+ Maximum value to saturate the measurement to.
248
+
249
+ Raises
250
+ ------
251
+ ValueError
252
+ Raised if the user specified minimum measurement is greater than the
253
+ maximum measurement.
254
+ """
255
+ if meas_min > meas_max:
256
+ raise ValueError("Minimum must be smaller than maximum for "+
257
+ "systematic error saturation")
258
+
259
+ self._min = meas_min
260
+ self._max = meas_max
261
+ self._err_dep = EErrDependence.DEPENDENT
262
+
263
+ def get_error_dep(self) -> EErrDependence:
264
+ """Gets the error dependence state for this error calculator. An
265
+ independent error is calculated based on the input truth values as the
266
+ error basis. A dependent error is calculated based on the accumulated
267
+ sensor reading from all preceeding errors in the chain.
268
+
269
+ Returns
270
+ -------
271
+ EErrDependence
272
+ Enumeration defining INDEPENDENT or DEPENDENT behaviour.
273
+ """
274
+ return self._err_dep
275
+
276
+ def set_error_dep(self, dependence: EErrDependence) -> None:
277
+ """Sets the error dependence state for this error calculator. An
278
+ independent error is calculated based on the input truth values as the
279
+ error basis. A dependent error is calculated based on the accumulated
280
+ sensor reading from all preceeding errors in the chain.
281
+
282
+ NOTE: For this error to function as expected the error dependence must
283
+ be set to `EErrDependence.DEPENDENT`.
284
+
285
+ Parameters
286
+ ----------
287
+ dependence : EErrDependence
288
+ Enumeration defining INDEPENDENT or DEPENDENT behaviour.
289
+ """
290
+ self._err_dep = dependence
291
+
292
+ def get_error_type(self) -> EErrType:
293
+ """Gets the error type.
294
+
295
+ Returns
296
+ -------
297
+ EErrType
298
+ Enumeration definining RANDOM or SYSTEMATIC error types.
299
+ """
300
+ return EErrType.SYSTEMATIC
301
+
302
+ def calc_errs(self,
303
+ err_basis: np.ndarray,
304
+ sens_data: SensorData,
305
+ ) -> tuple[np.ndarray, SensorData]:
306
+ """Calculates the error array based on the size of the input.
307
+
308
+ Parameters
309
+ ----------
310
+ err_basis : np.ndarray
311
+ Array of values with the same dimensions as the sensor measurement
312
+ matrix.
313
+ sens_data : SensorData
314
+ The accumulated sensor state data for all errors prior to this one.
315
+
316
+ Returns
317
+ -------
318
+ tuple[np.ndarray, SensorData]
319
+ Tuple containing the calculated error array and pass through of the
320
+ sensor data object as it is not modified by this class. The returned
321
+ error array has the same shape as the input error basis.
322
+ """
323
+ saturated = np.copy(err_basis)
324
+ saturated[saturated > self._max] = self._max
325
+ saturated[saturated < self._min] = self._min
326
+
327
+ return (saturated - err_basis,sens_data)
328
+
329
+
330
+
331
+