pyvale 2025.4.0__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 (153) hide show
  1. pyvale/__init__.py +78 -64
  2. pyvale/analyticmeshgen.py +102 -0
  3. pyvale/{core/analyticsimdatafactory.py → analyticsimdatafactory.py} +44 -16
  4. pyvale/analyticsimdatagenerator.py +323 -0
  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/{core/camera.py → camera.py} +15 -15
  12. pyvale/{core/cameradata.py → cameradata.py} +27 -22
  13. pyvale/{core/cameradata2d.py → cameradata2d.py} +8 -6
  14. pyvale/camerastereo.py +217 -0
  15. pyvale/{core/cameratools.py → cameratools.py} +220 -26
  16. pyvale/{core/cython → cython}/rastercyth.py +11 -7
  17. pyvale/data/__init__.py +5 -7
  18. pyvale/data/cal_target.tiff +0 -0
  19. pyvale/data/case00_HEX20_out.e +0 -0
  20. pyvale/data/case00_HEX27_out.e +0 -0
  21. pyvale/data/case00_HEX8_out.e +0 -0
  22. pyvale/data/case00_TET10_out.e +0 -0
  23. pyvale/data/case00_TET14_out.e +0 -0
  24. pyvale/data/case00_TET4_out.e +0 -0
  25. pyvale/{core/dataset.py → dataset.py} +91 -16
  26. pyvale/{core/errorcalculator.py → errorcalculator.py} +13 -16
  27. pyvale/{core/errordriftcalc.py → errordriftcalc.py} +14 -14
  28. pyvale/{core/errorintegrator.py → errorintegrator.py} +25 -28
  29. pyvale/{core/errorrand.py → errorrand.py} +39 -46
  30. pyvale/errorsyscalib.py +134 -0
  31. pyvale/{core/errorsysdep.py → errorsysdep.py} +25 -29
  32. pyvale/{core/errorsysfield.py → errorsysfield.py} +59 -52
  33. pyvale/{core/errorsysindep.py → errorsysindep.py} +85 -182
  34. pyvale/examples/__init__.py +5 -7
  35. pyvale/examples/basics/ex1_1_basicscalars_therm2d.py +131 -0
  36. pyvale/examples/basics/ex1_2_sensormodel_therm2d.py +158 -0
  37. pyvale/examples/basics/ex1_3_customsens_therm3d.py +216 -0
  38. pyvale/examples/basics/ex1_4_basicerrors_therm3d.py +153 -0
  39. pyvale/examples/basics/ex1_5_fielderrs_therm3d.py +168 -0
  40. pyvale/examples/basics/ex1_6_caliberrs_therm2d.py +133 -0
  41. pyvale/examples/basics/ex1_7_spatavg_therm2d.py +123 -0
  42. pyvale/examples/basics/ex2_1_basicvectors_disp2d.py +112 -0
  43. pyvale/examples/basics/ex2_2_vectorsens_disp2d.py +111 -0
  44. pyvale/examples/basics/ex2_3_sensangle_disp2d.py +139 -0
  45. pyvale/examples/basics/ex2_4_chainfielderrs_disp2d.py +196 -0
  46. pyvale/examples/basics/ex2_5_vectorfields3d_disp3d.py +109 -0
  47. pyvale/examples/basics/ex3_1_basictensors_strain2d.py +114 -0
  48. pyvale/examples/basics/ex3_2_tensorsens2d_strain2d.py +111 -0
  49. pyvale/examples/basics/ex3_3_tensorsens3d_strain3d.py +182 -0
  50. pyvale/examples/basics/ex4_1_expsim2d_thermmech2d.py +171 -0
  51. pyvale/examples/basics/ex4_2_expsim3d_thermmech3d.py +252 -0
  52. pyvale/examples/{analyticdatagen → genanalyticdata}/ex1_1_scalarvisualisation.py +6 -9
  53. pyvale/examples/{analyticdatagen → genanalyticdata}/ex1_2_scalarcasebuild.py +8 -11
  54. pyvale/examples/{analyticdatagen → genanalyticdata}/ex2_1_analyticsensors.py +9 -12
  55. pyvale/examples/imagedef2d/ex_imagedef2d_todisk.py +8 -15
  56. pyvale/examples/renderblender/ex1_1_blenderscene.py +121 -0
  57. pyvale/examples/renderblender/ex1_2_blenderdeformed.py +119 -0
  58. pyvale/examples/renderblender/ex2_1_stereoscene.py +128 -0
  59. pyvale/examples/renderblender/ex2_2_stereodeformed.py +131 -0
  60. pyvale/examples/renderblender/ex3_1_blendercalibration.py +120 -0
  61. pyvale/examples/{rasterisation → renderrasterisation}/ex_rastenp.py +6 -7
  62. pyvale/examples/{rasterisation → renderrasterisation}/ex_rastercyth_oneframe.py +5 -7
  63. pyvale/examples/{rasterisation → renderrasterisation}/ex_rastercyth_static_cypara.py +6 -13
  64. pyvale/examples/{rasterisation → renderrasterisation}/ex_rastercyth_static_pypara.py +9 -12
  65. pyvale/examples/{ex1_4_thermal2d.py → visualisation/ex1_1_plot_traces.py} +33 -20
  66. pyvale/examples/{features/ex_animation_tools_3dmonoblock.py → visualisation/ex2_1_animate_sim.py} +37 -31
  67. pyvale/experimentsimulator.py +175 -0
  68. pyvale/{core/field.py → field.py} +6 -14
  69. pyvale/fieldconverter.py +351 -0
  70. pyvale/{core/fieldsampler.py → fieldsampler.py} +9 -10
  71. pyvale/{core/fieldscalar.py → fieldscalar.py} +17 -18
  72. pyvale/{core/fieldtensor.py → fieldtensor.py} +23 -26
  73. pyvale/{core/fieldtransform.py → fieldtransform.py} +9 -5
  74. pyvale/{core/fieldvector.py → fieldvector.py} +14 -16
  75. pyvale/{core/generatorsrandom.py → generatorsrandom.py} +29 -52
  76. pyvale/{core/imagedef2d.py → imagedef2d.py} +11 -8
  77. pyvale/{core/integratorfactory.py → integratorfactory.py} +12 -13
  78. pyvale/{core/integratorquadrature.py → integratorquadrature.py} +57 -32
  79. pyvale/integratorrectangle.py +165 -0
  80. pyvale/{core/integratorspatial.py → integratorspatial.py} +9 -10
  81. pyvale/{core/integratortype.py → integratortype.py} +7 -8
  82. pyvale/output.py +17 -0
  83. pyvale/pyvaleexceptions.py +11 -0
  84. pyvale/{core/raster.py → raster.py} +8 -8
  85. pyvale/{core/rastercy.py → rastercy.py} +11 -10
  86. pyvale/{core/rasternp.py → rasternp.py} +12 -13
  87. pyvale/{core/rendermesh.py → rendermesh.py} +10 -19
  88. pyvale/{core/sensorarray.py → sensorarray.py} +7 -8
  89. pyvale/{core/sensorarrayfactory.py → sensorarrayfactory.py} +64 -78
  90. pyvale/{core/sensorarraypoint.py → sensorarraypoint.py} +39 -41
  91. pyvale/{core/sensordata.py → sensordata.py} +7 -8
  92. pyvale/sensordescriptor.py +213 -0
  93. pyvale/{core/sensortools.py → sensortools.py} +8 -9
  94. pyvale/simcases/case00_HEX20.i +5 -5
  95. pyvale/simcases/case00_HEX27.i +5 -5
  96. pyvale/simcases/case00_HEX8.i +242 -0
  97. pyvale/simcases/case00_TET10.i +2 -2
  98. pyvale/simcases/case00_TET14.i +2 -2
  99. pyvale/simcases/case00_TET4.i +242 -0
  100. pyvale/simcases/run_1case.py +1 -1
  101. pyvale/simtools.py +67 -0
  102. pyvale/visualexpplotter.py +191 -0
  103. pyvale/{core/visualimagedef.py → visualimagedef.py} +13 -10
  104. pyvale/{core/visualimages.py → visualimages.py} +10 -9
  105. pyvale/visualopts.py +493 -0
  106. pyvale/{core/visualsimanimator.py → visualsimanimator.py} +47 -19
  107. pyvale/visualsimsensors.py +318 -0
  108. pyvale/visualtools.py +136 -0
  109. pyvale/visualtraceplotter.py +142 -0
  110. {pyvale-2025.4.0.dist-info → pyvale-2025.5.1.dist-info}/METADATA +17 -14
  111. pyvale-2025.5.1.dist-info/RECORD +172 -0
  112. {pyvale-2025.4.0.dist-info → pyvale-2025.5.1.dist-info}/WHEEL +1 -1
  113. pyvale/core/__init__.py +0 -7
  114. pyvale/core/analyticmeshgen.py +0 -59
  115. pyvale/core/analyticsimdatagenerator.py +0 -160
  116. pyvale/core/cython/rastercyth.c +0 -32267
  117. pyvale/core/experimentsimulator.py +0 -99
  118. pyvale/core/fieldconverter.py +0 -154
  119. pyvale/core/integratorrectangle.py +0 -88
  120. pyvale/core/optimcheckfuncs.py +0 -153
  121. pyvale/core/sensordescriptor.py +0 -101
  122. pyvale/core/visualexpplotter.py +0 -151
  123. pyvale/core/visualopts.py +0 -180
  124. pyvale/core/visualsimplotter.py +0 -182
  125. pyvale/core/visualtools.py +0 -81
  126. pyvale/core/visualtraceplotter.py +0 -256
  127. pyvale/examples/analyticdatagen/__init__.py +0 -7
  128. pyvale/examples/ex1_1_thermal2d.py +0 -89
  129. pyvale/examples/ex1_2_thermal2d.py +0 -111
  130. pyvale/examples/ex1_3_thermal2d.py +0 -113
  131. pyvale/examples/ex1_5_thermal2d.py +0 -105
  132. pyvale/examples/ex2_1_thermal3d .py +0 -87
  133. pyvale/examples/ex2_2_thermal3d.py +0 -51
  134. pyvale/examples/ex2_3_thermal3d.py +0 -109
  135. pyvale/examples/ex3_1_displacement2d.py +0 -47
  136. pyvale/examples/ex3_2_displacement2d.py +0 -79
  137. pyvale/examples/ex3_3_displacement2d.py +0 -104
  138. pyvale/examples/ex3_4_displacement2d.py +0 -105
  139. pyvale/examples/ex4_1_strain2d.py +0 -57
  140. pyvale/examples/ex4_2_strain2d.py +0 -79
  141. pyvale/examples/ex4_3_strain2d.py +0 -100
  142. pyvale/examples/ex5_1_multiphysics2d.py +0 -78
  143. pyvale/examples/ex6_1_multiphysics2d_expsim.py +0 -118
  144. pyvale/examples/ex6_2_multiphysics3d_expsim.py +0 -158
  145. pyvale/examples/features/__init__.py +0 -7
  146. pyvale/examples/features/ex_area_avg.py +0 -89
  147. pyvale/examples/features/ex_calibration_error.py +0 -108
  148. pyvale/examples/features/ex_chain_field_errs.py +0 -141
  149. pyvale/examples/features/ex_field_errs.py +0 -78
  150. pyvale/examples/features/ex_sensor_single_angle_batch.py +0 -110
  151. pyvale-2025.4.0.dist-info/RECORD +0 -157
  152. {pyvale-2025.4.0.dist-info → pyvale-2025.5.1.dist-info}/licenses/LICENSE +0 -0
  153. {pyvale-2025.4.0.dist-info → pyvale-2025.5.1.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,242 @@
1
+ #-------------------------------------------------------------------------
2
+ # pyvale: single element test 3D
3
+ #-------------------------------------------------------------------------
4
+
5
+ #-------------------------------------------------------------------------
6
+ #_* MOOSEHERDER VARIABLES - START
7
+
8
+ endTime = 20
9
+ timeStep = 1
10
+
11
+ # Geometric Properties
12
+ lengX = 10e-3 # m
13
+ lengY = 10e-3 # m
14
+ lengZ = 10e-3 # m
15
+
16
+ # Mesh Properties
17
+ nElemX = 2
18
+ nElemY = 2
19
+ nElemZ = 2
20
+ eType = HEX8 # TET4, TET10, TET11, HEX8, HEX20, HEX27
21
+
22
+ # Thermal BCs
23
+ coolantTemp=100.0 # degC
24
+ heatTransCoeff=125.0e3 # W.m^-2.K^-1
25
+ surfHeatFlux=4.67e6 # W.m^-2, taken from Adel's first paper
26
+ timeConst = 1 # s
27
+
28
+ # Mechanical Loads/BCs
29
+ topDispRate = ${fparse 1e-3 / endTime} # m/s
30
+
31
+ # Thermal Props:
32
+ Density = 8829.0 # kg.m^-3
33
+ ThermCond = 384.0 # W.m^-1.K^-1
34
+ SpecHeat = 406.0 # J.kg^-1.K^-1
35
+
36
+ # Material Properties:
37
+ EMod= 100e9 # Pa
38
+ PRatio = 0.33 # -
39
+
40
+ # Thermo-mechanical coupling
41
+ stressFreeTemp = 20 # degC
42
+ ThermExp = 17.8e-6 # 1/degC
43
+
44
+ #** MOOSEHERDER VARIABLES - END
45
+ #-------------------------------------------------------------------------
46
+
47
+ [GlobalParams]
48
+ displacements = 'disp_x disp_y disp_z'
49
+ []
50
+
51
+ [Mesh]
52
+ [generated]
53
+ type = GeneratedMeshGenerator
54
+ dim = 3
55
+ nx = ${nElemX}
56
+ ny = ${nElemY}
57
+ nz = ${nElemZ}
58
+ xmax = ${lengX}
59
+ ymax = ${lengY}
60
+ zmax = ${lengZ}
61
+ elem_type = ${eType}
62
+ []
63
+ []
64
+
65
+ [Variables]
66
+ [temperature]
67
+ family = LAGRANGE
68
+ order = FIRST
69
+ initial_condition = ${coolantTemp}
70
+ []
71
+ []
72
+
73
+ [Kernels]
74
+ [heat_conduction]
75
+ type = HeatConduction
76
+ variable = temperature
77
+ []
78
+ [time_derivative]
79
+ type = HeatConductionTimeDerivative
80
+ variable = temperature
81
+ []
82
+ []
83
+
84
+
85
+ [Physics/SolidMechanics/QuasiStatic]
86
+ [all]
87
+ strain = SMALL
88
+ incremental = true
89
+ add_variables = true
90
+ material_output_family = MONOMIAL # MONOMIAL, LAGRANGE
91
+ material_output_order = FIRST # CONSTANT, FIRST, SECOND,
92
+ generate_output = 'strain_xx strain_yy strain_zz strain_xy strain_yz strain_xz'
93
+ []
94
+ []
95
+
96
+ [BCs]
97
+ [heat_flux_in]
98
+ type = FunctionNeumannBC
99
+ variable = temperature
100
+ boundary = 'top'
101
+ function = '${fparse surfHeatFlux}*(1-exp(-(1/${timeConst})*t))'
102
+ []
103
+ [heat_flux_out]
104
+ type = ConvectiveHeatFluxBC
105
+ variable = temperature
106
+ boundary = 'bottom'
107
+ T_infinity = ${coolantTemp}
108
+ heat_transfer_coefficient = ${heatTransCoeff}
109
+ []
110
+
111
+ [bottom_x]
112
+ type = DirichletBC
113
+ variable = disp_x
114
+ boundary = 'bottom'
115
+ value = 0.0
116
+ []
117
+ [bottom_y]
118
+ type = DirichletBC
119
+ variable = disp_y
120
+ boundary = 'bottom'
121
+ value = 0.0
122
+ []
123
+ [bottom_z]
124
+ type = DirichletBC
125
+ variable = disp_z
126
+ boundary = 'bottom'
127
+ value = 0.0
128
+ []
129
+ [top_x]
130
+ type = DirichletBC
131
+ variable = disp_x
132
+ boundary = 'top'
133
+ value = 0.0
134
+ []
135
+ [top_y]
136
+ type = FunctionDirichletBC
137
+ variable = disp_y
138
+ boundary = 'top'
139
+ function = '${topDispRate}*t'
140
+ []
141
+ [top_z]
142
+ type = DirichletBC
143
+ variable = disp_z
144
+ boundary = 'top'
145
+ value = 0.0
146
+ []
147
+ []
148
+
149
+ [Materials]
150
+ [mat_thermal]
151
+ type = HeatConductionMaterial
152
+ thermal_conductivity = ${ThermCond}
153
+ specific_heat = ${SpecHeat}
154
+ []
155
+ [mat_density]
156
+ type = GenericConstantMaterial
157
+ prop_names = 'density'
158
+ prop_values = ${Density}
159
+ []
160
+ [mat_expansion]
161
+ type = ComputeThermalExpansionEigenstrain
162
+ temperature = temperature
163
+ stress_free_temperature = ${stressFreeTemp}
164
+ thermal_expansion_coeff = ${ThermExp}
165
+ eigenstrain_name = thermal_expansion_eigenstrain
166
+ []
167
+
168
+ [mat_elasticity]
169
+ type = ComputeIsotropicElasticityTensor
170
+ youngs_modulus = ${EMod}
171
+ poissons_ratio = ${PRatio}
172
+ []
173
+ [stress]
174
+ type = ComputeFiniteStrainElasticStress
175
+ []
176
+ []
177
+
178
+ [Preconditioning]
179
+ [SMP]
180
+ type = SMP
181
+ full = true
182
+ []
183
+ []
184
+
185
+ [Executioner]
186
+ type = Transient
187
+
188
+ solve_type = 'NEWTON'
189
+ petsc_options = '-snes_converged_reason'
190
+ petsc_options_iname = '-pc_type -pc_hypre_type'
191
+ petsc_options_value = 'hypre boomeramg'
192
+
193
+ l_max_its = 1000
194
+ l_tol = 1e-6
195
+
196
+ nl_max_its = 50
197
+ nl_rel_tol = 1e-6
198
+ nl_abs_tol = 1e-6
199
+
200
+ start_time=0.0
201
+ end_time = ${endTime}
202
+ dt = ${timeStep}
203
+
204
+ [Predictor]
205
+ type = SimplePredictor
206
+ scale = 1
207
+ []
208
+ []
209
+
210
+
211
+ [Postprocessors]
212
+ [react_y_bot]
213
+ type = SidesetReaction
214
+ direction = '0 1 0'
215
+ stress_tensor = stress
216
+ boundary = 'bottom'
217
+ []
218
+ [react_y_top]
219
+ type = SidesetReaction
220
+ direction = '0 1 0'
221
+ stress_tensor = stress
222
+ boundary = 'top'
223
+ []
224
+
225
+ [disp_y_max]
226
+ type = NodalExtremeValue
227
+ variable = disp_y
228
+ []
229
+ [disp_x_max]
230
+ type = NodalExtremeValue
231
+ variable = disp_x
232
+ []
233
+ [disp_z_max]
234
+ type = NodalExtremeValue
235
+ variable = disp_z
236
+ []
237
+
238
+ []
239
+
240
+ [Outputs]
241
+ exodus = true
242
+ []
@@ -5,7 +5,7 @@
5
5
  #-------------------------------------------------------------------------
6
6
  #_* MOOSEHERDER VARIABLES - START
7
7
 
8
- endTime = 50
8
+ endTime = 20
9
9
  timeStep = 1
10
10
 
11
11
  # Geometric Properties
@@ -89,7 +89,7 @@ ThermExp = 17.8e-6 # 1/degC
89
89
  add_variables = true
90
90
  material_output_family = MONOMIAL # MONOMIAL, LAGRANGE
91
91
  material_output_order = FIRST # CONSTANT, FIRST, SECOND,
92
- generate_output = 'stress_xx stress_yy stress_zz stress_xy stress_yz stress_xz strain_xx strain_yy strain_zz strain_xy strain_yz strain_xz'
92
+ generate_output = 'strain_xx strain_yy strain_zz strain_xy strain_yz strain_xz'
93
93
  []
94
94
  []
95
95
 
@@ -5,7 +5,7 @@
5
5
  #-------------------------------------------------------------------------
6
6
  #_* MOOSEHERDER VARIABLES - START
7
7
 
8
- endTime = 50
8
+ endTime = 20
9
9
  timeStep = 1
10
10
 
11
11
  # Geometric Properties
@@ -89,7 +89,7 @@ ThermExp = 17.8e-6 # 1/degC
89
89
  add_variables = true
90
90
  material_output_family = MONOMIAL # MONOMIAL, LAGRANGE
91
91
  material_output_order = FIRST # CONSTANT, FIRST, SECOND,
92
- generate_output = 'stress_xx stress_yy stress_zz stress_xy stress_yz stress_xz strain_xx strain_yy strain_zz strain_xy strain_yz strain_xz'
92
+ generate_output = 'strain_xx strain_yy strain_zz strain_xy strain_yz strain_xz'
93
93
  []
94
94
  []
95
95
 
@@ -0,0 +1,242 @@
1
+ #-------------------------------------------------------------------------
2
+ # pyvale: single element test 3D
3
+ #-------------------------------------------------------------------------
4
+
5
+ #-------------------------------------------------------------------------
6
+ #_* MOOSEHERDER VARIABLES - START
7
+
8
+ endTime = 20
9
+ timeStep = 1
10
+
11
+ # Geometric Properties
12
+ lengX = 10e-3 # m
13
+ lengY = 10e-3 # m
14
+ lengZ = 10e-3 # m
15
+
16
+ # Mesh Properties
17
+ nElemX = 1
18
+ nElemY = 1
19
+ nElemZ = 1
20
+ eType = TET4 # TET4, TET10, TET11, HEX8, HEX20, HEX27
21
+
22
+ # Thermal BCs
23
+ coolantTemp=100.0 # degC
24
+ heatTransCoeff=125.0e3 # W.m^-2.K^-1
25
+ surfHeatFlux=4.67e6 # W.m^-2, taken from Adel's first paper
26
+ timeConst = 1 # s
27
+
28
+ # Mechanical Loads/BCs
29
+ topDispRate = ${fparse 1e-3 / endTime} # m/s
30
+
31
+ # Thermal Props:
32
+ Density = 8829.0 # kg.m^-3
33
+ ThermCond = 384.0 # W.m^-1.K^-1
34
+ SpecHeat = 406.0 # J.kg^-1.K^-1
35
+
36
+ # Material Properties:
37
+ EMod= 100e9 # Pa
38
+ PRatio = 0.33 # -
39
+
40
+ # Thermo-mechanical coupling
41
+ stressFreeTemp = 20 # degC
42
+ ThermExp = 17.8e-6 # 1/degC
43
+
44
+ #** MOOSEHERDER VARIABLES - END
45
+ #-------------------------------------------------------------------------
46
+
47
+ [GlobalParams]
48
+ displacements = 'disp_x disp_y disp_z'
49
+ []
50
+
51
+ [Mesh]
52
+ [generated]
53
+ type = GeneratedMeshGenerator
54
+ dim = 3
55
+ nx = ${nElemX}
56
+ ny = ${nElemY}
57
+ nz = ${nElemZ}
58
+ xmax = ${lengX}
59
+ ymax = ${lengY}
60
+ zmax = ${lengZ}
61
+ elem_type = ${eType}
62
+ []
63
+ []
64
+
65
+ [Variables]
66
+ [temperature]
67
+ family = LAGRANGE
68
+ order = FIRST
69
+ initial_condition = ${coolantTemp}
70
+ []
71
+ []
72
+
73
+ [Kernels]
74
+ [heat_conduction]
75
+ type = HeatConduction
76
+ variable = temperature
77
+ []
78
+ [time_derivative]
79
+ type = HeatConductionTimeDerivative
80
+ variable = temperature
81
+ []
82
+ []
83
+
84
+
85
+ [Physics/SolidMechanics/QuasiStatic]
86
+ [all]
87
+ strain = SMALL
88
+ incremental = true
89
+ add_variables = true
90
+ material_output_family = MONOMIAL # MONOMIAL, LAGRANGE
91
+ material_output_order = FIRST # CONSTANT, FIRST, SECOND,
92
+ generate_output = 'strain_xx strain_yy strain_zz strain_xy strain_yz strain_xz'
93
+ []
94
+ []
95
+
96
+ [BCs]
97
+ [heat_flux_in]
98
+ type = FunctionNeumannBC
99
+ variable = temperature
100
+ boundary = 'top'
101
+ function = '${fparse surfHeatFlux}*(1-exp(-(1/${timeConst})*t))'
102
+ []
103
+ [heat_flux_out]
104
+ type = ConvectiveHeatFluxBC
105
+ variable = temperature
106
+ boundary = 'bottom'
107
+ T_infinity = ${coolantTemp}
108
+ heat_transfer_coefficient = ${heatTransCoeff}
109
+ []
110
+
111
+ [bottom_x]
112
+ type = DirichletBC
113
+ variable = disp_x
114
+ boundary = 'bottom'
115
+ value = 0.0
116
+ []
117
+ [bottom_y]
118
+ type = DirichletBC
119
+ variable = disp_y
120
+ boundary = 'bottom'
121
+ value = 0.0
122
+ []
123
+ [bottom_z]
124
+ type = DirichletBC
125
+ variable = disp_z
126
+ boundary = 'bottom'
127
+ value = 0.0
128
+ []
129
+ [top_x]
130
+ type = DirichletBC
131
+ variable = disp_x
132
+ boundary = 'top'
133
+ value = 0.0
134
+ []
135
+ [top_y]
136
+ type = FunctionDirichletBC
137
+ variable = disp_y
138
+ boundary = 'top'
139
+ function = '${topDispRate}*t'
140
+ []
141
+ [top_z]
142
+ type = DirichletBC
143
+ variable = disp_z
144
+ boundary = 'top'
145
+ value = 0.0
146
+ []
147
+ []
148
+
149
+ [Materials]
150
+ [mat_thermal]
151
+ type = HeatConductionMaterial
152
+ thermal_conductivity = ${ThermCond}
153
+ specific_heat = ${SpecHeat}
154
+ []
155
+ [mat_density]
156
+ type = GenericConstantMaterial
157
+ prop_names = 'density'
158
+ prop_values = ${Density}
159
+ []
160
+ [mat_expansion]
161
+ type = ComputeThermalExpansionEigenstrain
162
+ temperature = temperature
163
+ stress_free_temperature = ${stressFreeTemp}
164
+ thermal_expansion_coeff = ${ThermExp}
165
+ eigenstrain_name = thermal_expansion_eigenstrain
166
+ []
167
+
168
+ [mat_elasticity]
169
+ type = ComputeIsotropicElasticityTensor
170
+ youngs_modulus = ${EMod}
171
+ poissons_ratio = ${PRatio}
172
+ []
173
+ [stress]
174
+ type = ComputeFiniteStrainElasticStress
175
+ []
176
+ []
177
+
178
+ [Preconditioning]
179
+ [SMP]
180
+ type = SMP
181
+ full = true
182
+ []
183
+ []
184
+
185
+ [Executioner]
186
+ type = Transient
187
+
188
+ solve_type = 'NEWTON'
189
+ petsc_options = '-snes_converged_reason'
190
+ petsc_options_iname = '-pc_type -pc_hypre_type'
191
+ petsc_options_value = 'hypre boomeramg'
192
+
193
+ l_max_its = 1000
194
+ l_tol = 1e-6
195
+
196
+ nl_max_its = 50
197
+ nl_rel_tol = 1e-6
198
+ nl_abs_tol = 1e-6
199
+
200
+ start_time=0.0
201
+ end_time = ${endTime}
202
+ dt = ${timeStep}
203
+
204
+ [Predictor]
205
+ type = SimplePredictor
206
+ scale = 1
207
+ []
208
+ []
209
+
210
+
211
+ [Postprocessors]
212
+ [react_y_bot]
213
+ type = SidesetReaction
214
+ direction = '0 1 0'
215
+ stress_tensor = stress
216
+ boundary = 'bottom'
217
+ []
218
+ [react_y_top]
219
+ type = SidesetReaction
220
+ direction = '0 1 0'
221
+ stress_tensor = stress
222
+ boundary = 'top'
223
+ []
224
+
225
+ [disp_y_max]
226
+ type = NodalExtremeValue
227
+ variable = disp_y
228
+ []
229
+ [disp_x_max]
230
+ type = NodalExtremeValue
231
+ variable = disp_x
232
+ []
233
+ [disp_z_max]
234
+ type = NodalExtremeValue
235
+ variable = disp_z
236
+ []
237
+
238
+ []
239
+
240
+ [Outputs]
241
+ exodus = true
242
+ []
@@ -15,7 +15,7 @@ from mooseherder import (MooseConfig,
15
15
 
16
16
  #===============================================================================
17
17
  # Change this to run a different case
18
- CASE_STR = 'case16'
18
+ CASE_STR = 'case00_HEX27'
19
19
  #===============================================================================
20
20
 
21
21
  CASE_FILES = (CASE_STR+'.geo',CASE_STR+'.i')
pyvale/simtools.py ADDED
@@ -0,0 +1,67 @@
1
+ # ==============================================================================
2
+ # pyvale: the python validation engine
3
+ # License: MIT
4
+ # Copyright (C) 2025 The Computer Aided Validation Team
5
+ # ==============================================================================
6
+ import numpy as np
7
+ from pyvale.rendermesh import RenderMeshData
8
+
9
+ class SimTools:
10
+ """Namespace for tools required for analysing simulation results.
11
+ """
12
+
13
+ @staticmethod
14
+ def centre_mesh_nodes(nodes: np.ndarray, spat_dim: int) -> np.ndarray:
15
+ """A method to centre the nodes of a mesh around the origin.
16
+
17
+ Parameters
18
+ ----------
19
+ nodes : np.ndarray
20
+ An array containing the node locations of the mesh.
21
+ spat_dim : int
22
+ The spatial dimension of the mesh.
23
+
24
+ Returns
25
+ -------
26
+ np.ndarray
27
+ An array containing the mesh node locations, but centred around
28
+ the origin.
29
+ """
30
+ max = np.max(nodes, axis=0)
31
+ min = np.min(nodes, axis=0)
32
+ middle = max - ((max - min) / 2)
33
+ if spat_dim == 3:
34
+ middle[2] = 0
35
+ centred = np.subtract(nodes, middle)
36
+ return centred
37
+
38
+ @staticmethod
39
+ def get_deformed_nodes(timestep: int,
40
+ render_mesh: RenderMeshData) -> np.ndarray | None:
41
+ """A method to obtain the deformed locations of all the nodes at a given
42
+ timestep.
43
+
44
+ Parameters
45
+ ----------
46
+ timestep : int
47
+ The timestep at which to find the deformed nodes.
48
+ render_mesh: RenderMeshData
49
+ A dataclass containing the skinned mesh and simulation results.
50
+
51
+ Returns
52
+ -------
53
+ np.ndarray | None
54
+ An array containing the deformed values of all the components at
55
+ each node location. Returns None if there are no deformation values.
56
+ """
57
+ if render_mesh.fields_disp is None:
58
+ return None
59
+
60
+ added_disp = render_mesh.fields_disp[:, timestep]
61
+ if added_disp.shape[1] == 2:
62
+ added_disp = np.hstack((added_disp,np.zeros([added_disp.shape[0],1])))
63
+ coords = np.delete(render_mesh.coords, 3, axis=1)
64
+ deformed_nodes = coords + added_disp
65
+ return deformed_nodes
66
+
67
+