pyvale 2025.4.1__py3-none-any.whl → 2025.5.2__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 (126) hide show
  1. pyvale/__init__.py +18 -3
  2. pyvale/analyticmeshgen.py +1 -0
  3. pyvale/analyticsimdatafactory.py +18 -13
  4. pyvale/analyticsimdatagenerator.py +105 -72
  5. pyvale/blendercalibrationdata.py +15 -0
  6. pyvale/blenderlightdata.py +26 -0
  7. pyvale/blendermaterialdata.py +15 -0
  8. pyvale/blenderrenderdata.py +30 -0
  9. pyvale/blenderscene.py +488 -0
  10. pyvale/blendertools.py +420 -0
  11. pyvale/camera.py +6 -5
  12. pyvale/cameradata.py +25 -7
  13. pyvale/cameradata2d.py +6 -4
  14. pyvale/camerastereo.py +217 -0
  15. pyvale/cameratools.py +206 -11
  16. pyvale/cython/rastercyth.py +6 -2
  17. pyvale/data/cal_target.tiff +0 -0
  18. pyvale/dataset.py +73 -14
  19. pyvale/errorcalculator.py +8 -10
  20. pyvale/errordriftcalc.py +10 -9
  21. pyvale/errorintegrator.py +19 -21
  22. pyvale/errorrand.py +33 -39
  23. pyvale/errorsyscalib.py +134 -0
  24. pyvale/errorsysdep.py +19 -22
  25. pyvale/errorsysfield.py +49 -41
  26. pyvale/errorsysindep.py +79 -175
  27. pyvale/examples/basics/ex1_1_basicscalars_therm2d.py +131 -0
  28. pyvale/examples/basics/ex1_2_sensormodel_therm2d.py +158 -0
  29. pyvale/examples/basics/ex1_3_customsens_therm3d.py +216 -0
  30. pyvale/examples/basics/ex1_4_basicerrors_therm3d.py +153 -0
  31. pyvale/examples/basics/ex1_5_fielderrs_therm3d.py +168 -0
  32. pyvale/examples/basics/ex1_6_caliberrs_therm2d.py +133 -0
  33. pyvale/examples/basics/ex1_7_spatavg_therm2d.py +123 -0
  34. pyvale/examples/basics/ex2_1_basicvectors_disp2d.py +112 -0
  35. pyvale/examples/basics/ex2_2_vectorsens_disp2d.py +111 -0
  36. pyvale/examples/basics/ex2_3_sensangle_disp2d.py +139 -0
  37. pyvale/examples/basics/ex2_4_chainfielderrs_disp2d.py +196 -0
  38. pyvale/examples/basics/ex2_5_vectorfields3d_disp3d.py +109 -0
  39. pyvale/examples/basics/ex3_1_basictensors_strain2d.py +114 -0
  40. pyvale/examples/basics/ex3_2_tensorsens2d_strain2d.py +111 -0
  41. pyvale/examples/basics/ex3_3_tensorsens3d_strain3d.py +182 -0
  42. pyvale/examples/basics/ex4_1_expsim2d_thermmech2d.py +171 -0
  43. pyvale/examples/basics/ex4_2_expsim3d_thermmech3d.py +252 -0
  44. pyvale/examples/{analyticdatagen → genanalyticdata}/ex1_1_scalarvisualisation.py +6 -9
  45. pyvale/examples/{analyticdatagen → genanalyticdata}/ex1_2_scalarcasebuild.py +8 -11
  46. pyvale/examples/{analyticdatagen → genanalyticdata}/ex2_1_analyticsensors.py +9 -12
  47. pyvale/examples/imagedef2d/ex_imagedef2d_todisk.py +8 -15
  48. pyvale/examples/renderblender/ex1_1_blenderscene.py +121 -0
  49. pyvale/examples/renderblender/ex1_2_blenderdeformed.py +119 -0
  50. pyvale/examples/renderblender/ex2_1_stereoscene.py +128 -0
  51. pyvale/examples/renderblender/ex2_2_stereodeformed.py +131 -0
  52. pyvale/examples/renderblender/ex3_1_blendercalibration.py +120 -0
  53. pyvale/examples/{rasterisation → renderrasterisation}/ex_rastenp.py +3 -2
  54. pyvale/examples/{rasterisation → renderrasterisation}/ex_rastercyth_oneframe.py +2 -2
  55. pyvale/examples/{rasterisation → renderrasterisation}/ex_rastercyth_static_cypara.py +3 -8
  56. pyvale/examples/{rasterisation → renderrasterisation}/ex_rastercyth_static_pypara.py +6 -7
  57. pyvale/examples/{ex1_4_thermal2d.py → visualisation/ex1_1_plot_traces.py} +32 -16
  58. pyvale/examples/{features/ex_animation_tools_3dmonoblock.py → visualisation/ex2_1_animate_sim.py} +37 -31
  59. pyvale/experimentsimulator.py +107 -30
  60. pyvale/field.py +2 -9
  61. pyvale/fieldconverter.py +98 -22
  62. pyvale/fieldsampler.py +2 -2
  63. pyvale/fieldscalar.py +10 -10
  64. pyvale/fieldtensor.py +15 -17
  65. pyvale/fieldtransform.py +7 -2
  66. pyvale/fieldvector.py +6 -7
  67. pyvale/generatorsrandom.py +25 -47
  68. pyvale/imagedef2d.py +6 -2
  69. pyvale/integratorfactory.py +2 -2
  70. pyvale/integratorquadrature.py +50 -24
  71. pyvale/integratorrectangle.py +85 -7
  72. pyvale/integratorspatial.py +4 -4
  73. pyvale/integratortype.py +3 -3
  74. pyvale/output.py +17 -0
  75. pyvale/pyvaleexceptions.py +11 -0
  76. pyvale/raster.py +6 -5
  77. pyvale/rastercy.py +6 -4
  78. pyvale/rasternp.py +6 -4
  79. pyvale/rendermesh.py +6 -2
  80. pyvale/sensorarray.py +2 -2
  81. pyvale/sensorarrayfactory.py +52 -65
  82. pyvale/sensorarraypoint.py +29 -30
  83. pyvale/sensordata.py +2 -2
  84. pyvale/sensordescriptor.py +138 -25
  85. pyvale/sensortools.py +3 -3
  86. pyvale/simtools.py +67 -0
  87. pyvale/visualexpplotter.py +99 -57
  88. pyvale/visualimagedef.py +11 -7
  89. pyvale/visualimages.py +6 -4
  90. pyvale/visualopts.py +372 -58
  91. pyvale/visualsimanimator.py +42 -13
  92. pyvale/visualsimsensors.py +318 -0
  93. pyvale/visualtools.py +69 -13
  94. pyvale/visualtraceplotter.py +52 -165
  95. {pyvale-2025.4.1.dist-info → pyvale-2025.5.2.dist-info}/METADATA +17 -14
  96. pyvale-2025.5.2.dist-info/RECORD +172 -0
  97. {pyvale-2025.4.1.dist-info → pyvale-2025.5.2.dist-info}/WHEEL +1 -1
  98. pyvale/examples/analyticdatagen/__init__.py +0 -5
  99. pyvale/examples/ex1_1_thermal2d.py +0 -86
  100. pyvale/examples/ex1_2_thermal2d.py +0 -108
  101. pyvale/examples/ex1_3_thermal2d.py +0 -110
  102. pyvale/examples/ex1_5_thermal2d.py +0 -102
  103. pyvale/examples/ex2_1_thermal3d .py +0 -84
  104. pyvale/examples/ex2_2_thermal3d.py +0 -51
  105. pyvale/examples/ex2_3_thermal3d.py +0 -106
  106. pyvale/examples/ex3_1_displacement2d.py +0 -44
  107. pyvale/examples/ex3_2_displacement2d.py +0 -76
  108. pyvale/examples/ex3_3_displacement2d.py +0 -101
  109. pyvale/examples/ex3_4_displacement2d.py +0 -102
  110. pyvale/examples/ex4_1_strain2d.py +0 -54
  111. pyvale/examples/ex4_2_strain2d.py +0 -76
  112. pyvale/examples/ex4_3_strain2d.py +0 -97
  113. pyvale/examples/ex5_1_multiphysics2d.py +0 -75
  114. pyvale/examples/ex6_1_multiphysics2d_expsim.py +0 -115
  115. pyvale/examples/ex6_2_multiphysics3d_expsim.py +0 -160
  116. pyvale/examples/features/__init__.py +0 -5
  117. pyvale/examples/features/ex_area_avg.py +0 -89
  118. pyvale/examples/features/ex_calibration_error.py +0 -108
  119. pyvale/examples/features/ex_chain_field_errs.py +0 -141
  120. pyvale/examples/features/ex_field_errs.py +0 -78
  121. pyvale/examples/features/ex_sensor_single_angle_batch.py +0 -110
  122. pyvale/optimcheckfuncs.py +0 -153
  123. pyvale/visualsimplotter.py +0 -182
  124. pyvale-2025.4.1.dist-info/RECORD +0 -163
  125. {pyvale-2025.4.1.dist-info → pyvale-2025.5.2.dist-info}/licenses/LICENSE +0 -0
  126. {pyvale-2025.4.1.dist-info → pyvale-2025.5.2.dist-info}/top_level.txt +0 -0
@@ -1,101 +0,0 @@
1
- # ================================================================================
2
- # pyvale: the python validation engine
3
- # License: MIT
4
- # Copyright (C) 2025 The Computer Aided Validation Team
5
- # ================================================================================
6
-
7
- from pathlib import Path
8
- import numpy as np
9
- import matplotlib.pyplot as plt
10
- from scipy.spatial.transform import Rotation
11
- import mooseherder as mh
12
- import pyvale as pyv
13
-
14
- def main() -> None:
15
- """pyvale example: displacement sensors on a 2D plate with a hole
16
- ----------------------------------------------------------------------------
17
- - Demonstrates sensor rotation for vector fields
18
- """
19
- data_path = pyv.DataSet.mechanical_2d_path()
20
- sim_data = mh.ExodusReader(data_path).read_all_sim_data()
21
- # Scale to mm to make 3D visualisation scaling easier
22
- sim_data.coords = sim_data.coords*1000.0 # type: ignore
23
-
24
- descriptor = pyv.SensorDescriptorFactory.displacement_descriptor()
25
-
26
- spat_dims = 2
27
- field_key = 'disp'
28
- components = ('disp_x','disp_y')
29
- disp_field = pyv.FieldVector(sim_data,field_key,components,spat_dims)
30
-
31
- n_sens = (2,2,1)
32
- x_lims = (0.0,100.0)
33
- y_lims = (0.0,150.0)
34
- z_lims = (0.0,0.0)
35
- sensor_positions = pyv.create_sensor_pos_array(n_sens,x_lims,y_lims,z_lims)
36
-
37
- use_sim_time = False
38
- if use_sim_time:
39
- sample_times = None
40
- else:
41
- sample_times = np.linspace(0.0,np.max(sim_data.time),50)
42
-
43
- sens_data_norot = pyv.SensorData(positions=sensor_positions,
44
- sample_times=sample_times)
45
-
46
- disp_sens_norot = pyv.SensorArrayPoint(sens_data_norot,
47
- disp_field,
48
- descriptor)
49
-
50
- meas_norot = disp_sens_norot.get_measurements()
51
-
52
- sens_angles = sensor_positions.shape[0] * \
53
- (Rotation.from_euler("zyx", [45, 0, 0], degrees=True),)
54
-
55
- sens_data_rot = pyv.SensorData(positions=sensor_positions,
56
- sample_times=sample_times,
57
- angles=sens_angles)
58
-
59
- disp_sens_rot = pyv.SensorArrayPoint(sens_data_rot,
60
- disp_field,
61
- descriptor)
62
-
63
-
64
- angle_offset = np.zeros_like(sensor_positions)
65
- angle_offset[:,0] = 1.0 # only rotate about z in 2D
66
- angle_error_data = pyv.ErrFieldData(ang_offset_zyx=angle_offset)
67
-
68
- sys_err_rot = pyv.ErrSysField(disp_field,angle_error_data)
69
-
70
- sys_err_int = pyv.ErrIntegrator([sys_err_rot],
71
- sens_data_rot,
72
- disp_sens_rot.get_measurement_shape())
73
- disp_sens_rot.set_error_integrator(sys_err_int)
74
-
75
- meas_rot = disp_sens_rot.get_measurements()
76
-
77
-
78
- print(80*'-')
79
- sens_num = 4
80
- print('The last 5 time steps (measurements) of sensor {sens_num}:')
81
- pyv.print_measurements(disp_sens_rot,
82
- (sens_num-1,sens_num),
83
- (0,1),
84
- (meas_rot.shape[2]-5,meas_rot.shape[2]))
85
- print(80*'-')
86
-
87
- plot_field = 'disp_x'
88
- if plot_field == 'disp_x':
89
- pv_plot = pyv.plot_point_sensors_on_sim(disp_sens_rot,'disp_x')
90
- pv_plot.show(cpos="xy")
91
- elif plot_field == 'disp_y':
92
- pv_plot = pyv.plot_point_sensors_on_sim(disp_sens_rot,'disp_y')
93
- pv_plot.show(cpos="xy")
94
-
95
- pyv.plot_time_traces(disp_sens_norot,plot_field)
96
- pyv.plot_time_traces(disp_sens_rot,plot_field)
97
- plt.show()
98
-
99
-
100
- if __name__ == "__main__":
101
- main()
@@ -1,102 +0,0 @@
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 matplotlib.pyplot as plt
9
- from scipy.spatial.transform import Rotation
10
- import mooseherder as mh
11
- import pyvale as pyv
12
-
13
- def main() -> None:
14
- """pyvale example: displacement sensors on a 2D plate with a hole
15
- ----------------------------------------------------------------------------
16
- """
17
- data_path = pyv.DataSet.mechanical_2d_path()
18
- sim_data = mh.ExodusReader(data_path).read_all_sim_data()
19
- # Scale to mm to make 3D visualisation scaling easier
20
- sim_data.coords = sim_data.coords*1000.0 # type: ignore
21
-
22
- descriptor = pyv.SensorDescriptorFactory.displacement_descriptor()
23
-
24
- spat_dims = 2
25
- field_key = "disp"
26
- components = ("disp_x","disp_y")
27
- disp_field = pyv.FieldVector(sim_data,field_key,components,spat_dims)
28
-
29
- #---------------------------------------------------------------------------
30
- n_sens = (2,2,1)
31
- x_lims = (0.0,100.0)
32
- y_lims = (0.0,150.0)
33
- z_lims = (0.0,0.0)
34
- sensor_positions = pyv.create_sensor_pos_array(n_sens,
35
- x_lims,
36
- y_lims,
37
- z_lims)
38
-
39
- use_sim_time = False
40
- if use_sim_time:
41
- sample_times = None
42
- else:
43
- sample_times = np.linspace(0.0,np.max(sim_data.time),50)
44
-
45
- sensor_angles = sensor_positions.shape[0] * \
46
- (Rotation.from_euler("zyx", [0, 0, 0], degrees=True),)
47
-
48
- sensor_data = pyv.SensorData(positions=sensor_positions,
49
- sample_times=sample_times,
50
- angles=sensor_angles,
51
- spatial_averager=pyv.EIntSpatialType.QUAD4PT,
52
- spatial_dims=np.array([5.0,5.0,0.0]))
53
-
54
- #---------------------------------------------------------------------------
55
- disp_sensors = pyv.SensorArrayPoint(sensor_data,
56
- disp_field,
57
- descriptor)
58
-
59
- pos_offset = -10.0*np.ones_like(sensor_positions)
60
- pos_offset[:,2] = 0 # in 2d we only have offset in x and y so zero z
61
-
62
- angle_offset = np.zeros_like(sensor_positions)
63
- angle_offset[:,0] = 5.0 # only rotate about z in 2D
64
-
65
- time_offset = 1.0*np.ones_like(disp_sensors.get_sample_times())
66
-
67
- field_error_data = pyv.ErrFieldData(pos_offset_xyz=pos_offset,
68
- ang_offset_zyx=angle_offset,
69
- time_offset=time_offset)
70
-
71
- error_chain = []
72
- error_chain.append(pyv.ErrSysField(disp_field,field_error_data))
73
- error_integrator = pyv.ErrIntegrator(error_chain,
74
- sensor_data,
75
- disp_sensors.get_measurement_shape())
76
-
77
- disp_sensors.set_error_integrator(error_integrator)
78
-
79
- measurements = disp_sensors.calc_measurements()
80
-
81
- #---------------------------------------------------------------------------
82
- print(80*"-")
83
- sens_num = 4
84
- print("The last 5 time steps (measurements) of sensor {sens_num}:")
85
- pyv.print_measurements(disp_sensors,
86
- (sens_num-1,sens_num),
87
- (0,1),
88
- (measurements.shape[2]-5,measurements.shape[2]))
89
- print(80*"-")
90
-
91
- #---------------------------------------------------------------------------
92
- plot_field = "disp_x"
93
-
94
- pv_plot = pyv.plot_point_sensors_on_sim(disp_sensors,plot_field)
95
- pv_plot.show(cpos="xy")
96
-
97
- pyv.plot_time_traces(disp_sensors,plot_field)
98
- plt.show()
99
-
100
-
101
- if __name__ == "__main__":
102
- main()
@@ -1,54 +0,0 @@
1
- # ================================================================================
2
- # pyvale: the python validation engine
3
- # License: MIT
4
- # Copyright (C) 2025 The Computer Aided Validation Team
5
- # ================================================================================
6
-
7
- from pathlib import Path
8
- import numpy as np
9
- import matplotlib.pyplot as plt
10
- import mooseherder as mh
11
- import pyvale as pyv
12
-
13
- def main() -> None:
14
- """pyvale example: strain sensors on a 2D plate with a hole
15
- ----------------------------------------------------------------------------
16
- """
17
- data_path = pyv.DataSet.mechanical_2d_path()
18
- sim_data = mh.ExodusReader(data_path).read_all_sim_data()
19
- # Scale to mm to make 3D visualisation scaling easier
20
- sim_data.coords = sim_data.coords*1000.0 # type: ignore
21
-
22
- n_sens = (2,3,1)
23
- x_lims = (0.0,100.0)
24
- y_lims = (0.0,150.0)
25
- z_lims = (0.0,0.0)
26
- sens_pos = pyv.create_sensor_pos_array(n_sens,x_lims,y_lims,z_lims)
27
-
28
- use_sim_time = False
29
- if use_sim_time:
30
- sample_times = None
31
- else:
32
- sample_times = np.linspace(0.0,np.max(sim_data.time),50)
33
-
34
- sens_data = pyv.SensorData(positions=sens_pos,
35
- sample_times=sample_times)
36
-
37
- straingauge_array = pyv.SensorArrayFactory \
38
- .strain_gauges_basic_errs(sim_data,
39
- sens_data,
40
- "strain",
41
- spat_dims=2)
42
-
43
- plot_field = 'strain_yy'
44
- pv_plot = pyv.plot_point_sensors_on_sim(straingauge_array,plot_field)
45
- pv_plot.show(cpos="xy")
46
-
47
- pyv.plot_time_traces(straingauge_array,'strain_xx')
48
- pyv.plot_time_traces(straingauge_array,'strain_yy')
49
- pyv.plot_time_traces(straingauge_array,'strain_xy')
50
- plt.show()
51
-
52
-
53
- if __name__ == "__main__":
54
- main()
@@ -1,76 +0,0 @@
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 matplotlib.pyplot as plt
9
- import mooseherder as mh
10
- import pyvale as pyv
11
-
12
- def main() -> None:
13
- """pyvale example: strain sensors on a 2D plate with a hole
14
- ----------------------------------------------------------------------------
15
- """
16
- data_path = pyv.DataSet.mechanical_2d_path()
17
- sim_data = mh.ExodusReader(data_path).read_all_sim_data()
18
- # Scale to mm to make 3D visualisation scaling easier
19
- sim_data.coords = sim_data.coords*1000.0 # type: ignore
20
-
21
- descriptor = pyv.SensorDescriptor()
22
- descriptor.name = 'Strain'
23
- descriptor.symbol = r'\varepsilon'
24
- descriptor.units = r'-'
25
- descriptor.tag = 'SG'
26
- descriptor.components = ('xx','yy','xy')
27
-
28
- spat_dims = 2
29
- field_key = 'strain'
30
- norm_components = ('strain_xx','strain_yy')
31
- dev_components = ('strain_xy',)
32
- strain_field = pyv.FieldTensor(sim_data,
33
- field_key,
34
- norm_components,
35
- dev_components,
36
- spat_dims)
37
-
38
- n_sens = (2,3,1)
39
- x_lims = (0.0,100.0)
40
- y_lims = (0.0,150.0)
41
- z_lims = (0.0,0.0)
42
- sens_pos = pyv.create_sensor_pos_array(n_sens,x_lims,y_lims,z_lims)
43
-
44
- use_sim_time = False
45
- if use_sim_time:
46
- sample_times = None
47
- else:
48
- sample_times = np.linspace(0.0,np.max(sim_data.time),50)
49
-
50
- sens_data = pyv.SensorData(positions=sens_pos,
51
- sample_times=sample_times)
52
-
53
- straingauge_array = pyv.SensorArrayPoint(sens_data,
54
- strain_field,
55
- descriptor)
56
-
57
- error_chain = []
58
- error_chain.append(pyv.ErrSysUniform(low=-0.1e-3,high=0.1e-3))
59
- error_chain.append(pyv.ErrRandNormal(std=0.1e-3))
60
- error_int = pyv.ErrIntegrator(error_chain,
61
- sens_data,
62
- straingauge_array.get_measurement_shape())
63
- straingauge_array.set_error_integrator(error_int)
64
-
65
- plot_field = 'strain_yy'
66
- pv_plot = pyv.plot_point_sensors_on_sim(straingauge_array,plot_field)
67
- pv_plot.show(cpos="xy")
68
-
69
- pyv.plot_time_traces(straingauge_array,'strain_xx')
70
- pyv.plot_time_traces(straingauge_array,'strain_yy')
71
- pyv.plot_time_traces(straingauge_array,'strain_xy')
72
- plt.show()
73
-
74
-
75
- if __name__ == "__main__":
76
- main()
@@ -1,97 +0,0 @@
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 matplotlib.pyplot as plt
9
- from scipy.spatial.transform import Rotation as R
10
- import mooseherder as mh
11
- import pyvale as pyv
12
-
13
- def main() -> None:
14
- """pyvale example: strain sensors on a 2D plate with a hole
15
- ----------------------------------------------------------------------------
16
- - Demonstrates rotation of tensor fields
17
- """
18
- data_path = pyv.DataSet.mechanical_2d_path()
19
- sim_data = mh.ExodusReader(data_path).read_all_sim_data()
20
- # Scale to mm to make 3D visualisation scaling easier
21
- sim_data.coords = sim_data.coords*1000.0 # type: ignore
22
-
23
- descriptor = pyv.SensorDescriptorFactory.strain_descriptor()
24
-
25
- spat_dims = 2
26
- field_key = 'strain'
27
- norm_components = ('strain_xx','strain_yy')
28
- dev_components = ('strain_xy',)
29
- strain_field = pyv.FieldTensor(sim_data,
30
- field_key,
31
- norm_components,
32
- dev_components,
33
- spat_dims)
34
-
35
- n_sens = (2,3,1)
36
- x_lims = (0.0,100.0)
37
- y_lims = (0.0,150.0)
38
- z_lims = (0.0,0.0)
39
- sensor_positions = pyv.create_sensor_pos_array(n_sens,x_lims,y_lims,z_lims)
40
-
41
- use_sim_time = False
42
- if use_sim_time:
43
- sample_times = None
44
- else:
45
- sample_times = np.linspace(0.0,np.max(sim_data.time),50)
46
-
47
- sens_data_norot = pyv.SensorData(positions=sensor_positions,
48
- sample_times=sample_times)
49
-
50
- sg_array_norot = pyv.SensorArrayPoint(sens_data_norot,
51
- strain_field,
52
- descriptor)
53
-
54
- meas_norot = sg_array_norot.get_measurements()
55
-
56
- sens_angles = sensor_positions.shape[0] * \
57
- (R.from_euler("zyx", [45, 0, 0], degrees=True),)
58
-
59
- sens_data_rot = pyv.SensorData(positions=sensor_positions,
60
- sample_times=sample_times,
61
- angles=sens_angles)
62
-
63
- sg_array_rot = pyv.SensorArrayPoint(sens_data_rot,
64
- strain_field,
65
- descriptor)
66
-
67
- angle_offset = np.zeros_like(sensor_positions)
68
- angle_offset[:,0] = 1.0 # only rotate about z in 2D
69
- angle_error_data = pyv.ErrFieldData(ang_offset_zyx=angle_offset)
70
-
71
- sys_err_rot = pyv.ErrSysField(strain_field,angle_error_data)
72
- err_int = pyv.ErrIntegrator([sys_err_rot],
73
- sens_data_rot,
74
- sg_array_rot.get_measurement_shape())
75
- sg_array_rot.set_error_integrator(err_int)
76
-
77
-
78
- meas_rot = sg_array_rot.get_measurements()
79
-
80
-
81
- print(80*'-')
82
- sens_num = 4
83
- print('The last 5 time steps (measurements) of sensor {sens_num}:')
84
- pyv.print_measurements(sg_array_rot,
85
- (sens_num-1,sens_num),
86
- (1,2),
87
- (meas_rot.shape[2]-5,meas_rot.shape[2]))
88
- print(80*'-')
89
-
90
- plot_comp = 'strain_yy'
91
- pyv.plot_time_traces(sg_array_norot,plot_comp)
92
- pyv.plot_time_traces(sg_array_rot,plot_comp)
93
- plt.show()
94
-
95
-
96
- if __name__ == "__main__":
97
- main()
@@ -1,75 +0,0 @@
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 matplotlib.pyplot as plt
9
- import mooseherder as mh
10
- import pyvale as pyv
11
-
12
-
13
- def main() -> None:
14
- """pyvale example: thermo-mechanical multi-physics sensors on a 2D plate
15
- ----------------------------------------------------------------------------
16
- """
17
- #===========================================================================
18
- # Load Simulations as mooseherder.SimData objects
19
- data_path = pyv.DataSet.thermomechanical_2d_path()
20
- sim_data = mh.ExodusReader(data_path).read_all_sim_data()
21
- # Scale to mm to make 3D visualisation scaling easier
22
- sim_data.coords = sim_data.coords*1000.0 # type: ignore
23
-
24
- #===========================================================================
25
- # Specify sensor locations and sample times
26
- n_sens = (4,1,1)
27
- x_lims = (0.0,100.0)
28
- y_lims = (0.0,50.0)
29
- z_lims = (0.0,0.0)
30
- sens_pos = pyv.create_sensor_pos_array(n_sens,x_lims,y_lims,z_lims)
31
-
32
- use_sim_time = True
33
- if use_sim_time:
34
- sample_times = None
35
- else:
36
- sample_times = np.linspace(0.0,np.max(sim_data.time),50)
37
-
38
- sens_data = pyv.SensorData(positions=sens_pos,
39
- sample_times=sample_times)
40
-
41
- #===========================================================================
42
- # Create pyvale sensor arrays for thermal and mechanical data
43
- tc_field = 'temperature'
44
- tc_array = pyv.SensorArrayFactory \
45
- .thermocouples_basic_errs(sim_data,
46
- sens_data,
47
- tc_field,
48
- spat_dims=2)
49
-
50
- sg_field = 'strain'
51
- sg_array = pyv.SensorArrayFactory \
52
- .strain_gauges_basic_errs(sim_data,
53
- sens_data,
54
- sg_field,
55
- spat_dims=2)
56
-
57
- #===========================================================================
58
- # Visualise Traces
59
- print(80*'-')
60
- sens_num = 4
61
- print('THERMAL: The last 5 time steps (measurements) of sensor {sens_num}:')
62
- pyv.print_measurements(tc_array,
63
- (sens_num-1,sens_num),
64
- (0,1),
65
- (tc_array.get_measurement_shape()[2]-5,
66
- tc_array.get_measurement_shape()[2]))
67
- print(80*'-')
68
-
69
- pyv.plot_time_traces(tc_array,"temperature")
70
- pyv.plot_time_traces(sg_array,"strain_xx")
71
- plt.show()
72
-
73
-
74
- if __name__ == "__main__":
75
- main()
@@ -1,115 +0,0 @@
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 matplotlib.pyplot as plt
9
- import mooseherder as mh
10
- import pyvale as pyv
11
-
12
- def main() -> None:
13
- """pyvale example: thermo-mechanical multi-physics sensors on a 2D plate
14
- ----------------------------------------------------------------------------
15
- - Demonstrates the experiment module for running many monte-carlo style
16
- experiments and statistically analysing the results.
17
- """
18
- # Load Simulations as mooseherder.SimData objects
19
- #base_path = Path("src/pyvale/data")
20
- data_paths = pyv.DataSet.thermomechanical_2d_experiment_paths()
21
-
22
- sim_list = []
23
- for pp in data_paths:
24
- sim_data = mh.ExodusReader(pp).read_all_sim_data()
25
- # Scale to mm to make 3D visualisation scaling easier
26
- sim_data.coords = sim_data.coords*1000.0 # type: ignore
27
- sim_list.append(sim_data)
28
-
29
- #===========================================================================
30
- # Create pyvale sensor arrays for thermal and mechanical data
31
- sim_data = sim_list[0]
32
-
33
- n_sens = (4,1,1)
34
- x_lims = (0.0,100.0)
35
- y_lims = (0.0,50.0)
36
- z_lims = (0.0,0.0)
37
- sens_pos = pyv.create_sensor_pos_array(n_sens,x_lims,y_lims,z_lims)
38
-
39
- use_sim_time = True
40
- if use_sim_time:
41
- sample_times = None
42
- else:
43
- sample_times = np.linspace(0.0,np.max(sim_data.time),50)
44
-
45
- sens_data = pyv.SensorData(positions=sens_pos,
46
- sample_times=sample_times)
47
-
48
- tc_field = 'temperature'
49
- tc_array = pyv.SensorArrayFactory \
50
- .thermocouples_basic_errs(sim_data,
51
- sens_data,
52
- tc_field,
53
- spat_dims=2,
54
- errs_pc=1.0)
55
-
56
- sg_field = 'strain'
57
- sg_array = pyv.SensorArrayFactory \
58
- .strain_gauges_basic_errs(sim_data,
59
- sens_data,
60
- sg_field,
61
- spat_dims=2,
62
- errs_pc=1.0)
63
-
64
- sensor_arrays = [tc_array,sg_array]
65
-
66
- #===========================================================================
67
- # Create and run the simulated experiment
68
- exp_sim = pyv.ExperimentSimulator(sim_list,
69
- sensor_arrays,
70
- num_exp_per_sim=1000)
71
-
72
- exp_data = exp_sim.run_experiments()
73
- exp_stats = exp_sim.calc_stats()
74
-
75
- #===========================================================================
76
- print(80*"=")
77
- print("exp_data and exp_stats are lists where the index is the sensor array")
78
- print("position in the list as field components are not consistent dims.\n")
79
-
80
- print(80*"-")
81
- print("Thermal sensor array @ exp_data[0]")
82
- print(80*"-")
83
- print("shape=(n_sims,n_exps,n_sensors,n_field_comps,n_time_steps)")
84
- print(f"{exp_data[0].shape=}")
85
- print()
86
- print("Stats are calculated over all experiments (axis=1)")
87
- print("shape=(n_sims,n_sensors,n_field_comps,n_time_steps)")
88
- print(f"{exp_stats[0].max.shape=}")
89
- print()
90
- print(80*"-")
91
- print("Mechanical sensor array @ exp_data[1]")
92
- print(80*"-")
93
- print("shape=(n_sims,n_exps,n_sensors,n_field_comps,n_time_steps)")
94
- print(f"{exp_data[1].shape=}")
95
- print()
96
- print("shape=(n_sims,n_sensors,n_field_comps,n_time_steps)")
97
- print(f"{exp_stats[1].max.shape=}")
98
- print(80*"=")
99
-
100
- #===========================================================================
101
- # VISUALISE RESULTS
102
- (fig,ax) = pyv.plot_exp_traces(exp_sim,
103
- component="temperature",
104
- sens_array_num=0,
105
- sim_num=0)
106
-
107
- (fig,ax) = pyv.plot_exp_traces(exp_sim,
108
- component="strain_yy",
109
- sens_array_num=1,
110
- sim_num=2)
111
- plt.show()
112
-
113
-
114
- if __name__ == "__main__":
115
- main()