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.

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.1.dist-info}/METADATA +17 -14
  96. pyvale-2025.5.1.dist-info/RECORD +172 -0
  97. {pyvale-2025.4.1.dist-info → pyvale-2025.5.1.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.1.dist-info}/licenses/LICENSE +0 -0
  126. {pyvale-2025.4.1.dist-info → pyvale-2025.5.1.dist-info}/top_level.txt +0 -0
@@ -1,108 +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 matplotlib.pyplot as plt
8
- import mooseherder as mh
9
- import pyvale as pyv
10
-
11
-
12
- def main() -> None:
13
- """pyvale example: Point sensors on a 2D thermal simulation
14
- ----------------------------------------------------------------------------
15
- - Explanation of the usage of "get_measurements()" and "calc_measurements()"
16
-
17
- NOTES:
18
- - A sensor measurement is defined as:
19
- measurement = truth + systematic error + random error.
20
- - Calling the "get" methods of the sensor array will retrieve the results
21
- for the current experiment.
22
- - Calling the "calc" methods will generate a new
23
- experiment by sampling/calculating the systematic and random errors.
24
- """
25
- data_path = pyv.DataSet.thermal_2d_path()
26
- sim_data = mh.ExodusReader(data_path).read_all_sim_data()
27
- field_key = list(sim_data.node_vars.keys())[0] # type: ignore
28
- # Scale to mm to make 3D visualisation scaling easier
29
- sim_data.coords = sim_data.coords*1000.0 # type: ignore
30
-
31
- n_sens = (4,1,1)
32
- x_lims = (0.0,100.0)
33
- y_lims = (0.0,50.0)
34
- z_lims = (0.0,0.0)
35
- sens_pos = pyv.create_sensor_pos_array(n_sens,x_lims,y_lims,z_lims)
36
- sens_data = pyv.SensorData(positions=sens_pos)
37
-
38
- tc_array = pyv.SensorArrayFactory \
39
- .thermocouples_basic_errs(sim_data,
40
- sens_data,
41
- field_key,
42
- spat_dims=2)
43
-
44
-
45
- measurements = tc_array.get_measurements()
46
-
47
- print("\n"+80*"-")
48
- print("For a sensor: measurement = truth + sysematic error + random error")
49
- print(f"measurements.shape = {measurements.shape} = "+
50
- "(n_sensors,n_field_components,n_timesteps)\n")
51
- print("The truth, systematic error and random error arrays have the same "+
52
- "shape.")
53
-
54
- print(80*"-")
55
- print("Looking at the last 5 time steps (measurements) of sensor 0:")
56
- pyv.print_measurements(tc_array,
57
- (0,1),
58
- (0,1),
59
- (measurements.shape[2]-5,measurements.shape[2]))
60
- print(80*"-")
61
- print("If we call the \"calc_measurements()\" method then the errors are "+
62
- "(re)calculated or sampled.")
63
- measurements = tc_array.calc_measurements()
64
-
65
- pyv.print_measurements(tc_array,
66
- (0,1),
67
- (0,1),
68
- (measurements.shape[2]-5,measurements.shape[2]))
69
-
70
-
71
- (_,ax) = pyv.plot_time_traces(tc_array,field_key)
72
- ax.set_title("Exp 1: called calc_measurements()")
73
-
74
- print(80*"-")
75
- print("If we call the \"get_measurements()\" method then the errors are the "+
76
- "same:")
77
- measurements = tc_array.get_measurements()
78
-
79
- pyv.print_measurements(tc_array,
80
- (0,1),
81
- (0,1),
82
- (measurements.shape[2]-5,measurements.shape[2]))
83
-
84
- (_,ax) = pyv.plot_time_traces(tc_array,field_key)
85
- ax.set_title("Exp 2: called get_measurements()")
86
-
87
- print(80*"-")
88
- print("If we call the \"calc_measurements()\" method again we generate/sample"+
89
- "new errors:")
90
- measurements = tc_array.calc_measurements()
91
-
92
- pyv.print_measurements(tc_array,
93
- (0,1),
94
- (0,1),
95
- (measurements.shape[2]-5,measurements.shape[2]))
96
-
97
- (_,ax) = pyv.plot_time_traces(tc_array,field_key)
98
- ax.set_title("Exp 3: called calc_measurements()")
99
-
100
- print(80*"-")
101
-
102
- plot_on = True
103
- if plot_on:
104
- plt.show()
105
-
106
-
107
- if __name__ == "__main__":
108
- main()
@@ -1,110 +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: Point sensors on a 2D thermal simulation
15
- ----------------------------------------------------------------------------
16
- - Full construction of a point sensor array from scratch
17
- - Explanation of the different types of error models
18
- - There are flags throughout the example allowing the user to toggle on/off
19
- parts of the sensor array construction
20
- """
21
- data_path = pyv.DataSet.thermal_2d_path()
22
- sim_data = mh.ExodusReader(data_path).read_all_sim_data()
23
- # Scale to mm to make 3D visualisation scaling easier
24
- sim_data.coords = sim_data.coords*1000.0 # type: ignore
25
-
26
- use_auto_descriptor = "blank"
27
- if use_auto_descriptor == "factory":
28
- descriptor = pyv.SensorDescriptorFactory.temperature_descriptor()
29
- elif use_auto_descriptor == "manual":
30
- descriptor = pyv.SensorDescriptor()
31
- descriptor.name = "Temperature"
32
- descriptor.symbol = "T"
33
- descriptor.units = r"^{\circ}C"
34
- descriptor.tag = "TC"
35
- else:
36
- descriptor = pyv.SensorDescriptor()
37
-
38
- field_key = "temperature" # ("disp_x","disp_y")
39
- t_field = pyv.FieldScalar(sim_data,
40
- field_key=field_key,
41
- spat_dims=2)
42
-
43
- n_sens = (4,1,1)
44
- x_lims = (0.0,100.0)
45
- y_lims = (0.0,50.0)
46
- z_lims = (0.0,0.0)
47
- sens_pos = pyv.create_sensor_pos_array(n_sens,x_lims,y_lims,z_lims)
48
-
49
- use_sim_time = False
50
- if use_sim_time:
51
- sample_times = None
52
- else:
53
- sample_times = np.linspace(0.0,np.max(sim_data.time),50)
54
-
55
- sensor_data = pyv.SensorData(positions=sens_pos,
56
- sample_times=sample_times)
57
-
58
- tc_array = pyv.SensorArrayPoint(sensor_data,
59
- t_field,
60
- descriptor)
61
-
62
- errors_on = {"indep_sys": True,
63
- "rand": True,
64
- "dep_sys": True}
65
-
66
- error_chain = []
67
- if errors_on["indep_sys"]:
68
- error_chain.append(pyv.ErrSysOffset(offset=-5.0))
69
- error_chain.append(pyv.ErrSysUniform(low=-5.0,
70
- high=5.0))
71
-
72
- if errors_on["rand"]:
73
- error_chain.append(pyv.ErrRandNormPercent(std_percent=1.0))
74
- error_chain.append(pyv.ErrRandUnifPercent(low_percent=-1.0,
75
- high_percent=1.0))
76
-
77
- if errors_on["dep_sys"]:
78
- error_chain.append(pyv.ErrSysDigitisation(bits_per_unit=2**8/100))
79
- error_chain.append(pyv.ErrSysSaturation(meas_min=0.0,meas_max=300.0))
80
-
81
- if len(error_chain) > 0:
82
- error_integrator = pyv.ErrIntegrator(error_chain,
83
- sensor_data,
84
- tc_array.get_measurement_shape())
85
- tc_array.set_error_integrator(error_integrator)
86
-
87
-
88
- measurements = tc_array.get_measurements()
89
-
90
- print("\n"+80*"-")
91
- print("For a sensor: measurement = truth + sysematic error + random error")
92
- print(f"measurements.shape = {measurements.shape} = "+
93
- "(n_sensors,n_field_components,n_timesteps)\n")
94
- print("The truth, systematic error and random error arrays have the same "+
95
- "shape.")
96
-
97
- print(80*"-")
98
- print("Looking at the last 5 time steps (measurements) of sensor 0:")
99
- pyv.print_measurements(tc_array,
100
- (0,1),
101
- (0,1),
102
- (measurements.shape[2]-5,measurements.shape[2]))
103
- print(80*"-")
104
-
105
- pyv.plot_time_traces(tc_array,field_key)
106
- plt.show()
107
-
108
-
109
- if __name__ == "__main__":
110
- 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
- import mooseherder as mh
10
- import pyvale as pyv
11
-
12
-
13
- def main() -> None:
14
- """pyvale example: point sensors on a 2D thermal simulation
15
- ----------------------------------------------------------------------------
16
- """
17
- data_path = pyv.DataSet.thermal_2d_path()
18
- sim_data = mh.ExodusReader(data_path).read_all_sim_data()
19
- field_key = list(sim_data.node_vars.keys())[0] # type: ignore
20
- # Scale to mm to make 3D visualisation scaling easier
21
- sim_data.coords = sim_data.coords*1000.0 # type: ignore
22
-
23
- n_sens = (4,1,1)
24
- x_lims = (0.0,100.0)
25
- y_lims = (0.0,50.0)
26
- z_lims = (0.0,0.0)
27
- sens_pos = pyv.create_sensor_pos_array(n_sens,x_lims,y_lims,z_lims)
28
-
29
- sample_times = np.linspace(0.0,np.max(sim_data.time),50) # | None
30
-
31
- sensor_data = pyv.SensorData(positions=sens_pos,
32
- sample_times=sample_times)
33
-
34
- tc_array = pyv.SensorArrayFactory \
35
- .thermocouples_no_errs(sim_data,
36
- sensor_data,
37
- field_key,
38
- spat_dims=2)
39
-
40
- #===========================================================================
41
- # Examples of full error library
42
-
43
- #---------------------------------------------------------------------------
44
- # Standard independent systematic errors
45
- err_chain = []
46
- err_chain.append(pyv.ErrSysOffset(offset=-1.0))
47
- err_chain.append(pyv.ErrSysOffsetPercent(offset_percent=-1.0))
48
-
49
- err_chain.append(pyv.ErrSysUniform(low=-2.0,
50
- high=2.0))
51
- err_chain.append(pyv.ErrSysUniformPercent(low_percent=-2.0,
52
- high_percent=2.0))
53
-
54
- err_chain.append(pyv.ErrSysNormal(std=1.0))
55
- err_chain.append(pyv.ErrSysNormPercent(std_percent=2.0))
56
-
57
- sys_gen = pyv.GeneratorTriangular(left=-1.0,
58
- mode=0.0,
59
- right=1.0)
60
- err_chain.append(pyv.ErrSysGenerator(sys_gen))
61
-
62
- #---------------------------------------------------------------------------
63
- err_chain.append(pyv.ErrRandNormal(std = 2.0))
64
- err_chain.append(pyv.ErrRandNormPercent(std_percent=2.0))
65
-
66
- err_chain.append(pyv.ErrRandUniform(low=-2.0,high=2.0))
67
- err_chain.append(pyv.ErrRandUnifPercent(low_percent=-2.0,
68
- high_percent=2.0))
69
-
70
- rand_gen = pyv.GeneratorTriangular(left=-5.0,
71
- mode=0.0,
72
- right=5.0)
73
- err_chain.append(pyv.ErrRandGenerator(rand_gen))
74
-
75
- #---------------------------------------------------------------------------
76
- err_chain.append(pyv.ErrSysDigitisation(bits_per_unit=2**8/100))
77
- err_chain.append(pyv.ErrSysSaturation(meas_min=0.0,meas_max=300.0))
78
-
79
- err_int = pyv.ErrIntegrator(err_chain,
80
- sensor_data,
81
- tc_array.get_measurement_shape())
82
- tc_array.set_error_integrator(err_int)
83
-
84
-
85
- #===========================================================================
86
-
87
- measurements = tc_array.calc_measurements()
88
- print(80*'-')
89
- sens_num = 4
90
- print('The last 5 time steps (measurements) of sensor {sens_num}:')
91
- pyv.print_measurements(tc_array,
92
- (sens_num-1,sens_num),
93
- (0,1),
94
- (measurements.shape[2]-5,measurements.shape[2]))
95
- print(80*'-')
96
-
97
- pyv.plot_time_traces(tc_array,field_key)
98
- plt.show()
99
-
100
-
101
- if __name__ == '__main__':
102
- main()
@@ -1,84 +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 matplotlib.pyplot as plt
9
- import mooseherder as mh
10
- import pyvale as pyv
11
-
12
-
13
- def main() -> None:
14
- """pyvale example: thermocouples on a 3D divertor monoblock heatsink
15
- ----------------------------------------------------------------------------
16
- """
17
- #data_path = pyv.DataSet.thermal_3d_path()
18
- data_path = Path.cwd()/"src"/"pyvale"/"simcases"/"case16_out.e"
19
- sim_data = mh.ExodusReader(data_path).read_all_sim_data()
20
- field_name = 'temperature'
21
- # Scale to mm to make 3D visualisation scaling easier
22
- sim_data.coords = sim_data.coords*1000.0 # type: ignore
23
-
24
- n_sens = (1,4,1)
25
- x_lims = (12.5,12.5)
26
- y_lims = (0.0,33.0)
27
- z_lims = (0.0,12.0)
28
- sens_pos = pyv.create_sensor_pos_array(n_sens,x_lims,y_lims,z_lims)
29
-
30
- sens_data = pyv.SensorData(positions=sens_pos)
31
-
32
- tc_array = pyv.SensorArrayFactory \
33
- .thermocouples_basic_errs(sim_data,
34
- sens_data,
35
- field_name,
36
- spat_dims=3)
37
-
38
- measurements = tc_array.get_measurements()
39
- print(f'\nMeasurements for sensor at top of block:\n{measurements[-1,0,:]}\n')
40
-
41
- pv_plot = pyv.plot_point_sensors_on_sim(tc_array,field_name)
42
-
43
- # Set this to 'interactive' to get an interactive 3D plot of the simulation
44
- # and labelled sensor locations, set to 'save_fig' to create a vector
45
- # graphic using a specified camera position.
46
- pv_plot_mode = 'interactive'
47
-
48
- if pv_plot_mode == 'interactive':
49
- pv_plot.camera_position = [(59.354, 43.428, 69.946),
50
- (-2.858, 13.189, 4.523),
51
- (-0.215, 0.948, -0.233)]
52
- pv_plot.show()
53
-
54
- print(80*"=")
55
- print('Camera positions = ')
56
- print(pv_plot.camera_position)
57
- print(80*"="+"\n")
58
-
59
- if pv_plot_mode == 'save_fig':
60
- # Determined manually by moving camera and then dumping camera position
61
- # to console after window close - see 'interactive above'
62
- pv_plot.camera_position = [(59.354, 43.428, 69.946),
63
- (-2.858, 13.189, 4.523),
64
- (-0.215, 0.948, -0.233)]
65
- save_render = Path('src/examples/monoblock_thermal_sim_view.svg')
66
- pv_plot.save_graphic(save_render) # only for .svg .eps .ps .pdf .tex
67
- pv_plot.screenshot(save_render.with_suffix('.png'))
68
-
69
- # Set this to 'interactive' to get a matplotlib.pyplot with the sensor
70
- # traces plotted over time. Set to 'save_fig' to save an image of the plot
71
- # to file.
72
- trace_plot_mode = 'interactive'
73
-
74
- (fig,_) = pyv.plot_time_traces(tc_array,field_name)
75
-
76
- if trace_plot_mode == 'interactive':
77
- plt.show()
78
- if trace_plot_mode == 'save_fig':
79
- save_traces = Path('src/examples/monoblock_thermal_traces.png')
80
- fig.savefig(save_traces, dpi=300, format='png', bbox_inches='tight')
81
-
82
-
83
- if __name__ == '__main__':
84
- main()
@@ -1,51 +0,0 @@
1
- '''
2
- ================================================================================
3
- Example: 3d thermocouples on a monoblock
4
-
5
- pyvale: the python validation engine
6
- License: MIT
7
- Copyright (C) 2025 The Computer Aided Validation Team
8
- ================================================================================
9
- '''
10
- import mooseherder as mh
11
- import pyvale as pyv
12
-
13
-
14
- def main() -> None:
15
- """pyvale example: thermocouples on a 3D divertor monoblock heatsink
16
- ----------------------------------------------------------------------------
17
- """
18
- data_path = pyv.DataSet.thermal_3d_path()
19
- sim_data = mh.ExodusReader(data_path).read_all_sim_data()
20
- field_name = 'temperature'
21
-
22
- # Scale to mm to make 3D visualisation scaling easier
23
- sim_data.coords = sim_data.coords*1000.0 # type: ignore
24
-
25
- n_sens = (1,4,1)
26
- x_lims = (12.5,12.5)
27
- y_lims = (0,31.0)
28
- z_lims = (0.0,12.5)
29
- sens_pos = pyv.create_sensor_pos_array(n_sens,x_lims,y_lims,z_lims)
30
-
31
- sens_data = pyv.SensorData(positions=sens_pos)
32
-
33
- tc_array = pyv.SensorArrayFactory() \
34
- .thermocouples_basic_errs(sim_data,
35
- sens_data,
36
- field_name,
37
- spat_dims=3)
38
-
39
-
40
- measurements = tc_array.get_measurements()
41
- print(f'\nMeasurements for sensor at top of block:\n{measurements[-1,0,:]}\n')
42
-
43
- pv_plot = pyv.plot_point_sensors_on_sim(tc_array,field_name)
44
- pv_plot.camera_position = [(59.354, 43.428, 69.946),
45
- (-2.858, 13.189, 4.523),
46
- (-0.215, 0.948, -0.233)]
47
- pv_plot.show()
48
-
49
-
50
- if __name__ == '__main__':
51
- main()
@@ -1,106 +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
-
14
- def main() -> None:
15
- """pyvale example: thermocouples on a 3D divertor monoblock heatsink
16
- ----------------------------------------------------------------------------
17
- """
18
- data_path = pyv.DataSet.thermal_3d_path()
19
- sim_data = mh.ExodusReader(data_path).read_all_sim_data()
20
-
21
- # Scale to mm to make 3D visualisation scaling easier
22
- sim_data.coords = sim_data.coords*1000.0 # type: ignore
23
-
24
- use_auto_descriptor = "manual"
25
- if use_auto_descriptor == "factory":
26
- descriptor = pyv.SensorDescriptorFactory.temperature_descriptor()
27
- elif use_auto_descriptor == "manual":
28
- descriptor = pyv.SensorDescriptor()
29
- descriptor.name = "Temperature"
30
- descriptor.symbol = "T"
31
- descriptor.units = r"^{\circ}C"
32
- descriptor.tag = "TC"
33
- else:
34
- descriptor = pyv.SensorDescriptor()
35
-
36
-
37
- field_key = "temperature"
38
- t_field = pyv.FieldScalar(sim_data,
39
- field_key=field_key,
40
- spat_dims=3)
41
-
42
- n_sens = (1,4,1)
43
- x_lims = (12.5,12.5)
44
- y_lims = (0.0,33.0)
45
- z_lims = (0.0,12.0)
46
- sens_pos = pyv.create_sensor_pos_array(n_sens,x_lims,y_lims,z_lims)
47
-
48
- use_sim_time = False
49
- if use_sim_time:
50
- sample_times = None
51
- else:
52
- sample_times = np.linspace(0.0,np.max(sim_data.time),80)
53
-
54
- sens_data = pyv.SensorData(positions=sens_pos,
55
- sample_times=sample_times)
56
-
57
- tc_array = pyv.SensorArrayPoint(sens_data,
58
- t_field,
59
- descriptor)
60
-
61
- errors_on = {"indep_sys": True,
62
- "rand": True,
63
- "dep_sys": True}
64
-
65
- error_chain = []
66
- if errors_on["indep_sys"]:
67
- error_chain.append(pyv.ErrSysOffset(offset=-5.0))
68
- error_chain.append(pyv.ErrSysUniform(low=-10.0,
69
- high=10.0))
70
-
71
- if errors_on["rand"]:
72
- error_chain.append(pyv.ErrRandNormPercent(std_percent=5.0))
73
- error_chain.append(pyv.ErrRandUnifPercent(low_percent=-5.0,
74
- high_percent=5.0))
75
-
76
- if errors_on["dep_sys"]:
77
- error_chain.append(pyv.ErrSysDigitisation(bits_per_unit=1/20))
78
- error_chain.append(pyv.ErrSysSaturation(meas_min=0.0,meas_max=800.0))
79
-
80
- if len(error_chain) > 0:
81
- error_integrator = pyv.ErrIntegrator(
82
- error_chain,
83
- sens_data,
84
- tc_array.get_measurement_shape(),
85
- )
86
- tc_array.set_error_integrator(error_integrator)
87
-
88
- measurements = tc_array.get_measurements()
89
- print(f"\nMeasurements for sensor at top of block:\n{measurements[-1,0,:]}\n")
90
-
91
-
92
- (fig,_) = pyv.plot_time_traces(tc_array,field_key)
93
- plt.show()
94
-
95
- save_fig = True
96
- if save_fig:
97
- image_path = Path.cwd() / "example_output"
98
- image_file = image_path / "monoblock_thermal_traces_syserrs.png"
99
- if not image_path.is_dir():
100
- image_path.mkdir()
101
-
102
- fig.savefig(image_file, dpi=300, format="png", bbox_inches="tight")
103
-
104
-
105
- if __name__ == "__main__":
106
- main()
@@ -1,44 +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 matplotlib.pyplot as plt
8
- import mooseherder as mh
9
- import pyvale as pyv
10
-
11
- def main() -> None:
12
- """pyvale example: displacement sensors on a 2D plate with a hole
13
- ----------------------------------------------------------------------------
14
- """
15
- data_path = pyv.DataSet.mechanical_2d_path()
16
- sim_data = mh.ExodusReader(data_path).read_all_sim_data()
17
- # Scale to mm to make 3D visualisation scaling easier
18
- sim_data.coords = sim_data.coords*1000.0 # type: ignore
19
-
20
- n_sens = (2,3,1)
21
- x_lims = (0.0,100.0)
22
- y_lims = (0.0,150.0)
23
- z_lims = (0.0,0.0)
24
- sens_pos = pyv.create_sensor_pos_array(n_sens,x_lims,y_lims,z_lims)
25
-
26
- sens_data = pyv.SensorData(positions=sens_pos)
27
-
28
- disp_sens_array = pyv.SensorArrayFactory \
29
- .disp_sensors_basic_errs(sim_data,
30
- sens_data,
31
- "displacement",
32
- spat_dims=2)
33
-
34
- plot_field = 'disp_x'
35
- pv_plot = pyv.plot_point_sensors_on_sim(disp_sens_array,plot_field)
36
- pv_plot.show(cpos="xy")
37
-
38
- pyv.plot_time_traces(disp_sens_array,'disp_x')
39
- pyv.plot_time_traces(disp_sens_array,'disp_y')
40
- plt.show()
41
-
42
-
43
- if __name__ == "__main__":
44
- 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
- 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: 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.SensorDescriptor()
23
- descriptor.name = 'Disp.'
24
- descriptor.symbol = r'u'
25
- descriptor.units = r'm'
26
- descriptor.tag = 'DS'
27
- descriptor.components = ('x','y','z')
28
-
29
- spat_dims = 2
30
- field_key = 'disp'
31
- components = ('disp_x','disp_y')
32
- disp_field = pyv.FieldVector(sim_data,field_key,components,spat_dims)
33
-
34
- n_sens = (2,3,1)
35
- x_lims = (0.0,100.0)
36
- y_lims = (0.0,150.0)
37
- z_lims = (0.0,0.0)
38
- sens_pos = pyv.create_sensor_pos_array(n_sens,x_lims,y_lims,z_lims)
39
-
40
- use_sim_time = False
41
- if use_sim_time:
42
- sample_times = None
43
- else:
44
- sample_times = np.linspace(0.0,np.max(sim_data.time),50)
45
-
46
- sens_data = pyv.SensorData(positions=sens_pos,
47
- sample_times=sample_times)
48
-
49
- disp_sens_array = pyv.SensorArrayPoint(sens_data,
50
- disp_field,
51
- descriptor)
52
-
53
- error_chain = []
54
- error_chain.append(pyv.ErrSysUniform(low=-0.01e-3,high=0.01e-3))
55
- error_chain.append(pyv.ErrRandNormal(std=0.01e-3))
56
- error_int = pyv.ErrIntegrator(error_chain,
57
- sens_data,
58
- disp_sens_array.get_measurement_shape())
59
- disp_sens_array.set_error_integrator(error_int)
60
-
61
-
62
- plot_field = 'disp_x'
63
- if plot_field == 'disp_x':
64
- pv_plot = pyv.plot_point_sensors_on_sim(disp_sens_array,'disp_x')
65
- pv_plot.show(cpos="xy")
66
- elif plot_field == 'disp_y':
67
- pv_plot = pyv.plot_point_sensors_on_sim(disp_sens_array,'disp_y')
68
- pv_plot.show(cpos="xy")
69
-
70
- pyv.plot_time_traces(disp_sens_array,'disp_x')
71
- pyv.plot_time_traces(disp_sens_array,'disp_y')
72
- plt.show()
73
-
74
-
75
- if __name__ == "__main__":
76
- main()