pyvale 2025.4.0__py3-none-any.whl → 2025.4.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 (98) hide show
  1. pyvale/__init__.py +51 -52
  2. pyvale/analyticmeshgen.py +101 -0
  3. pyvale/{core/analyticsimdatafactory.py → analyticsimdatafactory.py} +32 -9
  4. pyvale/{core/analyticsimdatagenerator.py → analyticsimdatagenerator.py} +151 -21
  5. pyvale/{core/camera.py → camera.py} +13 -14
  6. pyvale/{core/cameradata.py → cameradata.py} +6 -19
  7. pyvale/{core/cameradata2d.py → cameradata2d.py} +7 -7
  8. pyvale/{core/cameratools.py → cameratools.py} +18 -19
  9. pyvale/{core/cython → cython}/rastercyth.py +9 -9
  10. pyvale/data/__init__.py +5 -7
  11. pyvale/data/case00_HEX20_out.e +0 -0
  12. pyvale/data/case00_HEX27_out.e +0 -0
  13. pyvale/data/case00_HEX8_out.e +0 -0
  14. pyvale/data/case00_TET10_out.e +0 -0
  15. pyvale/data/case00_TET14_out.e +0 -0
  16. pyvale/data/case00_TET4_out.e +0 -0
  17. pyvale/{core/dataset.py → dataset.py} +24 -8
  18. pyvale/{core/errorcalculator.py → errorcalculator.py} +7 -8
  19. pyvale/{core/errordriftcalc.py → errordriftcalc.py} +6 -7
  20. pyvale/{core/errorintegrator.py → errorintegrator.py} +8 -9
  21. pyvale/{core/errorrand.py → errorrand.py} +9 -10
  22. pyvale/{core/errorsysdep.py → errorsysdep.py} +8 -9
  23. pyvale/{core/errorsysfield.py → errorsysfield.py} +13 -14
  24. pyvale/{core/errorsysindep.py → errorsysindep.py} +9 -10
  25. pyvale/examples/__init__.py +5 -7
  26. pyvale/examples/analyticdatagen/__init__.py +5 -7
  27. pyvale/examples/ex1_1_thermal2d.py +6 -9
  28. pyvale/examples/ex1_2_thermal2d.py +6 -9
  29. pyvale/examples/ex1_3_thermal2d.py +6 -9
  30. pyvale/examples/ex1_4_thermal2d.py +6 -9
  31. pyvale/examples/ex1_5_thermal2d.py +6 -9
  32. pyvale/examples/ex2_1_thermal3d .py +6 -9
  33. pyvale/examples/ex2_3_thermal3d.py +6 -9
  34. pyvale/examples/ex3_1_displacement2d.py +6 -9
  35. pyvale/examples/ex3_2_displacement2d.py +5 -8
  36. pyvale/examples/ex3_3_displacement2d.py +6 -9
  37. pyvale/examples/ex3_4_displacement2d.py +6 -9
  38. pyvale/examples/ex4_1_strain2d.py +6 -9
  39. pyvale/examples/ex4_2_strain2d.py +5 -8
  40. pyvale/examples/ex4_3_strain2d.py +6 -9
  41. pyvale/examples/ex5_1_multiphysics2d.py +5 -8
  42. pyvale/examples/ex6_1_multiphysics2d_expsim.py +6 -9
  43. pyvale/examples/ex6_2_multiphysics3d_expsim.py +15 -13
  44. pyvale/examples/features/__init__.py +5 -7
  45. pyvale/examples/rasterisation/ex_rastenp.py +5 -7
  46. pyvale/examples/rasterisation/ex_rastercyth_oneframe.py +5 -7
  47. pyvale/examples/rasterisation/ex_rastercyth_static_cypara.py +5 -7
  48. pyvale/examples/rasterisation/ex_rastercyth_static_pypara.py +5 -7
  49. pyvale/{core/experimentsimulator.py → experimentsimulator.py} +7 -8
  50. pyvale/{core/field.py → field.py} +6 -7
  51. pyvale/{core/fieldconverter.py → fieldconverter.py} +138 -17
  52. pyvale/{core/fieldsampler.py → fieldsampler.py} +9 -10
  53. pyvale/{core/fieldscalar.py → fieldscalar.py} +9 -10
  54. pyvale/{core/fieldtensor.py → fieldtensor.py} +10 -11
  55. pyvale/{core/fieldtransform.py → fieldtransform.py} +6 -7
  56. pyvale/{core/fieldvector.py → fieldvector.py} +10 -11
  57. pyvale/{core/generatorsrandom.py → generatorsrandom.py} +6 -7
  58. pyvale/{core/imagedef2d.py → imagedef2d.py} +9 -10
  59. pyvale/{core/integratorfactory.py → integratorfactory.py} +12 -13
  60. pyvale/{core/integratorquadrature.py → integratorquadrature.py} +9 -10
  61. pyvale/{core/integratorrectangle.py → integratorrectangle.py} +9 -10
  62. pyvale/{core/integratorspatial.py → integratorspatial.py} +7 -8
  63. pyvale/{core/integratortype.py → integratortype.py} +6 -7
  64. pyvale/{core/optimcheckfuncs.py → optimcheckfuncs.py} +1 -1
  65. pyvale/{core/raster.py → raster.py} +6 -7
  66. pyvale/{core/rastercy.py → rastercy.py} +9 -10
  67. pyvale/{core/rasternp.py → rasternp.py} +10 -13
  68. pyvale/{core/rendermesh.py → rendermesh.py} +8 -21
  69. pyvale/{core/sensorarray.py → sensorarray.py} +7 -8
  70. pyvale/{core/sensorarrayfactory.py → sensorarrayfactory.py} +15 -16
  71. pyvale/{core/sensorarraypoint.py → sensorarraypoint.py} +12 -13
  72. pyvale/{core/sensordata.py → sensordata.py} +7 -8
  73. pyvale/{core/sensordescriptor.py → sensordescriptor.py} +6 -7
  74. pyvale/{core/sensortools.py → sensortools.py} +7 -8
  75. pyvale/simcases/case00_HEX20.i +5 -5
  76. pyvale/simcases/case00_HEX27.i +5 -5
  77. pyvale/simcases/case00_HEX8.i +242 -0
  78. pyvale/simcases/case00_TET10.i +2 -2
  79. pyvale/simcases/case00_TET14.i +2 -2
  80. pyvale/simcases/case00_TET4.i +242 -0
  81. pyvale/simcases/run_1case.py +1 -1
  82. pyvale/{core/visualexpplotter.py → visualexpplotter.py} +8 -10
  83. pyvale/{core/visualimagedef.py → visualimagedef.py} +6 -7
  84. pyvale/{core/visualimages.py → visualimages.py} +8 -9
  85. pyvale/{core/visualopts.py → visualopts.py} +6 -7
  86. pyvale/{core/visualsimanimator.py → visualsimanimator.py} +10 -11
  87. pyvale/{core/visualsimplotter.py → visualsimplotter.py} +30 -30
  88. pyvale/{core/visualtools.py → visualtools.py} +7 -8
  89. pyvale/{core/visualtraceplotter.py → visualtraceplotter.py} +9 -10
  90. {pyvale-2025.4.0.dist-info → pyvale-2025.4.1.dist-info}/METADATA +1 -1
  91. pyvale-2025.4.1.dist-info/RECORD +163 -0
  92. {pyvale-2025.4.0.dist-info → pyvale-2025.4.1.dist-info}/WHEEL +1 -1
  93. pyvale/core/__init__.py +0 -7
  94. pyvale/core/analyticmeshgen.py +0 -59
  95. pyvale/core/cython/rastercyth.c +0 -32267
  96. pyvale-2025.4.0.dist-info/RECORD +0 -157
  97. {pyvale-2025.4.0.dist-info → pyvale-2025.4.1.dist-info}/licenses/LICENSE +0 -0
  98. {pyvale-2025.4.0.dist-info → pyvale-2025.4.1.dist-info}/top_level.txt +0 -0
@@ -1,12 +1,9 @@
1
- '''
2
- ================================================================================
3
- Example: strain sensors on a 2d plate
4
-
5
- pyvale: the python validation engine
6
- License: MIT
7
- Copyright (C) 2025 The Computer Aided Validation Team
8
- ================================================================================
9
- '''
1
+ # ================================================================================
2
+ # pyvale: the python validation engine
3
+ # License: MIT
4
+ # Copyright (C) 2025 The Computer Aided Validation Team
5
+ # ================================================================================
6
+
10
7
  import numpy as np
11
8
  import matplotlib.pyplot as plt
12
9
  from scipy.spatial.transform import Rotation as R
@@ -1,12 +1,9 @@
1
- '''
2
- ================================================================================
3
- Example: thermo-mechanical multiphysics on 2D plate
1
+ # ================================================================================
2
+ # pyvale: the python validation engine
3
+ # License: MIT
4
+ # Copyright (C) 2025 The Computer Aided Validation Team
5
+ # ================================================================================
4
6
 
5
- pyvale: the python validation engine
6
- License: MIT
7
- Copyright (C) 2025 The Computer Aided Validation Team
8
- ================================================================================
9
- '''
10
7
  import numpy as np
11
8
  import matplotlib.pyplot as plt
12
9
  import mooseherder as mh
@@ -1,12 +1,9 @@
1
- '''
2
- ================================================================================
3
- Example: thermo-mechanical multiphysics on a 2D plate
4
-
5
- pyvale: the python validation engine
6
- License: MIT
7
- Copyright (C) 2025 The Computer Aided Validation Team
8
- ================================================================================
9
- '''
1
+ # ================================================================================
2
+ # pyvale: the python validation engine
3
+ # License: MIT
4
+ # Copyright (C) 2025 The Computer Aided Validation Team
5
+ # ================================================================================
6
+
10
7
  import numpy as np
11
8
  import matplotlib.pyplot as plt
12
9
  import mooseherder as mh
@@ -1,12 +1,9 @@
1
- '''
2
- ================================================================================
3
- Example: thermo-mechanical multiphysics on a divertor armour heatsink
4
-
5
- pyvale: the python validation engine
6
- License: MIT
7
- Copyright (C) 2025 The Computer Aided Validation Team
8
- ================================================================================
9
- '''
1
+ # ================================================================================
2
+ # pyvale: the python validation engine
3
+ # License: MIT
4
+ # Copyright (C) 2025 The Computer Aided Validation Team
5
+ # ================================================================================
6
+
10
7
  from pathlib import Path
11
8
  import numpy as np
12
9
  import matplotlib.pyplot as plt
@@ -33,6 +30,7 @@ def main() -> None:
33
30
  else:
34
31
  sample_times = np.linspace(0.0,np.max(sim_data.time),50)
35
32
 
33
+ save_figs = False
36
34
  save_tag = "thermomech3d"
37
35
  fig_save_path = Path.cwd()/"images"
38
36
  if not fig_save_path.is_dir():
@@ -62,7 +60,8 @@ def main() -> None:
62
60
  pv_plot.camera_position = [(59.354, 43.428, 69.946),
63
61
  (-2.858, 13.189, 4.523),
64
62
  (-0.215, 0.948, -0.233)]
65
- pv_plot.save_graphic(fig_save_path/(save_tag+"_tc_vis.svg"))
63
+ if save_figs:
64
+ pv_plot.save_graphic(fig_save_path/(save_tag+"_tc_vis.svg"))
66
65
  pv_plot.show()
67
66
 
68
67
  #---------------------------------------------------------------------------
@@ -90,7 +89,8 @@ def main() -> None:
90
89
  pv_plot.camera_position = [(59.354, 43.428, 69.946),
91
90
  (-2.858, 13.189, 4.523),
92
91
  (-0.215, 0.948, -0.233)]
93
- pv_plot.save_graphic(fig_save_path/(save_tag+"_sg_vis.svg"))
92
+ if save_figs:
93
+ pv_plot.save_graphic(fig_save_path/(save_tag+"_sg_vis.svg"))
94
94
  pv_plot.show()
95
95
 
96
96
  #---------------------------------------------------------------------------
@@ -141,7 +141,8 @@ def main() -> None:
141
141
  sens_array_num=0,
142
142
  sim_num=0,
143
143
  trace_opts=trace_opts)
144
- fig.savefig(fig_save_path/(save_tag+"_tc_traces.png"),
144
+ if save_figs:
145
+ fig.savefig(fig_save_path/(save_tag+"_tc_traces.png"),
145
146
  dpi=300, format='png', bbox_inches='tight')
146
147
 
147
148
  (fig,ax) = pyv.plot_exp_traces(exp_sim,
@@ -149,7 +150,8 @@ def main() -> None:
149
150
  sens_array_num=1,
150
151
  sim_num=0,
151
152
  trace_opts=trace_opts)
152
- fig.savefig(fig_save_path/(save_tag+"_sg_traces.png"),
153
+ if save_figs:
154
+ fig.savefig(fig_save_path/(save_tag+"_sg_traces.png"),
153
155
  dpi=300, format='png', bbox_inches='tight')
154
156
  plt.show()
155
157
 
@@ -1,7 +1,5 @@
1
- """
2
- ================================================================================
3
- pyvale: the python validation engine
4
- License: MIT
5
- Copyright (C) 2025 The Computer Aided Validation Team
6
- ================================================================================
7
- """
1
+ #===============================================================================
2
+ # pyvale: the python validation engine
3
+ # License: MIT
4
+ # Copyright (C) 2025 The Computer Aided Validation Team
5
+ #===============================================================================
@@ -1,10 +1,8 @@
1
- """
2
- ================================================================================
3
- pyvale: the python validation engine
4
- License: MIT
5
- Copyright (C) 2025 The Computer Aided Validation Team
6
- ================================================================================
7
- """
1
+ #===============================================================================
2
+ # pyvale: the python validation engine
3
+ # License: MIT
4
+ # Copyright (C) 2025 The Computer Aided Validation Team
5
+ #===============================================================================
8
6
  from pathlib import Path
9
7
  import time
10
8
  import numpy as np
@@ -1,10 +1,8 @@
1
- """
2
- ================================================================================
3
- pyvale: the python validation engine
4
- License: MIT
5
- Copyright (C) 2025 The Computer Aided Validation Team
6
- ================================================================================
7
- """
1
+ #===============================================================================
2
+ # pyvale: the python validation engine
3
+ # License: MIT
4
+ # Copyright (C) 2025 The Computer Aided Validation Team
5
+ #===============================================================================
8
6
 
9
7
  import time
10
8
  import numpy as np
@@ -1,10 +1,8 @@
1
- """
2
- ================================================================================
3
- pyvale: the python validation engine
4
- License: MIT
5
- Copyright (C) 2025 The Computer Aided Validation Team
6
- ================================================================================
7
- """
1
+ #===============================================================================
2
+ # pyvale: the python validation engine
3
+ # License: MIT
4
+ # Copyright (C) 2025 The Computer Aided Validation Team
5
+ #===============================================================================
8
6
  from pathlib import Path
9
7
  import time
10
8
  import numpy as np
@@ -1,10 +1,8 @@
1
- """
2
- ================================================================================
3
- pyvale: the python validation engine
4
- License: MIT
5
- Copyright (C) 2025 The Computer Aided Validation Team
6
- ================================================================================
7
- """
1
+ #===============================================================================
2
+ # pyvale: the python validation engine
3
+ # License: MIT
4
+ # Copyright (C) 2025 The Computer Aided Validation Team
5
+ #===============================================================================
8
6
  from pathlib import Path
9
7
  import time
10
8
  import numpy as np
@@ -1,13 +1,12 @@
1
- """
2
- ================================================================================
3
- pyvale: the python validation engine
4
- License: MIT
5
- Copyright (C) 2025 The Computer Aided Validation Team
6
- ================================================================================
7
- """
1
+ # ================================================================================
2
+ # pyvale: the python validation engine
3
+ # License: MIT
4
+ # Copyright (C) 2025 The Computer Aided Validation Team
5
+ # ================================================================================
6
+
8
7
  from dataclasses import dataclass
9
8
  import numpy as np
10
- from pyvale.core.sensorarray import ISensorArray
9
+ from pyvale.sensorarray import ISensorArray
11
10
  import mooseherder as mh
12
11
 
13
12
  # NOTE: This module is a feature under developement.
@@ -1,10 +1,9 @@
1
- """
2
- ================================================================================
3
- pyvale: the python validation engine
4
- License: MIT
5
- Copyright (C) 2025 The Computer Aided Validation Team
6
- ================================================================================
7
- """
1
+ # ================================================================================
2
+ # pyvale: the python validation engine
3
+ # License: MIT
4
+ # Copyright (C) 2025 The Computer Aided Validation Team
5
+ # ================================================================================
6
+
8
7
  from abc import ABC, abstractmethod
9
8
  import numpy as np
10
9
  from scipy.spatial.transform import Rotation
@@ -1,10 +1,9 @@
1
- """
2
- ================================================================================
3
- pyvale: the python validation engine
4
- License: MIT
5
- Copyright (C) 2025 The Computer Aided Validation Team
6
- ================================================================================
7
- """
1
+ # ================================================================================
2
+ # pyvale: the python validation engine
3
+ # License: MIT
4
+ # Copyright (C) 2025 The Computer Aided Validation Team
5
+ # ================================================================================
6
+
8
7
  import warnings
9
8
  import numpy as np
10
9
  import pyvista as pv
@@ -14,7 +13,7 @@ import mooseherder as mh
14
13
 
15
14
  def simdata_to_pyvista(sim_data: mh.SimData,
16
15
  components: tuple[str,...] | None,
17
- spat_dim: int
16
+ elem_dims: int
18
17
  ) -> tuple[pv.UnstructuredGrid,pv.UnstructuredGrid]:
19
18
  """Converts the mesh and field data in a `SimData` object into a pyvista
20
19
  UnstructuredGrid for sampling (interpolating) the data and visualisation.
@@ -26,7 +25,7 @@ def simdata_to_pyvista(sim_data: mh.SimData,
26
25
  components : tuple[str,...] | None
27
26
  String keys for the components of the field to extract from the
28
27
  simulation data.
29
- spat_dim : int
28
+ elem_dim : int
30
29
  Number of spatial dimensions (2 or 3) used to determine the element
31
30
  types in the mesh from the number of nodes per element.
32
31
 
@@ -44,7 +43,7 @@ def simdata_to_pyvista(sim_data: mh.SimData,
44
43
  this_connect = np.copy(sim_data.connect[cc])-1
45
44
  (nodes_per_elem,n_elems) = this_connect.shape
46
45
 
47
- this_cell_type = _get_pyvista_cell_type(nodes_per_elem,spat_dim)
46
+ this_cell_type = _get_pyvista_cell_type(nodes_per_elem,elem_dims)
48
47
 
49
48
  # VTK and exodus have different winding for 3D higher order quads
50
49
  this_connect = _exodus_to_pyvista_connect(this_cell_type,this_connect)
@@ -70,6 +69,99 @@ def simdata_to_pyvista(sim_data: mh.SimData,
70
69
  return (pv_grid,pv_grid_vis)
71
70
 
72
71
 
72
+ def scale_length_units(sim_data: mh.SimData,
73
+ disp_comps: tuple[str,...],
74
+ scale: float) -> mh.SimData:
75
+
76
+ sim_data.coords = sim_data.coords*scale
77
+ for cc in disp_comps:
78
+ sim_data.node_vars[cc] = sim_data.node_vars[cc]*scale
79
+
80
+ return sim_data
81
+
82
+
83
+ # TODO: make this work for sim_data with multiple connectivity
84
+ def extract_surf_mesh(sim_data: mh.SimData) -> mh.SimData:
85
+
86
+ # NOTE: need to fix exodus 1 indexing for now and put it back at the end
87
+ # shape=(nodes_per_elem,num_elems)
88
+ connect = np.copy(sim_data.connect["connect1"])-1
89
+ num_elems = connect.shape[1]
90
+
91
+ assert "connect2" not in sim_data.connect, \
92
+ "Multiple connectivity tables not supported yet."
93
+
94
+ # Mapping of node numbers to faces for each element face
95
+ face_map = _get_surf_map(nodes_per_elem=connect.shape[0])
96
+ faces_per_elem = face_map.shape[0]
97
+ nodes_per_face = face_map.shape[1]
98
+
99
+ # shape=(faces_per_elem,nodes_per_face,num_elems)
100
+ faces_wound = connect[face_map,:]
101
+ # shape=(num_elems,faces_per_elem,nodes_per_face)
102
+ faces_wound = faces_wound.transpose((2,0,1))
103
+
104
+ # Create an array of all faces with shape=(total_faces,nodes_per_face)
105
+ faces_total = faces_per_elem*num_elems
106
+ faces_flat_wound = faces_wound.reshape((faces_total,nodes_per_face))
107
+ # Sort the rows so nodes are in the same order when comparing them
108
+ faces_flat_sorted = np.copy(np.sort(faces_flat_wound,axis=1))
109
+
110
+ # Count each unique face in the list of faces, faces that appear only once
111
+ # must be external faces
112
+ (_,
113
+ faces_unique_inds,
114
+ faces_unique_counts) = np.unique(faces_flat_sorted,
115
+ axis=0,
116
+ return_counts=True,
117
+ return_index=True)
118
+
119
+ # Indices of the external faces in faces_flat
120
+ faces_ext_inds_in_unique = np.where(faces_unique_counts==1)[0]
121
+
122
+ # shape=(num_ext_faces,nodes_per_face)
123
+ faces_ext_inds = faces_unique_inds[faces_ext_inds_in_unique]
124
+
125
+ faces_ext_wound = faces_flat_wound[faces_ext_inds]
126
+
127
+ faces_coord_inds = np.unique(faces_ext_wound.flatten())
128
+ faces_coords = np.copy(sim_data.coords[faces_coord_inds])
129
+
130
+ faces_shape = faces_ext_wound.shape
131
+ faces_ext_wound_flat = faces_ext_wound.flatten()
132
+ faces_ext_remap_flat = np.copy(faces_ext_wound_flat)
133
+
134
+ # Remap coordinates in the connectivity to match the trimmed list of coords
135
+ # that belong to the external faces
136
+ for mm,cc in enumerate(faces_coord_inds):
137
+ if mm == cc:
138
+ continue
139
+
140
+ ind_to_map = np.where(faces_ext_wound_flat == cc)[0]
141
+ faces_ext_remap_flat[ind_to_map] = mm
142
+
143
+ faces_ext_remap = faces_ext_remap_flat.reshape(faces_shape)
144
+ faces_ext_remap = faces_ext_remap + 1 # back to exodus 1 index
145
+
146
+ # Now we build the SimData object and slice out the node and element
147
+ # variables using the coordinate indexing.
148
+ face_data = mh.SimData(coords=faces_coords,
149
+ connect={"connect1":faces_ext_remap.T},
150
+ time=sim_data.time)
151
+
152
+ if sim_data.node_vars is not None:
153
+ face_data.node_vars = {}
154
+ for nn in sim_data.node_vars:
155
+ face_data.node_vars[nn] = sim_data.node_vars[nn][faces_coord_inds,:]
156
+
157
+ if sim_data.elem_vars is not None:
158
+ face_data.elem_vars = {}
159
+ for ee in sim_data.node_vars:
160
+ face_data.elem_vars[ee] = sim_data.elem_vars[ee][faces_coord_inds,:]
161
+
162
+ return face_data
163
+
164
+
73
165
  def _get_pyvista_cell_type(nodes_per_elem: int, spat_dim: int) -> CellType:
74
166
  """Helper function to identify the pyvista element type in the mesh.
75
167
 
@@ -141,14 +233,43 @@ def _exodus_to_pyvista_connect(cell_type: CellType, connect: np.ndarray) -> np.n
141
233
 
142
234
  return connect
143
235
 
144
- def scale_length_units(sim_data: mh.SimData,
145
- disp_comps: tuple[str,...],
146
- scale: float) -> mh.SimData:
147
236
 
148
- sim_data.coords = sim_data.coords*scale
149
- for cc in disp_comps:
150
- sim_data.node_vars[cc] = sim_data.node_vars[cc]*scale
237
+ def _get_surf_map(nodes_per_elem: int) -> np.ndarray:
151
238
 
152
- return sim_data
239
+ if nodes_per_elem == 4: # TET4
240
+ return np.array(((0,1,2),
241
+ (0,3,1),
242
+ (0,2,3),
243
+ (1,3,2)))
244
+
245
+ if nodes_per_elem == 8: # HEX8
246
+ return np.array(((0,1,2,3),
247
+ (0,3,7,4),
248
+ (4,7,6,5),
249
+ (1,5,6,2),
250
+ (0,4,5,1),
251
+ (2,6,7,3)))
252
+
253
+ if nodes_per_elem == 10: # TET10
254
+ return np.array(((0,1,2,4,5,6),
255
+ (0,3,1,4,8,7),
256
+ (0,2,3,6,9,7),
257
+ (1,3,2,8,9,5)))
258
+
259
+ if nodes_per_elem == 20: # HEX20
260
+ return np.array(((0,1,2,3,8,9,10,11),
261
+ (0,3,7,4,11,15,19,12),
262
+ (4,7,6,5,19,18,17,16),
263
+ (1,5,6,2,13,17,14,9),
264
+ (0,4,5,1,12,16,13,8),
265
+ (2,6,7,3,14,18,15,10)))
153
266
 
267
+ if nodes_per_elem == 27: # HEX27
268
+ return np.array(((0,1,2,3,8,9,10,11,21),
269
+ (0,3,7,4,11,15,19,12,23),
270
+ (4,7,6,5,19,18,17,16,22),
271
+ (1,5,6,2,13,17,14,9,24),
272
+ (0,4,5,1,12,16,13,8,25),
273
+ (2,6,7,3,14,18,15,10,26)))
154
274
 
275
+ raise ValueError("Number of nodes does not match a 3D element type for surface extraction.")
@@ -1,15 +1,14 @@
1
- """
2
- ================================================================================
3
- pyvale: the python validation engine
4
- License: MIT
5
- Copyright (C) 2025 The Computer Aided Validation Team
6
- ================================================================================
7
- """
1
+ # ================================================================================
2
+ # pyvale: the python validation engine
3
+ # License: MIT
4
+ # Copyright (C) 2025 The Computer Aided Validation Team
5
+ # ================================================================================
6
+
8
7
  import numpy as np
9
8
  import pyvista as pv
10
- from pyvale.core.field import IField
11
- from pyvale.core.sensordata import SensorData
12
- from pyvale.core.integratorfactory import build_spatial_averager
9
+ from pyvale.field import IField
10
+ from pyvale.sensordata import SensorData
11
+ from pyvale.integratorfactory import build_spatial_averager
13
12
 
14
13
 
15
14
  def sample_field_with_sensor_data(field: IField, sensor_data: SensorData
@@ -1,18 +1,17 @@
1
- """
2
- ================================================================================
3
- pyvale: the python validation engine
4
- License: MIT
5
- Copyright (C) 2025 The Computer Aided Validation Team
6
- ================================================================================
7
- """
1
+ # ================================================================================
2
+ # pyvale: the python validation engine
3
+ # License: MIT
4
+ # Copyright (C) 2025 The Computer Aided Validation Team
5
+ # ================================================================================
6
+
8
7
  import numpy as np
9
8
  import pyvista as pv
10
9
  from scipy.spatial.transform import Rotation
11
10
  import mooseherder as mh
12
11
 
13
- from pyvale.core.field import IField
14
- from pyvale.core.fieldconverter import simdata_to_pyvista
15
- from pyvale.core.fieldsampler import sample_pyvista_grid
12
+ from pyvale.field import IField
13
+ from pyvale.fieldconverter import simdata_to_pyvista
14
+ from pyvale.fieldsampler import sample_pyvista_grid
16
15
 
17
16
  class FieldScalar(IField):
18
17
  """Class for sampling (interpolating) scalar fields from simulations to
@@ -1,19 +1,18 @@
1
- """
2
- ================================================================================
3
- pyvale: the python validation engine
4
- License: MIT
5
- Copyright (C) 2025 The Computer Aided Validation Team
6
- ================================================================================
7
- """
1
+ # ================================================================================
2
+ # pyvale: the python validation engine
3
+ # License: MIT
4
+ # Copyright (C) 2025 The Computer Aided Validation Team
5
+ # ================================================================================
6
+
8
7
  import numpy as np
9
8
  import pyvista as pv
10
9
  from scipy.spatial.transform import Rotation
11
10
  import mooseherder as mh
12
11
 
13
- from pyvale.core.field import IField
14
- from pyvale.core.fieldconverter import simdata_to_pyvista
15
- from pyvale.core.fieldsampler import sample_pyvista_grid
16
- from pyvale.core.fieldtransform import (transform_tensor_2d,
12
+ from pyvale.field import IField
13
+ from pyvale.fieldconverter import simdata_to_pyvista
14
+ from pyvale.fieldsampler import sample_pyvista_grid
15
+ from pyvale.fieldtransform import (transform_tensor_2d,
17
16
  transform_tensor_2d_batch,
18
17
  transform_tensor_3d,
19
18
  transform_tensor_3d_batch)
@@ -1,10 +1,9 @@
1
- """
2
- ================================================================================
3
- pyvale: the python validation engine
4
- License: MIT
5
- Copyright (C) 2025 The Computer Aided Validation Team
6
- ================================================================================
7
- """
1
+ # ================================================================================
2
+ # pyvale: the python validation engine
3
+ # License: MIT
4
+ # Copyright (C) 2025 The Computer Aided Validation Team
5
+ # ================================================================================
6
+
8
7
  import numpy as np
9
8
 
10
9
  def transform_vector_2d(trans_mat: np.ndarray, vector: np.ndarray
@@ -1,19 +1,18 @@
1
- """
2
- ================================================================================
3
- pyvale: the python validation engine
4
- License: MIT
5
- Copyright (C) 2025 The Computer Aided Validation Team
6
- ================================================================================
7
- """
1
+ # ================================================================================
2
+ # pyvale: the python validation engine
3
+ # License: MIT
4
+ # Copyright (C) 2025 The Computer Aided Validation Team
5
+ # ================================================================================
6
+
8
7
  import numpy as np
9
8
  import pyvista as pv
10
9
  from scipy.spatial.transform import Rotation
11
10
  import mooseherder as mh
12
11
 
13
- from pyvale.core.field import IField
14
- from pyvale.core.fieldconverter import simdata_to_pyvista
15
- from pyvale.core.fieldsampler import sample_pyvista_grid
16
- from pyvale.core.fieldtransform import (transform_vector_2d,
12
+ from pyvale.field import IField
13
+ from pyvale.fieldconverter import simdata_to_pyvista
14
+ from pyvale.fieldsampler import sample_pyvista_grid
15
+ from pyvale.fieldtransform import (transform_vector_2d,
17
16
  transform_vector_2d_batch,
18
17
  transform_vector_3d,
19
18
  transform_vector_3d_batch)
@@ -1,10 +1,9 @@
1
- """
2
- ================================================================================
3
- pyvale: the python validation engine
4
- License: MIT
5
- Copyright (C) 2025 The Computer Aided Validation Team
6
- ================================================================================
7
- """
1
+ # ================================================================================
2
+ # pyvale: the python validation engine
3
+ # License: MIT
4
+ # Copyright (C) 2025 The Computer Aided Validation Team
5
+ # ================================================================================
6
+
8
7
  from abc import ABC, abstractmethod
9
8
  import numpy as np
10
9
 
@@ -1,10 +1,9 @@
1
- """
2
- ================================================================================
3
- pyvale: the python validation engine
4
- License: MIT
5
- Copyright (C) 2025 The Computer Aided Validation Team
6
- ================================================================================
7
- """
1
+ # ================================================================================
2
+ # pyvale: the python validation engine
3
+ # License: MIT
4
+ # Copyright (C) 2025 The Computer Aided Validation Team
5
+ # ================================================================================
6
+
8
7
  import time
9
8
  import warnings
10
9
  from dataclasses import dataclass
@@ -14,9 +13,9 @@ from scipy.interpolate import griddata
14
13
  from scipy.interpolate import RectBivariateSpline
15
14
  from scipy import ndimage
16
15
 
17
- from pyvale.core.rasternp import edge_function, RasterNP
18
- from pyvale.core.cameradata2d import CameraData2D
19
- from pyvale.core.cameratools import CameraTools
16
+ from pyvale.rasternp import edge_function, RasterNP
17
+ from pyvale.cameradata2d import CameraData2D
18
+ from pyvale.cameratools import CameraTools
20
19
 
21
20
 
22
21
  @dataclass(slots=True)
@@ -1,17 +1,16 @@
1
- """
2
- ================================================================================
3
- pyvale: the python validation engine
4
- License: MIT
5
- Copyright (C) 2025 The Computer Aided Validation Team
6
- ================================================================================
7
- """
1
+ # ================================================================================
2
+ # pyvale: the python validation engine
3
+ # License: MIT
4
+ # Copyright (C) 2025 The Computer Aided Validation Team
5
+ # ================================================================================
6
+
8
7
  import numpy as np
9
- from pyvale.core.field import IField
10
- from pyvale.core.sensordata import SensorData
11
- from pyvale.core.integratorspatial import IIntegratorSpatial
12
- from pyvale.core.integratortype import EIntSpatialType
13
- from pyvale.core.integratorrectangle import Rectangle2D
14
- from pyvale.core.integratorquadrature import (Quadrature2D,
8
+ from pyvale.field import IField
9
+ from pyvale.sensordata import SensorData
10
+ from pyvale.integratorspatial import IIntegratorSpatial
11
+ from pyvale.integratortype import EIntSpatialType
12
+ from pyvale.integratorrectangle import Rectangle2D
13
+ from pyvale.integratorquadrature import (Quadrature2D,
15
14
  create_gauss_weights_2d_4pts,
16
15
  create_gauss_weights_2d_9pts)
17
16