pyvale 2025.7.2__cp311-cp311-win_amd64.whl → 2025.8.1__cp311-cp311-win_amd64.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 (176) hide show
  1. pyvale/__init__.py +12 -92
  2. pyvale/blender/__init__.py +23 -0
  3. pyvale/{pyvaleexceptions.py → blender/blenderexceptions.py} +0 -3
  4. pyvale/{blenderlightdata.py → blender/blenderlightdata.py} +3 -3
  5. pyvale/{blendermaterialdata.py → blender/blendermaterialdata.py} +1 -1
  6. pyvale/{blenderrenderdata.py → blender/blenderrenderdata.py} +5 -3
  7. pyvale/{blenderscene.py → blender/blenderscene.py} +33 -30
  8. pyvale/{blendertools.py → blender/blendertools.py} +14 -10
  9. pyvale/dataset/__init__.py +7 -0
  10. pyvale/dataset/dataset.py +443 -0
  11. pyvale/dic/__init__.py +20 -0
  12. pyvale/{dic2d.py → dic/dic2d.py} +31 -36
  13. pyvale/dic/dic2dconv.py +6 -0
  14. pyvale/{dic2dcpp.cp311-win_amd64.pyd → dic/dic2dcpp.cp311-win_amd64.pyd} +0 -0
  15. pyvale/{dicdataimport.py → dic/dicdataimport.py} +8 -8
  16. pyvale/{dicregionofinterest.py → dic/dicregionofinterest.py} +1 -1
  17. pyvale/{dicresults.py → dic/dicresults.py} +1 -1
  18. pyvale/{dicstrain.py → dic/dicstrain.py} +9 -9
  19. pyvale/examples/basics/{ex1_1_basicscalars_therm2d.py → ex1a_basicscalars_therm2d.py} +12 -9
  20. pyvale/examples/basics/{ex1_2_sensormodel_therm2d.py → ex1b_sensormodel_therm2d.py} +17 -14
  21. pyvale/examples/basics/{ex1_3_customsens_therm3d.py → ex1c_customsens_therm3d.py} +27 -24
  22. pyvale/examples/basics/{ex1_4_basicerrors_therm3d.py → ex1d_basicerrors_therm3d.py} +32 -29
  23. pyvale/examples/basics/{ex1_5_fielderrs_therm3d.py → ex1e_fielderrs_therm3d.py} +19 -15
  24. pyvale/examples/basics/{ex1_6_caliberrs_therm2d.py → ex1f_caliberrs_therm2d.py} +20 -16
  25. pyvale/examples/basics/{ex1_7_spatavg_therm2d.py → ex1g_spatavg_therm2d.py} +19 -16
  26. pyvale/examples/basics/{ex2_1_basicvectors_disp2d.py → ex2a_basicvectors_disp2d.py} +13 -10
  27. pyvale/examples/basics/{ex2_2_vectorsens_disp2d.py → ex2b_vectorsens_disp2d.py} +19 -15
  28. pyvale/examples/basics/{ex2_3_sensangle_disp2d.py → ex2c_sensangle_disp2d.py} +21 -18
  29. pyvale/examples/basics/{ex2_4_chainfielderrs_disp2d.py → ex2d_chainfielderrs_disp2d.py} +31 -29
  30. pyvale/examples/basics/{ex2_5_vectorfields3d_disp3d.py → ex2e_vectorfields3d_disp3d.py} +21 -18
  31. pyvale/examples/basics/{ex3_1_basictensors_strain2d.py → ex3a_basictensors_strain2d.py} +16 -14
  32. pyvale/examples/basics/{ex3_2_tensorsens2d_strain2d.py → ex3b_tensorsens2d_strain2d.py} +17 -14
  33. pyvale/examples/basics/{ex3_3_tensorsens3d_strain3d.py → ex3c_tensorsens3d_strain3d.py} +25 -22
  34. pyvale/examples/basics/{ex4_1_expsim2d_thermmech2d.py → ex4a_expsim2d_thermmech2d.py} +17 -14
  35. pyvale/examples/basics/{ex4_2_expsim3d_thermmech3d.py → ex4b_expsim3d_thermmech3d.py} +37 -34
  36. pyvale/examples/basics/ex5_nomesh.py +24 -0
  37. pyvale/examples/dic/ex1_2_blenderdeformed.py +174 -0
  38. pyvale/examples/dic/ex1_region_of_interest.py +6 -3
  39. pyvale/examples/dic/ex2_plate_with_hole.py +21 -18
  40. pyvale/examples/dic/ex3_plate_with_hole_strain.py +8 -6
  41. pyvale/examples/dic/ex4_dic_blender.py +17 -15
  42. pyvale/examples/dic/ex5_dic_challenge.py +19 -14
  43. pyvale/examples/genanalyticdata/ex1_1_scalarvisualisation.py +16 -10
  44. pyvale/examples/genanalyticdata/ex1_2_scalarcasebuild.py +3 -3
  45. pyvale/examples/genanalyticdata/ex2_1_analyticsensors.py +29 -23
  46. pyvale/examples/genanalyticdata/ex2_2_analyticsensors_nomesh.py +67 -0
  47. pyvale/examples/imagedef2d/ex_imagedef2d_todisk.py +12 -9
  48. pyvale/examples/mooseherder/ex0_create_moose_config.py +65 -0
  49. pyvale/examples/mooseherder/ex1a_modify_moose_input.py +71 -0
  50. pyvale/examples/mooseherder/ex1b_modify_gmsh_input.py +69 -0
  51. pyvale/examples/mooseherder/ex2a_run_moose_once.py +80 -0
  52. pyvale/examples/mooseherder/ex2b_run_gmsh_once.py +64 -0
  53. pyvale/examples/mooseherder/ex2c_run_both_once.py +114 -0
  54. pyvale/examples/mooseherder/ex3_run_moose_seq_para.py +157 -0
  55. pyvale/examples/mooseherder/ex4_run_gmsh-moose_seq_para.py +176 -0
  56. pyvale/examples/mooseherder/ex5_run_moose_paramulti.py +136 -0
  57. pyvale/examples/mooseherder/ex6_read_moose_exodus.py +163 -0
  58. pyvale/examples/mooseherder/ex7a_read_moose_herd_results.py +153 -0
  59. pyvale/examples/mooseherder/ex7b_read_multi_herd_results.py +116 -0
  60. pyvale/examples/mooseherder/ex7c_read_multi_gmshmoose_results.py +127 -0
  61. pyvale/examples/mooseherder/ex7d_readconfig_multi_gmshmoose_results.py +143 -0
  62. pyvale/examples/mooseherder/ex8_read_existing_sweep_output.py +72 -0
  63. pyvale/examples/renderblender/ex1_1_blenderscene.py +24 -20
  64. pyvale/examples/renderblender/ex1_2_blenderdeformed.py +22 -18
  65. pyvale/examples/renderblender/ex2_1_stereoscene.py +36 -29
  66. pyvale/examples/renderblender/ex2_2_stereodeformed.py +26 -20
  67. pyvale/examples/renderblender/ex3_1_blendercalibration.py +24 -17
  68. pyvale/examples/renderrasterisation/ex_rastenp.py +14 -12
  69. pyvale/examples/renderrasterisation/ex_rastercyth_oneframe.py +14 -15
  70. pyvale/examples/renderrasterisation/ex_rastercyth_static_cypara.py +13 -11
  71. pyvale/examples/renderrasterisation/ex_rastercyth_static_pypara.py +13 -11
  72. pyvale/mooseherder/__init__.py +32 -0
  73. pyvale/mooseherder/directorymanager.py +416 -0
  74. pyvale/mooseherder/exodusreader.py +763 -0
  75. pyvale/mooseherder/gmshrunner.py +163 -0
  76. pyvale/mooseherder/inputmodifier.py +236 -0
  77. pyvale/mooseherder/mooseconfig.py +226 -0
  78. pyvale/mooseherder/mooseherd.py +527 -0
  79. pyvale/mooseherder/mooserunner.py +303 -0
  80. pyvale/mooseherder/outputreader.py +22 -0
  81. pyvale/mooseherder/simdata.py +92 -0
  82. pyvale/mooseherder/simrunner.py +31 -0
  83. pyvale/mooseherder/sweepreader.py +356 -0
  84. pyvale/mooseherder/sweeptools.py +76 -0
  85. pyvale/sensorsim/__init__.py +82 -0
  86. pyvale/{camera.py → sensorsim/camera.py} +7 -7
  87. pyvale/{camerasensor.py → sensorsim/camerasensor.py} +7 -7
  88. pyvale/{camerastereo.py → sensorsim/camerastereo.py} +2 -2
  89. pyvale/{cameratools.py → sensorsim/cameratools.py} +4 -4
  90. pyvale/{cython → sensorsim/cython}/rastercyth.c +596 -596
  91. pyvale/{cython → sensorsim/cython}/rastercyth.cp311-win_amd64.pyd +0 -0
  92. pyvale/{cython → sensorsim/cython}/rastercyth.py +16 -17
  93. pyvale/{errorcalculator.py → sensorsim/errorcalculator.py} +1 -1
  94. pyvale/{errorintegrator.py → sensorsim/errorintegrator.py} +2 -2
  95. pyvale/{errorrand.py → sensorsim/errorrand.py} +4 -4
  96. pyvale/{errorsyscalib.py → sensorsim/errorsyscalib.py} +2 -2
  97. pyvale/{errorsysdep.py → sensorsim/errorsysdep.py} +2 -2
  98. pyvale/{errorsysfield.py → sensorsim/errorsysfield.py} +8 -8
  99. pyvale/{errorsysindep.py → sensorsim/errorsysindep.py} +3 -3
  100. pyvale/sensorsim/exceptions.py +8 -0
  101. pyvale/{experimentsimulator.py → sensorsim/experimentsimulator.py} +23 -3
  102. pyvale/{field.py → sensorsim/field.py} +1 -1
  103. pyvale/{fieldconverter.py → sensorsim/fieldconverter.py} +72 -19
  104. pyvale/sensorsim/fieldinterp.py +37 -0
  105. pyvale/sensorsim/fieldinterpmesh.py +124 -0
  106. pyvale/sensorsim/fieldinterppoints.py +55 -0
  107. pyvale/{fieldsampler.py → sensorsim/fieldsampler.py} +4 -4
  108. pyvale/{fieldscalar.py → sensorsim/fieldscalar.py} +28 -24
  109. pyvale/{fieldtensor.py → sensorsim/fieldtensor.py} +33 -31
  110. pyvale/{fieldvector.py → sensorsim/fieldvector.py} +33 -31
  111. pyvale/{imagedef2d.py → sensorsim/imagedef2d.py} +9 -5
  112. pyvale/{integratorfactory.py → sensorsim/integratorfactory.py} +6 -6
  113. pyvale/{integratorquadrature.py → sensorsim/integratorquadrature.py} +3 -3
  114. pyvale/{integratorrectangle.py → sensorsim/integratorrectangle.py} +3 -3
  115. pyvale/{integratorspatial.py → sensorsim/integratorspatial.py} +1 -1
  116. pyvale/{rastercy.py → sensorsim/rastercy.py} +5 -5
  117. pyvale/{rasternp.py → sensorsim/rasternp.py} +9 -9
  118. pyvale/{rasteropts.py → sensorsim/rasteropts.py} +1 -1
  119. pyvale/{renderer.py → sensorsim/renderer.py} +1 -1
  120. pyvale/{rendermesh.py → sensorsim/rendermesh.py} +5 -5
  121. pyvale/{renderscene.py → sensorsim/renderscene.py} +2 -2
  122. pyvale/{sensorarray.py → sensorsim/sensorarray.py} +1 -1
  123. pyvale/{sensorarrayfactory.py → sensorsim/sensorarrayfactory.py} +12 -12
  124. pyvale/{sensorarraypoint.py → sensorsim/sensorarraypoint.py} +10 -8
  125. pyvale/{sensordata.py → sensorsim/sensordata.py} +1 -1
  126. pyvale/{sensortools.py → sensorsim/sensortools.py} +2 -20
  127. pyvale/sensorsim/simtools.py +174 -0
  128. pyvale/{visualexpplotter.py → sensorsim/visualexpplotter.py} +3 -3
  129. pyvale/{visualimages.py → sensorsim/visualimages.py} +2 -2
  130. pyvale/{visualsimanimator.py → sensorsim/visualsimanimator.py} +4 -4
  131. pyvale/{visualsimplotter.py → sensorsim/visualsimplotter.py} +5 -5
  132. pyvale/{visualsimsensors.py → sensorsim/visualsimsensors.py} +12 -12
  133. pyvale/{visualtools.py → sensorsim/visualtools.py} +1 -1
  134. pyvale/{visualtraceplotter.py → sensorsim/visualtraceplotter.py} +2 -2
  135. pyvale/simcases/case17.geo +3 -0
  136. pyvale/simcases/case17.i +4 -4
  137. pyvale/simcases/run_1case.py +1 -9
  138. pyvale/simcases/run_all_cases.py +1 -1
  139. pyvale/simcases/run_build_case.py +1 -1
  140. pyvale/simcases/run_example_cases.py +1 -1
  141. pyvale/verif/__init__.py +12 -0
  142. pyvale/{analyticsimdatafactory.py → verif/analyticsimdatafactory.py} +2 -2
  143. pyvale/{analyticsimdatagenerator.py → verif/analyticsimdatagenerator.py} +2 -2
  144. pyvale/verif/psens.py +125 -0
  145. pyvale/verif/psensconst.py +18 -0
  146. pyvale/verif/psensmech.py +227 -0
  147. pyvale/verif/psensmultiphys.py +187 -0
  148. pyvale/verif/psensscalar.py +347 -0
  149. pyvale/verif/psenstensor.py +123 -0
  150. pyvale/verif/psensvector.py +116 -0
  151. {pyvale-2025.7.2.dist-info → pyvale-2025.8.1.dist-info}/METADATA +6 -7
  152. pyvale-2025.8.1.dist-info/RECORD +260 -0
  153. pyvale/dataset.py +0 -415
  154. pyvale/simtools.py +0 -67
  155. pyvale-2025.7.2.dist-info/RECORD +0 -212
  156. /pyvale/{blendercalibrationdata.py → blender/blendercalibrationdata.py} +0 -0
  157. /pyvale/{dicchecks.py → dic/dicchecks.py} +0 -0
  158. /pyvale/{dicspecklegenerator.py → dic/dicspecklegenerator.py} +0 -0
  159. /pyvale/{dicspecklequality.py → dic/dicspecklequality.py} +0 -0
  160. /pyvale/{dicstrainresults.py → dic/dicstrainresults.py} +0 -0
  161. /pyvale/{cameradata.py → sensorsim/cameradata.py} +0 -0
  162. /pyvale/{cameradata2d.py → sensorsim/cameradata2d.py} +0 -0
  163. /pyvale/{errordriftcalc.py → sensorsim/errordriftcalc.py} +0 -0
  164. /pyvale/{fieldtransform.py → sensorsim/fieldtransform.py} +0 -0
  165. /pyvale/{generatorsrandom.py → sensorsim/generatorsrandom.py} +0 -0
  166. /pyvale/{imagetools.py → sensorsim/imagetools.py} +0 -0
  167. /pyvale/{integratortype.py → sensorsim/integratortype.py} +0 -0
  168. /pyvale/{output.py → sensorsim/output.py} +0 -0
  169. /pyvale/{raster.py → sensorsim/raster.py} +0 -0
  170. /pyvale/{sensordescriptor.py → sensorsim/sensordescriptor.py} +0 -0
  171. /pyvale/{visualimagedef.py → sensorsim/visualimagedef.py} +0 -0
  172. /pyvale/{visualopts.py → sensorsim/visualopts.py} +0 -0
  173. /pyvale/{analyticmeshgen.py → verif/analyticmeshgen.py} +0 -0
  174. {pyvale-2025.7.2.dist-info → pyvale-2025.8.1.dist-info}/WHEEL +0 -0
  175. {pyvale-2025.7.2.dist-info → pyvale-2025.8.1.dist-info}/licenses/LICENSE +0 -0
  176. {pyvale-2025.7.2.dist-info → pyvale-2025.8.1.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,443 @@
1
+ #===============================================================================
2
+ # pyvale: the python validation engine
3
+ # License: MIT
4
+ # Copyright (C) 2025 The Computer Aided Validation Team
5
+ #===============================================================================
6
+
7
+ """
8
+ Accesors for data that comes pre-packaged with pyvale for demonstrating its
9
+ functionality. This includes moose simulation outputs as exodus files, input
10
+ files for moose and gmsh for additional simulation cases, and images required
11
+ for testing the image deformation and digital image correlation modules.
12
+ """
13
+
14
+ from enum import Enum
15
+ from pathlib import Path
16
+ from importlib.resources import files
17
+
18
+ SIM_CASE_COUNT = 26
19
+ """Constant describing the number of simulation test case input files for moose
20
+ and gmsh that come packaged with pyvale.
21
+ """
22
+
23
+ class EElemTest(Enum):
24
+ """Enumeration used to specify different 3D element types for extracting
25
+ specific test simulation datasets.
26
+ """
27
+
28
+ TET4 = "TET4"
29
+ """Tetrahedral element, linear with 4 nodes.
30
+ """
31
+
32
+ TET10 = "TET10"
33
+ """Tetrahedral element, quadratic with 10 nodes.
34
+ """
35
+
36
+ TET14 = "TET14"
37
+ """Tetrahedral element, quadratic with 14 nodes.
38
+ """
39
+
40
+ HEX8 = "HEX8"
41
+ """Hexahedral element, linear with 8 nodes.
42
+ """
43
+
44
+ HEX20 = "HEX20"
45
+ """Hexahedral element, quadratic with 20 nodes.
46
+ """
47
+
48
+ HEX27 = "HEX27"
49
+ """Hexahedral element, quadratic with 27 nodes.
50
+ """
51
+
52
+ def __str__(self):
53
+ return self.value
54
+
55
+
56
+ class DataSetError(Exception):
57
+ """Custom error class for file io errors associated with retrieving datasets
58
+ and files packaged with pyvale.
59
+ """
60
+
61
+
62
+ def sim_case_input_file_path(case_num: int) -> Path:
63
+ """Gets the path to MOOSE input file (*.i) for a particular simulation
64
+ case.
65
+
66
+ Parameters
67
+ ----------
68
+ case_num : int
69
+ Integer defining the case number to be retrieved. Must be greater
70
+ than 0 and less than the number of simulation cases.
71
+
72
+ Returns
73
+ -------
74
+ Path
75
+ Path object to the MOOSE *.i file for the selected simulation case.
76
+
77
+ Raises
78
+ ------
79
+ DataSetError
80
+ Raised if an invalid simulation case number is specified.
81
+ """
82
+ if case_num <= 0:
83
+ raise DataSetError("Simulation case number must be greater than 0")
84
+ elif case_num > SIM_CASE_COUNT:
85
+ raise DataSetError("Simulation case number must be less than " \
86
+ + f"{SIM_CASE_COUNT}")
87
+
88
+ case_num_str = str(case_num).zfill(2)
89
+ case_file = f"case{case_num_str}.i"
90
+ return Path(files("pyvale.simcases").joinpath(case_file))
91
+
92
+
93
+ def sim_case_gmsh_file_path(case_num: int) -> Path | None:
94
+ """Gets the path to Gmsh input file (*.geo) for a particular simulation
95
+ case. Note that not all simulation cases use Gmsh for geometry and mesh
96
+ generation. If the specified simulation case does not have an associated
97
+ Gmsh *.geo file. In this case 'None' is returned
98
+
99
+ Parameters
100
+ ----------
101
+ case_num : int
102
+ Integer defining the case number to be retrieved. Must be greater
103
+ than 0 and less than the number of simulation cases.
104
+
105
+ Returns
106
+ -------
107
+ Path | None
108
+ Path object to the Gmsh *.geo file for the selected simulation case.
109
+ Returns None if there is no *.geo for this simulation case.
110
+
111
+ Raises
112
+ ------
113
+ DataSetError
114
+ Raised if an invalid simulation case number is specified.
115
+ """
116
+ if case_num <= 0:
117
+ raise DataSetError("Simulation case number must be greater than 0")
118
+ elif case_num > SIM_CASE_COUNT:
119
+ raise DataSetError("Simulation case number must be less than " \
120
+ + f"{SIM_CASE_COUNT}")
121
+
122
+ case_num_str = str(case_num).zfill(2)
123
+ case_file = f"case{case_num_str}.geo"
124
+ case_path = Path(files("pyvale.simcases").joinpath(case_file))
125
+
126
+ if case_path.is_file():
127
+ return case_path
128
+
129
+ return None
130
+
131
+
132
+ def dic_pattern_5mpx_path() -> Path:
133
+ """Path to a 5 mega-pixel speckle pattern image (2464 x 2056 pixels)
134
+ with 8 bit resolution stored as a *.tiff. Speckles are sampled by
135
+ 5 pixels. A gaussian blur has been applied to the image to remove sharp
136
+ transitions from black to white.
137
+
138
+ Path
139
+ Path to the *.tiff file containing the speckle pattern.
140
+ """
141
+ return Path(files("pyvale.data")
142
+ .joinpath("optspeckle_2464x2056px_spec5px_8bit_gblur1px.tiff"))
143
+
144
+
145
+ def thermal_2d_path() -> Path:
146
+ """Path to a MOOSE simulation output in exodus format. This case is a
147
+ thermal problem solving for a scalar temperature field. The geometry is
148
+ a 2D plate (in x,y) with a heat flux applied on one edge and a heat
149
+ transfer coefficient applied on the opposite edge inducing a temperature
150
+ gradient along the x axis of the plate.
151
+
152
+ The simulation parameters can be found in the corresponding MOOSE input
153
+ file: case13.i which can be retrieved using `sim_case_input_file_path`
154
+ in this class.
155
+
156
+
157
+ Returns
158
+ -------
159
+ Path
160
+ Path to the exodus (*.e) output file for this simulation case.
161
+ """
162
+ return Path(files("pyvale.data").joinpath("case13_out.e"))
163
+
164
+
165
+ def thermal_3d_path() -> Path:
166
+ """Path to a MOOSE simulation output in exodus format. This case is a 3D
167
+ thermal problem solving for a scalar temperature field. The model is a
168
+ divertor armour monoblock composed of a tungsten block bonded to a
169
+ copper-chromium-zirconium pipe with a pure copper interlayer. A heat
170
+ flux is applied to the top surface of the block and a heat transfer
171
+ coefficient for cooling water is applied to the inner surface of the
172
+ pipe inducing a temperature gradient from the top of the block to the
173
+ pipe.
174
+
175
+ The simulation parameters can be found in the corresponding MOOSE input
176
+ file: case16.i which can be retrieved using `sim_case_input_file_path`
177
+ in this class. Note that this case uses a Gmsh *.geo file for geometry
178
+ and mesh creation.
179
+
180
+ Returns
181
+ -------
182
+ Path
183
+ Path to the exodus (*.e) output file for this simulation case.
184
+ """
185
+ return Path(files("pyvale.data").joinpath("case16_out.e"))
186
+
187
+
188
+ def mechanical_2d_path() -> Path:
189
+ """Path to a MOOSE simulation output in exodus format. This case is a 2D
190
+ plate with a hole in the center with the bottom edge fixed and a
191
+ displacement applied to the top edge. This is a mechanical problem and
192
+ solves for the displacement vector field and the tensorial strain field.
193
+
194
+ The simulation parameters can be found in the corresponding MOOSE input
195
+ file: case17.i which can be retrieved using `sim_case_input_file_path`
196
+ in this class. Note that this case uses a Gmsh *.geo file for geometry
197
+ and mesh creation.
198
+
199
+ Returns
200
+ -------
201
+ Path
202
+ Path to the exodus (*.e) output file for this simulation case.
203
+ """
204
+ return Path(files("pyvale.data").joinpath("case17_out.e"))
205
+
206
+
207
+ def thermomechanical_2d_path() -> Path:
208
+ """Path to a MOOSE simulation output in exodus format. This case is a
209
+ thermo-mechanical analysis of a 2D plate with a heat flux applied on one
210
+ edge and a heat transfer coefficient applied on the opposing edge. The
211
+ mechanical deformation results from thermal expansion due to the imposed
212
+ temperature gradient. This model is solved for the scalar temperature
213
+ field, vector displacement and tensor strain field.
214
+
215
+ Returns
216
+ -------
217
+ Path
218
+ Path to the exodus (*.e) output file for this simulation case.
219
+ """
220
+ return Path(files("pyvale.data").joinpath("case18_1_out.e"))
221
+
222
+
223
+ def thermomechanical_3d_path() -> Path:
224
+ """Path to a MOOSE simulation output in exodus format. This case is a
225
+ thermo-mechanical analysis of a 3D monoblock divertor armour with a heat
226
+ flux applied on the top surface and a heat transfer coefficient applied
227
+ on the inner surface of the pipe. The mechanical deformation results
228
+ from thermal expansion due to the imposed temperature gradient.
229
+ This model is solved for the scalar temperature field, vector
230
+ displacement and tensor strain field.
231
+
232
+ Returns
233
+ -------
234
+ Path
235
+ Path to the exodus (*.e) output file for this simulation case.
236
+ """
237
+ return Path(files("pyvale.data").joinpath("case16_out.e"))
238
+
239
+
240
+ def thermomechanical_2d_experiment_paths() -> list[Path]:
241
+ """Path to a MOOSE simulation output in exodus format. This case is a
242
+ thermo-mechanical analysis of a 2D plate with a heat flux applied on one
243
+ edge and a heat transfer coefficient applied on the opposing edge. The
244
+ mechanical deformation results from thermal expansion due to the imposed
245
+ temperature gradient. This model is solved for the scalar temperature
246
+ field, vector temperature and tensor strain field.
247
+
248
+ Here we analyse 3 separate experiments where the thermal conductivity of
249
+ the material is perturbed from the nominal case by +/-10%.
250
+
251
+ The simulation parameters can be found in the corresponding MOOSE input
252
+ file: case18.i which can be retrieved using `sim_case_input_file_path`
253
+ in this class.
254
+
255
+ Returns
256
+ -------
257
+ Path
258
+ Path to the exodus (*.e) output file for this simulation case.
259
+ """
260
+ return [Path(files("pyvale.data").joinpath("case18_1_out.e")),
261
+ Path(files("pyvale.data").joinpath("case18_2_out.e")),
262
+ Path(files("pyvale.data").joinpath("case18_3_out.e"))]
263
+
264
+
265
+ def render_mechanical_3d_path() -> Path:
266
+ """Path to a MOOSE simulation output in exodus format. This case is a
267
+ purely mechanical test case in 3D meant for testing image rendering
268
+ algorithms for digital image correlation simulation. The simulation
269
+ consists of a linear elastic thin plate with a hole loaded in tension.
270
+ The simulation uses linear tetrahedral elements for rendering tests.
271
+
272
+ Returns
273
+ -------
274
+ Path
275
+ Path to the exodus (*.e) output file for this simulation case.
276
+ """
277
+ return Path(files("pyvale.data").joinpath("case26_out.e"))
278
+
279
+
280
+ def render_simple_block_path() -> Path:
281
+ """Path to a MOOSE simulation output in exodus format. This case is a
282
+ a simple rectangular block in 3D loaded in tension. It uses a minimum
283
+ number of elements and is intended purely for testing image rendering
284
+ algorithms. This simulation uses linear tetrahedral elements.
285
+
286
+ Returns
287
+ -------
288
+ Path
289
+ Path to the exodus (*.e) output file for this simulation case.
290
+ """
291
+ return Path(files("pyvale.data").joinpath("case25_out.e"))
292
+
293
+
294
+ def element_case_input_path(elem_type: EElemTest) -> Path:
295
+ """Path to a MOOSE simulation input file (.i) for a simple test
296
+ case. This case is a 10mm cube undergoing thermo-mechanical loading
297
+ solved for the temperature, displacement and strain fields. This case is
298
+ solved using a variety of tetrahedral and hexahedral elements with
299
+ linear or quadratic shapes functions. These simulation cases are
300
+ intended for testing purposes and contain a minimal number of elements.
301
+
302
+ Parameters
303
+ ----------
304
+ elem_type : EElemTest
305
+ Enumeration specifying the element type for this test case.
306
+
307
+ Returns
308
+ -------
309
+ Path
310
+ Path to the moose input file (.i) for this simulation case.
311
+ """
312
+ return Path(files("pyvale.simcases")
313
+ .joinpath(f"case00_{elem_type.value}.i"))
314
+
315
+
316
+
317
+ def element_case_output_path(elem_type: EElemTest) -> Path:
318
+ """Path to a MOOSE simulation output in exodus format. This case is a
319
+ 10mm cube undergoing thermo-mechanical loading solved for the
320
+ temperature, displacement and strain fields. This case is solved using a
321
+ variety of tetrahedral and hexahedral elements with linear or quadratic
322
+ shapes functions. These simulation cases are intended for testing
323
+ purposes and contain a minimal number of elements.
324
+
325
+ Parameters
326
+ ----------
327
+ elem_type : EElemTest
328
+ Enumeration specifying the element type for this test case.
329
+
330
+ Returns
331
+ -------
332
+ Path
333
+ Path to the exodus (*.e) output file for this simulation case.
334
+ """
335
+ return Path(files("pyvale.data")
336
+ .joinpath(f"case00_{elem_type.value}_out.e"))
337
+
338
+
339
+ def dic_plate_with_hole_ref() -> Path:
340
+ """Path to the reference image for the plate with hole example.
341
+ 1040x1540 image in .tiff format.
342
+
343
+ Parameters
344
+ ----------
345
+ elem_type : EElemTest
346
+ Enumeration specifying the element type for this test case.
347
+
348
+ Returns
349
+ -------
350
+ Path
351
+ Path to the reference image (*.tiff).
352
+ """
353
+ return Path(files("pyvale.data")
354
+ .joinpath("plate_hole_ref0000.tiff"))
355
+
356
+
357
+ def dic_plate_with_hole_def() -> Path:
358
+ """Path to the deformed images for the plate with hole example.
359
+ 1040x1540 image in .tiff format.
360
+
361
+ Parameters
362
+ ----------
363
+ elem_type : EElemTest
364
+ Enumeration specifying the element type for this test case.
365
+
366
+ Returns
367
+ -------
368
+ Path
369
+ Path to the reference image (*.tiff).
370
+ """
371
+ return Path(files("pyvale.data")
372
+ .joinpath("plate_hole_def*.tiff"))
373
+
374
+
375
+ def dic_plate_rigid_ref() -> Path:
376
+ """Path to the reference image for the plate with hole example.
377
+ 1040x1540 image in .tiff format.
378
+
379
+ Parameters
380
+ ----------
381
+ elem_type : EElemTest
382
+ Enumeration specifying the element type for this test case.
383
+
384
+ Returns
385
+ -------
386
+ Path
387
+ Path to the reference image (*.tiff).
388
+ """
389
+ return Path(files("pyvale.data")
390
+ .joinpath("plate_rigid_ref0000.tiff"))
391
+
392
+
393
+ def dic_plate_rigid_def() -> Path:
394
+ """Path to the deformed images for the plate with hole example.
395
+ 1040x1540 image in .tiff format.
396
+
397
+ Returns
398
+ -------
399
+ Path
400
+ Path to the reference image (*.tiff).
401
+ """
402
+ return Path(files("pyvale.data")
403
+ .joinpath("plate_rigid_def*.tiff"))
404
+
405
+
406
+
407
+
408
+ def dic_challenge_ref() -> Path:
409
+ """Path to the reference images for the 2D dic challenge.
410
+
411
+ Returns
412
+ -------
413
+ Path
414
+ Path to the reference image (*.tiff).
415
+ """
416
+ return Path(files("pyvale.data")
417
+ .joinpath("DIC_Challenge_Star_Noise_Ref.tiff"))
418
+
419
+
420
+ def dic_challenge_def() -> Path:
421
+ """Path to the reference images for the 2D dic challenge.
422
+
423
+ Returns
424
+ -------
425
+ Path
426
+ Path to the reference image (*.tiff).
427
+ """
428
+ return Path(files("pyvale.data")
429
+ .joinpath("DIC_Challenge_Star_Noise_Def.tiff"))
430
+
431
+ def cal_target() -> Path:
432
+ """Path to example calibration target.
433
+
434
+ Returns
435
+ -------
436
+ Path
437
+ Path to the image (*.tiff).
438
+ """
439
+ return Path(files("pyvale.data")
440
+ .joinpath("cal_target.tiff"))
441
+
442
+
443
+
pyvale/dic/__init__.py ADDED
@@ -0,0 +1,20 @@
1
+ #===============================================================================
2
+ # pyvale: the python validation engine
3
+ # License: MIT
4
+ # Copyright (C) 2025 The Computer Aided Validation Team
5
+ #===============================================================================
6
+
7
+ from .dic2d import two_dimensional
8
+ from .dicdataimport import data_import
9
+ from .dicregionofinterest import RegionOfInterest
10
+ from .dicresults import Results
11
+ from .dicstrain import strain_two_dimensional, strain_data_import
12
+ from .dicstrainresults import StrainResults
13
+
14
+ __all__ = ["two_dimensional",
15
+ "RegionOfInterest",
16
+ "data_import",
17
+ "Results",
18
+ "strain_two_dimensional",
19
+ "strain_data_import",
20
+ "StrainResults"]
@@ -6,45 +6,40 @@
6
6
 
7
7
 
8
8
 
9
- import os
10
- import io
11
- import sys
12
9
  import numpy as np
13
10
  from pathlib import Path
14
11
 
15
- import pybind11
16
-
17
- # import cython module
18
- import pyvale.dic2dcpp as dic2dcpp
19
- import pyvale.dicchecks as dicchecks
20
-
21
-
22
- def dic_2d(reference: np.ndarray | str | Path,
23
- deformed: np.ndarray | str | Path,
24
- roi_mask: np.ndarray,
25
- seed: list[int] | list[np.int32] | np.ndarray,
26
- subset_size: int = 21,
27
- subset_step: int = 10,
28
- correlation_criteria: str="ZNSSD",
29
- shape_function: str="AFFINE",
30
- interpolation_routine: str="BICUBIC",
31
- max_iterations: int=40,
32
- opt_precision: float=0.001,
33
- opt_threshold: float=0.9,
34
- bf_threshold: float=0.6,
35
- num_threads: int | None = None,
36
- max_displacement: int=128,
37
- scanning_method: str="RG",
38
- fft_mad: bool=False,
39
- fft_mad_scale: float=3.0,
40
- output_at_end: bool=False,
41
- output_basepath: Path | str = "./",
42
- output_binary: bool=False,
43
- output_prefix: str="dic_results_",
44
- output_delimiter: str=",",
45
- output_unconverged: bool=False,
46
- output_shape_params: bool=False,
47
- debug_level: int=0) -> None:
12
+ # pyvale
13
+ import pyvale.dic.dic2dcpp as dic2dcpp
14
+ import pyvale.dic.dicchecks as dicchecks
15
+
16
+
17
+ def two_dimensional(reference: np.ndarray | str | Path,
18
+ deformed: np.ndarray | str | Path,
19
+ roi_mask: np.ndarray,
20
+ seed: list[int] | list[np.int32] | np.ndarray,
21
+ subset_size: int = 21,
22
+ subset_step: int = 10,
23
+ correlation_criteria: str="ZNSSD",
24
+ shape_function: str="AFFINE",
25
+ interpolation_routine: str="BICUBIC",
26
+ max_iterations: int=40,
27
+ opt_precision: float=0.001,
28
+ opt_threshold: float=0.9,
29
+ bf_threshold: float=0.6,
30
+ num_threads: int | None = None,
31
+ max_displacement: int=128,
32
+ scanning_method: str="RG",
33
+ fft_mad: bool=False,
34
+ fft_mad_scale: float=3.0,
35
+ output_at_end: bool=False,
36
+ output_basepath: Path | str = "./",
37
+ output_binary: bool=False,
38
+ output_prefix: str="dic_results_",
39
+ output_delimiter: str=",",
40
+ output_unconverged: bool=False,
41
+ output_shape_params: bool=False,
42
+ debug_level: int=0) -> None:
48
43
 
49
44
  """
50
45
  Perform 2D Digital Image Correlation (DIC) between a reference image and one or more deformed images.
@@ -0,0 +1,6 @@
1
+ # ================================================================================
2
+ # pyvale: the python validation engine
3
+ # License: MIT
4
+ # Copyright (C) 2025 The Computer Aided Validation Team
5
+ # ================================================================================
6
+
@@ -11,8 +11,8 @@ import glob
11
11
  import os
12
12
  from pathlib import Path
13
13
 
14
- # import cython module
15
- from pyvale.dicresults import DICResults
14
+ # Pyvale modules
15
+ from pyvale.dic.dicresults import Results
16
16
 
17
17
  """
18
18
  Module responsible for handling importing of DIC results from completed
@@ -20,10 +20,10 @@ calculations.
20
20
  """
21
21
 
22
22
 
23
- def dic_data_import(data: str | Path,
23
+ def data_import(data: str | Path,
24
24
  binary: bool = False,
25
25
  layout: str = "matrix",
26
- delimiter: str = ",") -> DICResults:
26
+ delimiter: str = ",") -> Results:
27
27
  """
28
28
  Import DIC result data from human readable text or binary files.
29
29
 
@@ -46,7 +46,7 @@ def dic_data_import(data: str | Path,
46
46
 
47
47
  Returns
48
48
  -------
49
- DICResults
49
+ Results
50
50
  A named container with the following fields:
51
51
  - ss_x, ss_y (grid arrays if layout=="matrix"; otherwise, 1D integer arrays)
52
52
  - u, v, m, converged, cost, ftol, xtol, niter (arrays with shape depending on layout)
@@ -57,7 +57,7 @@ def dic_data_import(data: str | Path,
57
57
  ValueError:
58
58
  If `layout` is not "column" or "matrix", or text data has insufficient columns,
59
59
  or binary rows are malformed.
60
-
60
+ import cython module
61
61
  FileNotFoundError:
62
62
  If no matching data files are found.
63
63
  """
@@ -129,7 +129,7 @@ def dic_data_import(data: str | Path,
129
129
 
130
130
 
131
131
 
132
- return DICResults(X, Y, arrays[0], arrays[1], arrays[2], arrays[3],
132
+ return Results(X, Y, arrays[0], arrays[1], arrays[2], arrays[3],
133
133
  arrays[4], arrays[5], arrays[6], arrays[7],
134
134
  shape_params, filenames)
135
135
  # column layout
@@ -151,7 +151,7 @@ def dic_data_import(data: str | Path,
151
151
  shape_params[:,:,4] = arrays[12]
152
152
  shape_params[:,:,5] = arrays[13]
153
153
 
154
- return DICResults(ss_x_ref, ss_y_ref, arrays[0], arrays[1], arrays[2], arrays[3],
154
+ return Results(ss_x_ref, ss_y_ref, arrays[0], arrays[1], arrays[2], arrays[3],
155
155
  arrays[4], arrays[5], arrays[6], arrays[7],
156
156
  shape_params, filenames)
157
157
 
@@ -15,7 +15,7 @@ import yaml
15
15
  import os
16
16
  from pathlib import Path
17
17
 
18
- class DICRegionOfInterest:
18
+ class RegionOfInterest:
19
19
  """
20
20
  A class for interactively selecting and manipulating ROI of an image before passing to the DIC engine.
21
21
 
@@ -9,7 +9,7 @@ from dataclasses import dataclass
9
9
  import numpy as np
10
10
 
11
11
  @dataclass(slots=True)
12
- class DICResults:
12
+ class Results:
13
13
  """
14
14
  Data container for Digital Image Correlation (DIC) analysis results.
15
15
 
@@ -9,13 +9,13 @@ import numpy as np
9
9
  import glob
10
10
  from pathlib import Path
11
11
 
12
- from pyvale import dic2dcpp
13
- from pyvale import dicchecks
14
- from pyvale.dicdataimport import dic_data_import
15
- from pyvale.dicresults import DICResults
16
- from pyvale.dicstrainresults import StrainResults
12
+ # pyvale
13
+ import pyvale.dic.dic2dcpp as dic2dcpp
14
+ from pyvale.dic.dicstrainresults import StrainResults
15
+ from pyvale.dic.dicchecks import check_strain_files, check_output_directory
16
+ from pyvale.dic.dicdataimport import data_import
17
17
 
18
- def strain_2d(data: str | Path,
18
+ def strain_two_dimensional(data: str | Path,
19
19
  window_size: int=5,
20
20
  window_element: int=4,
21
21
  input_binary: bool=False,
@@ -80,10 +80,10 @@ def strain_2d(data: str | Path,
80
80
  if window_size % 2 == 0:
81
81
  raise ValueError(f"Invalid strain window size: '{window_size}'. Must be an odd number.")
82
82
 
83
- filenames = dicchecks.check_strain_files(strain_files=data)
83
+ filenames = check_strain_files(strain_files=data)
84
84
 
85
85
  # Load data if a file path is given
86
- results = dic_data_import(layout="matrix", data=str(data),
86
+ results = data_import(layout="matrix", data=str(data),
87
87
  binary=input_binary, delimiter=input_delimiter)
88
88
 
89
89
  # Extract dimensions from the validated object
@@ -92,7 +92,7 @@ def strain_2d(data: str | Path,
92
92
  nimg = results.u.shape[0]
93
93
 
94
94
 
95
- dicchecks.check_output_directory(str(output_basepath), output_prefix)
95
+ check_output_directory(str(output_basepath), output_prefix)
96
96
 
97
97
  # assigning c++ struct vals for save config
98
98
  strain_save_conf = dic2dcpp.SaveConfig()