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.
- pyvale/__init__.py +51 -52
- pyvale/analyticmeshgen.py +101 -0
- pyvale/{core/analyticsimdatafactory.py → analyticsimdatafactory.py} +32 -9
- pyvale/{core/analyticsimdatagenerator.py → analyticsimdatagenerator.py} +151 -21
- pyvale/{core/camera.py → camera.py} +13 -14
- pyvale/{core/cameradata.py → cameradata.py} +6 -19
- pyvale/{core/cameradata2d.py → cameradata2d.py} +7 -7
- pyvale/{core/cameratools.py → cameratools.py} +18 -19
- pyvale/{core/cython → cython}/rastercyth.py +9 -9
- pyvale/data/__init__.py +5 -7
- pyvale/data/case00_HEX20_out.e +0 -0
- pyvale/data/case00_HEX27_out.e +0 -0
- pyvale/data/case00_HEX8_out.e +0 -0
- pyvale/data/case00_TET10_out.e +0 -0
- pyvale/data/case00_TET14_out.e +0 -0
- pyvale/data/case00_TET4_out.e +0 -0
- pyvale/{core/dataset.py → dataset.py} +24 -8
- pyvale/{core/errorcalculator.py → errorcalculator.py} +7 -8
- pyvale/{core/errordriftcalc.py → errordriftcalc.py} +6 -7
- pyvale/{core/errorintegrator.py → errorintegrator.py} +8 -9
- pyvale/{core/errorrand.py → errorrand.py} +9 -10
- pyvale/{core/errorsysdep.py → errorsysdep.py} +8 -9
- pyvale/{core/errorsysfield.py → errorsysfield.py} +13 -14
- pyvale/{core/errorsysindep.py → errorsysindep.py} +9 -10
- pyvale/examples/__init__.py +5 -7
- pyvale/examples/analyticdatagen/__init__.py +5 -7
- pyvale/examples/ex1_1_thermal2d.py +6 -9
- pyvale/examples/ex1_2_thermal2d.py +6 -9
- pyvale/examples/ex1_3_thermal2d.py +6 -9
- pyvale/examples/ex1_4_thermal2d.py +6 -9
- pyvale/examples/ex1_5_thermal2d.py +6 -9
- pyvale/examples/ex2_1_thermal3d .py +6 -9
- pyvale/examples/ex2_3_thermal3d.py +6 -9
- pyvale/examples/ex3_1_displacement2d.py +6 -9
- pyvale/examples/ex3_2_displacement2d.py +5 -8
- pyvale/examples/ex3_3_displacement2d.py +6 -9
- pyvale/examples/ex3_4_displacement2d.py +6 -9
- pyvale/examples/ex4_1_strain2d.py +6 -9
- pyvale/examples/ex4_2_strain2d.py +5 -8
- pyvale/examples/ex4_3_strain2d.py +6 -9
- pyvale/examples/ex5_1_multiphysics2d.py +5 -8
- pyvale/examples/ex6_1_multiphysics2d_expsim.py +6 -9
- pyvale/examples/ex6_2_multiphysics3d_expsim.py +15 -13
- pyvale/examples/features/__init__.py +5 -7
- pyvale/examples/rasterisation/ex_rastenp.py +5 -7
- pyvale/examples/rasterisation/ex_rastercyth_oneframe.py +5 -7
- pyvale/examples/rasterisation/ex_rastercyth_static_cypara.py +5 -7
- pyvale/examples/rasterisation/ex_rastercyth_static_pypara.py +5 -7
- pyvale/{core/experimentsimulator.py → experimentsimulator.py} +7 -8
- pyvale/{core/field.py → field.py} +6 -7
- pyvale/{core/fieldconverter.py → fieldconverter.py} +138 -17
- pyvale/{core/fieldsampler.py → fieldsampler.py} +9 -10
- pyvale/{core/fieldscalar.py → fieldscalar.py} +9 -10
- pyvale/{core/fieldtensor.py → fieldtensor.py} +10 -11
- pyvale/{core/fieldtransform.py → fieldtransform.py} +6 -7
- pyvale/{core/fieldvector.py → fieldvector.py} +10 -11
- pyvale/{core/generatorsrandom.py → generatorsrandom.py} +6 -7
- pyvale/{core/imagedef2d.py → imagedef2d.py} +9 -10
- pyvale/{core/integratorfactory.py → integratorfactory.py} +12 -13
- pyvale/{core/integratorquadrature.py → integratorquadrature.py} +9 -10
- pyvale/{core/integratorrectangle.py → integratorrectangle.py} +9 -10
- pyvale/{core/integratorspatial.py → integratorspatial.py} +7 -8
- pyvale/{core/integratortype.py → integratortype.py} +6 -7
- pyvale/{core/optimcheckfuncs.py → optimcheckfuncs.py} +1 -1
- pyvale/{core/raster.py → raster.py} +6 -7
- pyvale/{core/rastercy.py → rastercy.py} +9 -10
- pyvale/{core/rasternp.py → rasternp.py} +10 -13
- pyvale/{core/rendermesh.py → rendermesh.py} +8 -21
- pyvale/{core/sensorarray.py → sensorarray.py} +7 -8
- pyvale/{core/sensorarrayfactory.py → sensorarrayfactory.py} +15 -16
- pyvale/{core/sensorarraypoint.py → sensorarraypoint.py} +12 -13
- pyvale/{core/sensordata.py → sensordata.py} +7 -8
- pyvale/{core/sensordescriptor.py → sensordescriptor.py} +6 -7
- pyvale/{core/sensortools.py → sensortools.py} +7 -8
- pyvale/simcases/case00_HEX20.i +5 -5
- pyvale/simcases/case00_HEX27.i +5 -5
- pyvale/simcases/case00_HEX8.i +242 -0
- pyvale/simcases/case00_TET10.i +2 -2
- pyvale/simcases/case00_TET14.i +2 -2
- pyvale/simcases/case00_TET4.i +242 -0
- pyvale/simcases/run_1case.py +1 -1
- pyvale/{core/visualexpplotter.py → visualexpplotter.py} +8 -10
- pyvale/{core/visualimagedef.py → visualimagedef.py} +6 -7
- pyvale/{core/visualimages.py → visualimages.py} +8 -9
- pyvale/{core/visualopts.py → visualopts.py} +6 -7
- pyvale/{core/visualsimanimator.py → visualsimanimator.py} +10 -11
- pyvale/{core/visualsimplotter.py → visualsimplotter.py} +30 -30
- pyvale/{core/visualtools.py → visualtools.py} +7 -8
- pyvale/{core/visualtraceplotter.py → visualtraceplotter.py} +9 -10
- {pyvale-2025.4.0.dist-info → pyvale-2025.4.1.dist-info}/METADATA +1 -1
- pyvale-2025.4.1.dist-info/RECORD +163 -0
- {pyvale-2025.4.0.dist-info → pyvale-2025.4.1.dist-info}/WHEEL +1 -1
- pyvale/core/__init__.py +0 -7
- pyvale/core/analyticmeshgen.py +0 -59
- pyvale/core/cython/rastercyth.c +0 -32267
- pyvale-2025.4.0.dist-info/RECORD +0 -157
- {pyvale-2025.4.0.dist-info → pyvale-2025.4.1.dist-info}/licenses/LICENSE +0 -0
- {pyvale-2025.4.0.dist-info → pyvale-2025.4.1.dist-info}/top_level.txt +0 -0
pyvale/__init__.py
CHANGED
|
@@ -1,3 +1,9 @@
|
|
|
1
|
+
# ================================================================================
|
|
2
|
+
# pyvale: the python validation engine
|
|
3
|
+
# License: MIT
|
|
4
|
+
# Copyright (C) 2025 The Computer Aided Validation Team
|
|
5
|
+
# ================================================================================
|
|
6
|
+
|
|
1
7
|
"""
|
|
2
8
|
`pyvale`: the python validation engine. Used to simulate experimental data from
|
|
3
9
|
an input multi-physics simulation by explicitly modelling sensors with realistic
|
|
@@ -5,71 +11,64 @@ uncertainties. Useful for experimental design, sensor placement optimisation,
|
|
|
5
11
|
testing simulation validation metrics and testing digital shadows/twins.
|
|
6
12
|
"""
|
|
7
13
|
|
|
8
|
-
"""
|
|
9
|
-
================================================================================
|
|
10
|
-
pyvale: the python validation engine
|
|
11
|
-
License: MIT
|
|
12
|
-
Copyright (C) 2025 The Computer Aided Validation Team
|
|
13
|
-
================================================================================
|
|
14
|
-
"""
|
|
15
14
|
# NOTE: this simplifies and decouples how the user calls pyvale from the
|
|
16
15
|
# underlying project structure: the user should be able to use 'pyvale.'
|
|
17
16
|
# and access everything in one layer without multiple import dots
|
|
18
17
|
|
|
19
|
-
from pyvale.
|
|
18
|
+
from pyvale.dataset import *
|
|
20
19
|
|
|
21
|
-
from pyvale.
|
|
22
|
-
from pyvale.
|
|
23
|
-
from pyvale.
|
|
24
|
-
from pyvale.
|
|
25
|
-
from pyvale.
|
|
26
|
-
from pyvale.
|
|
20
|
+
from pyvale.field import *
|
|
21
|
+
from pyvale.fieldscalar import *
|
|
22
|
+
from pyvale.fieldvector import *
|
|
23
|
+
from pyvale.fieldtensor import *
|
|
24
|
+
from pyvale.fieldconverter import *
|
|
25
|
+
from pyvale.fieldtransform import *
|
|
27
26
|
|
|
28
|
-
from pyvale.
|
|
29
|
-
from pyvale.
|
|
30
|
-
from pyvale.
|
|
31
|
-
from pyvale.
|
|
27
|
+
from pyvale.integratorspatial import *
|
|
28
|
+
from pyvale.integratorquadrature import *
|
|
29
|
+
from pyvale.integratorrectangle import *
|
|
30
|
+
from pyvale.integratorfactory import *
|
|
32
31
|
|
|
33
|
-
from pyvale.
|
|
34
|
-
from pyvale.
|
|
35
|
-
from pyvale.
|
|
36
|
-
from pyvale.
|
|
37
|
-
from pyvale.
|
|
38
|
-
from pyvale.
|
|
32
|
+
from pyvale.sensordescriptor import *
|
|
33
|
+
from pyvale.sensortools import *
|
|
34
|
+
from pyvale.sensorarray import *
|
|
35
|
+
from pyvale.sensorarrayfactory import *
|
|
36
|
+
from pyvale.sensorarraypoint import *
|
|
37
|
+
from pyvale.sensordata import *
|
|
39
38
|
|
|
40
|
-
from pyvale.
|
|
41
|
-
from pyvale.
|
|
42
|
-
from pyvale.
|
|
43
|
-
from pyvale.
|
|
39
|
+
from pyvale.camera import *
|
|
40
|
+
from pyvale.cameradata import *
|
|
41
|
+
from pyvale.cameradata2d import *
|
|
42
|
+
from pyvale.cameratools import *
|
|
44
43
|
|
|
45
|
-
import pyvale.
|
|
46
|
-
from pyvale.
|
|
44
|
+
import pyvale.cython.rastercyth as rastercyth
|
|
45
|
+
from pyvale.rastercy import *
|
|
47
46
|
|
|
48
|
-
from pyvale.
|
|
49
|
-
from pyvale.
|
|
47
|
+
from pyvale.rendermesh import *
|
|
48
|
+
from pyvale.rasternp import *
|
|
50
49
|
|
|
51
|
-
from pyvale.
|
|
50
|
+
from pyvale.imagedef2d import *
|
|
52
51
|
|
|
53
|
-
from pyvale.
|
|
54
|
-
from pyvale.
|
|
55
|
-
from pyvale.
|
|
56
|
-
from pyvale.
|
|
57
|
-
from pyvale.
|
|
58
|
-
from pyvale.
|
|
52
|
+
from pyvale.errorintegrator import *
|
|
53
|
+
from pyvale.errorrand import *
|
|
54
|
+
from pyvale.errorsysindep import *
|
|
55
|
+
from pyvale.errorsysdep import *
|
|
56
|
+
from pyvale.errorsysfield import *
|
|
57
|
+
from pyvale.errordriftcalc import *
|
|
59
58
|
|
|
60
|
-
from pyvale.
|
|
59
|
+
from pyvale.generatorsrandom import *
|
|
61
60
|
|
|
62
|
-
from pyvale.
|
|
63
|
-
from pyvale.
|
|
64
|
-
from pyvale.
|
|
65
|
-
from pyvale.
|
|
66
|
-
from pyvale.
|
|
67
|
-
from pyvale.
|
|
68
|
-
from pyvale.
|
|
69
|
-
from pyvale.
|
|
61
|
+
from pyvale.visualopts import *
|
|
62
|
+
from pyvale.visualtools import *
|
|
63
|
+
from pyvale.visualsimplotter import *
|
|
64
|
+
from pyvale.visualsimanimator import *
|
|
65
|
+
from pyvale.visualexpplotter import *
|
|
66
|
+
from pyvale.visualtraceplotter import *
|
|
67
|
+
from pyvale.visualimages import *
|
|
68
|
+
from pyvale.visualimagedef import *
|
|
70
69
|
|
|
71
|
-
from pyvale.
|
|
72
|
-
from pyvale.
|
|
73
|
-
from pyvale.
|
|
70
|
+
from pyvale.analyticmeshgen import *
|
|
71
|
+
from pyvale.analyticsimdatagenerator import *
|
|
72
|
+
from pyvale.analyticsimdatafactory import *
|
|
74
73
|
|
|
75
|
-
from pyvale.
|
|
74
|
+
from pyvale.experimentsimulator import *
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
#===============================================================================
|
|
2
|
+
# pyvale: the python validation engine
|
|
3
|
+
# License: MIT
|
|
4
|
+
# Copyright (C) 2025 The Computer Aided Validation Team
|
|
5
|
+
#===============================================================================
|
|
6
|
+
"""
|
|
7
|
+
Analytic mesh creation tools for testing pyvale sensor simulation and
|
|
8
|
+
uncertainty quantification functionality with a known analytic function for the
|
|
9
|
+
scalar/vector/tensor field of interest.
|
|
10
|
+
"""
|
|
11
|
+
import numpy as np
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def rectangle_mesh_2d(leng_x: float,
|
|
15
|
+
leng_y: float,
|
|
16
|
+
n_elem_x: int,
|
|
17
|
+
n_elem_y: int) -> tuple[np.ndarray,np.ndarray]:
|
|
18
|
+
"""Creates the nodal coordinates and element connectivity table for a simple
|
|
19
|
+
2D quad mesh for a rectangular plate.
|
|
20
|
+
|
|
21
|
+
Parameters
|
|
22
|
+
----------
|
|
23
|
+
leng_x : float
|
|
24
|
+
Length of the plate in the x direction.
|
|
25
|
+
leng_y : float
|
|
26
|
+
Length of the plate in the y direction.
|
|
27
|
+
n_elem_x : int
|
|
28
|
+
Number of elements along the x axis
|
|
29
|
+
n_elem_y : int
|
|
30
|
+
Number of elements along the y axis
|
|
31
|
+
|
|
32
|
+
Returns
|
|
33
|
+
-------
|
|
34
|
+
tuple[np.ndarray,np.ndarray]
|
|
35
|
+
The coordinates and connectivity table as numpy arrays. The coordinates
|
|
36
|
+
have shape=(n_nodes,coord[x,y,z]). The connectivity tables has shape=
|
|
37
|
+
(nodes_per_elem,num_elems).
|
|
38
|
+
"""
|
|
39
|
+
n_elems = n_elem_x*n_elem_y
|
|
40
|
+
n_node_x = n_elem_x+1
|
|
41
|
+
n_node_y = n_elem_y+1
|
|
42
|
+
nodes_per_elem = 4
|
|
43
|
+
|
|
44
|
+
coord_x = np.linspace(0,leng_x,n_node_x)
|
|
45
|
+
coord_y = np.linspace(0,leng_y,n_node_y)
|
|
46
|
+
(coord_grid_x,coord_grid_y) = np.meshgrid(coord_x,coord_y)
|
|
47
|
+
|
|
48
|
+
coord_x = np.atleast_2d(coord_grid_x.flatten()).T
|
|
49
|
+
coord_y = np.atleast_2d(coord_grid_y.flatten()).T
|
|
50
|
+
coord_z = np.zeros_like(coord_x)
|
|
51
|
+
coords = np.hstack((coord_x,coord_y,coord_z))
|
|
52
|
+
|
|
53
|
+
connect = np.zeros((n_elems,nodes_per_elem)).astype(np.int64)
|
|
54
|
+
row = 1
|
|
55
|
+
nn = 0
|
|
56
|
+
for ee in range(n_elems):
|
|
57
|
+
nn += 1
|
|
58
|
+
if nn >= row*n_node_x:
|
|
59
|
+
row += 1
|
|
60
|
+
nn += 1
|
|
61
|
+
|
|
62
|
+
connect[ee,:] = np.array([nn,nn+1,nn+n_node_x+1,nn+n_node_x])
|
|
63
|
+
connect = connect.T
|
|
64
|
+
|
|
65
|
+
return (coords,connect)
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
def fill_dims_2d(coord_x: np.ndarray,
|
|
69
|
+
coord_y: np.ndarray,
|
|
70
|
+
time: np.ndarray) -> tuple[np.ndarray,np.ndarray,np.ndarray]:
|
|
71
|
+
"""Helper function to generate 2D filled arrays tih consistent dimensions
|
|
72
|
+
for array based maths operations. Takes 1D input vectors for the x, y and
|
|
73
|
+
time dimensions and returns 2D arrays with shape=(num_coords,num_timesteps).
|
|
74
|
+
Useful for evaluating analytical functions in space and time.
|
|
75
|
+
|
|
76
|
+
Parameters
|
|
77
|
+
----------
|
|
78
|
+
coord_x : np.ndarray
|
|
79
|
+
1D flattened coordinate list for the x axis.
|
|
80
|
+
coord_y : np.ndarray
|
|
81
|
+
1D flattened coordinate list for the y axis.
|
|
82
|
+
time : np.ndarray
|
|
83
|
+
1D array of time steps.
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
Returns
|
|
87
|
+
-------
|
|
88
|
+
tuple[np.ndarray,np.ndarray,np.ndarray]
|
|
89
|
+
Filled 2D arrays with shape=(num_coords,num_timesteps) for the x, y and
|
|
90
|
+
time parameters respectively.
|
|
91
|
+
"""
|
|
92
|
+
full_x = np.repeat(np.atleast_2d(coord_x).T,
|
|
93
|
+
time.shape[0],
|
|
94
|
+
axis=1)
|
|
95
|
+
full_y = np.repeat(np.atleast_2d(coord_y).T,
|
|
96
|
+
time.shape[0],
|
|
97
|
+
axis=1)
|
|
98
|
+
full_time = np.repeat(np.atleast_2d(time),
|
|
99
|
+
coord_x.shape[0],
|
|
100
|
+
axis=0)
|
|
101
|
+
return (full_x,full_y,full_time)
|
|
@@ -1,19 +1,27 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
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 sympy
|
|
10
9
|
import mooseherder as mh
|
|
11
|
-
from pyvale.
|
|
10
|
+
from pyvale.analyticsimdatagenerator import (AnalyticCaseData2D,
|
|
12
11
|
AnalyticSimDataGenerator)
|
|
13
12
|
|
|
14
|
-
|
|
13
|
+
|
|
15
14
|
|
|
16
15
|
def standard_case_2d() -> AnalyticCaseData2D:
|
|
16
|
+
"""Created the standard 2D analytic test case which is a plate with
|
|
17
|
+
dimensions 10x7.5 (x,y), number of elements 40x30 (x,y), and time steps of
|
|
18
|
+
0 to 10 in increments of 1.
|
|
19
|
+
|
|
20
|
+
Returns
|
|
21
|
+
-------
|
|
22
|
+
AnalyticCaseData2D
|
|
23
|
+
_description_
|
|
24
|
+
"""
|
|
17
25
|
case_data = AnalyticCaseData2D()
|
|
18
26
|
case_data.length_x = 10.0
|
|
19
27
|
case_data.length_y = 7.5
|
|
@@ -25,10 +33,19 @@ def standard_case_2d() -> AnalyticCaseData2D:
|
|
|
25
33
|
|
|
26
34
|
|
|
27
35
|
class AnalyticCaseFactory:
|
|
36
|
+
"""Builds pre-defined 2D meshes and fields based on analytic functions for
|
|
37
|
+
testing the sensor simulation functionality of pyvale.
|
|
38
|
+
"""
|
|
28
39
|
|
|
29
40
|
@staticmethod
|
|
30
41
|
def scalar_linear_2d() -> tuple[mh.SimData,AnalyticSimDataGenerator]:
|
|
42
|
+
"""_summary_
|
|
31
43
|
|
|
44
|
+
Returns
|
|
45
|
+
-------
|
|
46
|
+
tuple[mh.SimData,AnalyticSimDataGenerator]
|
|
47
|
+
_description_
|
|
48
|
+
"""
|
|
32
49
|
case_data = standard_case_2d()
|
|
33
50
|
(sym_y,sym_x,sym_t) = sympy.symbols("y,x,t")
|
|
34
51
|
case_data.funcs_x = (20.0/case_data.length_x * sym_x,)
|
|
@@ -45,7 +62,13 @@ class AnalyticCaseFactory:
|
|
|
45
62
|
|
|
46
63
|
@staticmethod
|
|
47
64
|
def scalar_quadratic_2d() -> tuple[mh.SimData,AnalyticSimDataGenerator]:
|
|
65
|
+
"""_summary_
|
|
48
66
|
|
|
67
|
+
Returns
|
|
68
|
+
-------
|
|
69
|
+
tuple[mh.SimData,AnalyticSimDataGenerator]
|
|
70
|
+
_description_
|
|
71
|
+
"""
|
|
49
72
|
case_data = standard_case_2d()
|
|
50
73
|
(sym_y,sym_x,sym_t) = sympy.symbols("y,x,t")
|
|
51
74
|
case_data.funcs_x = (sym_x*(sym_x - case_data.length_x),)
|
|
@@ -1,41 +1,111 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
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
9
|
import sympy
|
|
11
10
|
import mooseherder as mh
|
|
12
|
-
from pyvale.
|
|
11
|
+
from pyvale.analyticmeshgen import rectangle_mesh_2d, fill_dims_2d
|
|
13
12
|
|
|
14
|
-
# NOTE: This module is a feature under developement.
|
|
15
13
|
|
|
16
|
-
@dataclass
|
|
14
|
+
@dataclass(slots=True)
|
|
17
15
|
class AnalyticCaseData2D:
|
|
16
|
+
"""Dataclass for describing a 2D analytic test case for pyvale sensor
|
|
17
|
+
simulation. Includes information about the geometry, the mesh and the
|
|
18
|
+
analytic functions used to generate the field data.
|
|
19
|
+
"""
|
|
20
|
+
|
|
18
21
|
length_x: float = 10.0
|
|
22
|
+
"""Length of the test case geometry in the X direction in length units.
|
|
23
|
+
Defaults to 10.0.
|
|
24
|
+
"""
|
|
25
|
+
|
|
19
26
|
length_y: float = 7.5
|
|
27
|
+
"""Length of the test case geometry in the Y direction in length units.
|
|
28
|
+
Defaults to 7.5.
|
|
29
|
+
"""
|
|
30
|
+
|
|
20
31
|
num_elem_x: int = 4
|
|
32
|
+
"""Number of elements in the mesh in the X direction. Defaults to 4.
|
|
33
|
+
"""
|
|
34
|
+
|
|
21
35
|
num_elem_y: int = 3
|
|
36
|
+
"""Number of elements in the mesh in the Y direction. Defaults to 3.
|
|
37
|
+
"""
|
|
38
|
+
|
|
22
39
|
time_steps: np.ndarray | None = None
|
|
40
|
+
"""1D array of time steps for the analytic test case. Defaults to None which
|
|
41
|
+
is for a test case that only has spatially varying functions.
|
|
42
|
+
"""
|
|
43
|
+
|
|
23
44
|
field_keys: tuple[str,...] = ('scalar',)
|
|
45
|
+
"""Keys used to describe the field of interest. For a scalar field there is
|
|
46
|
+
only a single key. For a vector field 2 keys are required in 2D (xx,yy). For
|
|
47
|
+
a tensor field 3 keys are required for 2D (xx,yy,xy). Defaults to a single
|
|
48
|
+
key for a scalar field: ("scalar",).
|
|
49
|
+
"""
|
|
50
|
+
|
|
24
51
|
funcs_x: tuple[sympy.Expr,...] | None = None
|
|
52
|
+
"""Analytic functions describing the field variation as a function of the x
|
|
53
|
+
coordinate. This tuple should have the same number of functions as the
|
|
54
|
+
number of field keys. Analytic functions in x, y and t are multiplied
|
|
55
|
+
together so setting a function to a constant of 1 will have no effect.
|
|
56
|
+
"""
|
|
25
57
|
funcs_y: tuple[sympy.Expr,...] | None = None
|
|
58
|
+
"""Analytic functions describing the field variation as a function of the y
|
|
59
|
+
coordinate. This tuple should have the same number of functions as the
|
|
60
|
+
number of field keys. Analytic functions in x, y and t are multiplied
|
|
61
|
+
together so setting a function to a constant of 1 will have no effect.
|
|
62
|
+
"""
|
|
63
|
+
|
|
26
64
|
funcs_t: tuple[sympy.Expr,...] | None = None
|
|
65
|
+
"""Analytic functions describing the field variation as a function of time
|
|
66
|
+
This tuple should have the same number of functions as the number of field
|
|
67
|
+
keys. Analytic functions in x, y and t are multiplied together so setting a
|
|
68
|
+
function to a constant of 1 will have no effect.
|
|
69
|
+
"""
|
|
70
|
+
|
|
27
71
|
symbols: tuple[sympy.Symbol,...] = (sympy.Symbol("y"),
|
|
28
72
|
sympy.Symbol("x"),
|
|
29
73
|
sympy.Symbol("t"))
|
|
74
|
+
"""Sympy symbols describing the relevant dimensions of the problem. For 2D
|
|
75
|
+
spatial dimensions default to x and y and time is denoted t.
|
|
76
|
+
"""
|
|
77
|
+
|
|
30
78
|
offsets_space: tuple[float,...] = (0.0,)
|
|
79
|
+
"""_summary_
|
|
80
|
+
"""
|
|
81
|
+
|
|
31
82
|
offsets_time: tuple[float,...] = (0.0,)
|
|
83
|
+
"""_summary_
|
|
84
|
+
"""
|
|
85
|
+
|
|
32
86
|
nodes_per_elem: int = 4
|
|
87
|
+
"""_summary_
|
|
88
|
+
"""
|
|
33
89
|
|
|
34
90
|
|
|
35
91
|
class AnalyticSimDataGenerator:
|
|
92
|
+
"""Class for generating analytic field data as a `SimData` object to test
|
|
93
|
+
the sensor simulation functionality of pyvale. Provides tools to evaluate
|
|
94
|
+
the analytic field functions at a given spatial coordinate and time to check
|
|
95
|
+
against pyvale interpolation functions.
|
|
96
|
+
"""
|
|
97
|
+
|
|
98
|
+
__slots__ = ("_case_data","_coords","_connect")
|
|
99
|
+
|
|
36
100
|
def __init__(self, case_data: AnalyticCaseData2D
|
|
37
101
|
) -> None:
|
|
102
|
+
"""_summary_
|
|
38
103
|
|
|
104
|
+
Parameters
|
|
105
|
+
----------
|
|
106
|
+
case_data : AnalyticCaseData2D
|
|
107
|
+
_description_
|
|
108
|
+
"""
|
|
39
109
|
self._case_data = case_data
|
|
40
110
|
(self._coords,self._connect) = rectangle_mesh_2d(case_data.length_x,
|
|
41
111
|
case_data.length_y,
|
|
@@ -61,28 +131,56 @@ class AnalyticSimDataGenerator:
|
|
|
61
131
|
field_key: str,
|
|
62
132
|
coords: np.ndarray,
|
|
63
133
|
time_steps: np.ndarray | None = None) -> np.ndarray:
|
|
64
|
-
|
|
134
|
+
"""_summary_
|
|
135
|
+
|
|
136
|
+
Parameters
|
|
137
|
+
----------
|
|
138
|
+
field_key : str
|
|
139
|
+
_description_
|
|
140
|
+
coords : np.ndarray
|
|
141
|
+
_description_
|
|
142
|
+
time_steps : np.ndarray | None, optional
|
|
143
|
+
_description_, by default None
|
|
144
|
+
|
|
145
|
+
Returns
|
|
146
|
+
-------
|
|
147
|
+
np.ndarray
|
|
148
|
+
_description_
|
|
149
|
+
"""
|
|
65
150
|
if time_steps is None:
|
|
66
151
|
time_steps = self._case_data.time_steps
|
|
67
152
|
|
|
68
|
-
(x_eval,y_eval,t_eval) =
|
|
69
|
-
|
|
70
|
-
|
|
153
|
+
(x_eval,y_eval,t_eval) = fill_dims_2d(coords[:,0],
|
|
154
|
+
coords[:,1],
|
|
155
|
+
time_steps)
|
|
71
156
|
|
|
72
157
|
field_vals = self._field_lam_funcs[field_key](y_eval,
|
|
73
|
-
|
|
74
|
-
|
|
158
|
+
x_eval,
|
|
159
|
+
t_eval)
|
|
75
160
|
return field_vals
|
|
76
161
|
|
|
77
162
|
|
|
78
163
|
def evaluate_all_fields_truth(self,
|
|
79
164
|
coords: np.ndarray,
|
|
80
165
|
time_steps: np.ndarray | None = None) -> np.ndarray:
|
|
81
|
-
|
|
166
|
+
"""_summary_
|
|
167
|
+
|
|
168
|
+
Parameters
|
|
169
|
+
----------
|
|
170
|
+
coords : np.ndarray
|
|
171
|
+
_description_
|
|
172
|
+
time_steps : np.ndarray | None, optional
|
|
173
|
+
_description_, by default None
|
|
174
|
+
|
|
175
|
+
Returns
|
|
176
|
+
-------
|
|
177
|
+
np.ndarray
|
|
178
|
+
_description_
|
|
179
|
+
"""
|
|
82
180
|
if time_steps is None:
|
|
83
181
|
time_steps = self._case_data.time_steps
|
|
84
182
|
|
|
85
|
-
(x_eval,y_eval,t_eval) =
|
|
183
|
+
(x_eval,y_eval,t_eval) = fill_dims_2d(coords[:,0],
|
|
86
184
|
coords[:,1],
|
|
87
185
|
time_steps)
|
|
88
186
|
|
|
@@ -95,17 +193,30 @@ class AnalyticSimDataGenerator:
|
|
|
95
193
|
|
|
96
194
|
|
|
97
195
|
def evaluate_field_at_nodes(self, field_key: str) -> np.ndarray:
|
|
98
|
-
(x_eval,y_eval,t_eval) =
|
|
196
|
+
(x_eval,y_eval,t_eval) = fill_dims_2d(self._coords[:,0],
|
|
99
197
|
self._coords[:,1],
|
|
100
198
|
self._case_data.time_steps)
|
|
199
|
+
"""_summary_
|
|
101
200
|
|
|
201
|
+
Returns
|
|
202
|
+
-------
|
|
203
|
+
_type_
|
|
204
|
+
_description_
|
|
205
|
+
"""
|
|
102
206
|
self._field_eval[field_key] = self._field_lam_funcs[field_key](y_eval,
|
|
103
207
|
x_eval,
|
|
104
208
|
t_eval)
|
|
105
209
|
return self._field_eval[field_key]
|
|
106
210
|
|
|
107
211
|
def evaluate_all_fields_at_nodes(self) -> dict[str,np.ndarray]:
|
|
108
|
-
|
|
212
|
+
"""_summary_
|
|
213
|
+
|
|
214
|
+
Returns
|
|
215
|
+
-------
|
|
216
|
+
dict[str,np.ndarray]
|
|
217
|
+
_description_
|
|
218
|
+
"""
|
|
219
|
+
(x_eval,y_eval,t_eval) = fill_dims_2d(self._coords[:,0],
|
|
109
220
|
self._coords[:,1],
|
|
110
221
|
self._case_data.time_steps)
|
|
111
222
|
eval_comps = dict()
|
|
@@ -118,7 +229,13 @@ class AnalyticSimDataGenerator:
|
|
|
118
229
|
|
|
119
230
|
|
|
120
231
|
def generate_sim_data(self) -> mh.SimData:
|
|
232
|
+
"""_summary_
|
|
121
233
|
|
|
234
|
+
Returns
|
|
235
|
+
-------
|
|
236
|
+
mh.SimData
|
|
237
|
+
_description_
|
|
238
|
+
"""
|
|
122
239
|
sim_data = mh.SimData()
|
|
123
240
|
sim_data.num_spat_dims = 2
|
|
124
241
|
sim_data.time = self._case_data.time_steps
|
|
@@ -136,7 +253,20 @@ class AnalyticSimDataGenerator:
|
|
|
136
253
|
field_key: str | None = None,
|
|
137
254
|
time_step: int = -1
|
|
138
255
|
) -> tuple[np.ndarray,np.ndarray,np.ndarray]:
|
|
139
|
-
|
|
256
|
+
"""_summary_
|
|
257
|
+
|
|
258
|
+
Parameters
|
|
259
|
+
----------
|
|
260
|
+
field_key : str | None, optional
|
|
261
|
+
_description_, by default None
|
|
262
|
+
time_step : int, optional
|
|
263
|
+
_description_, by default -1
|
|
264
|
+
|
|
265
|
+
Returns
|
|
266
|
+
-------
|
|
267
|
+
tuple[np.ndarray,np.ndarray,np.ndarray]
|
|
268
|
+
_description_
|
|
269
|
+
"""
|
|
140
270
|
if field_key is None:
|
|
141
271
|
field_key = self._case_data.field_keys[0]
|
|
142
272
|
|
|
@@ -1,18 +1,17 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
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.
|
|
10
|
-
from pyvale.
|
|
11
|
-
from pyvale.
|
|
12
|
-
from pyvale.
|
|
13
|
-
from pyvale.
|
|
14
|
-
from pyvale.
|
|
15
|
-
from pyvale.
|
|
8
|
+
from pyvale.field import IField
|
|
9
|
+
from pyvale.sensorarray import ISensorArray
|
|
10
|
+
from pyvale.errorintegrator import ErrIntegrator
|
|
11
|
+
from pyvale.sensordescriptor import SensorDescriptor
|
|
12
|
+
from pyvale.fieldsampler import sample_field_with_sensor_data
|
|
13
|
+
from pyvale.cameradata2d import CameraData2D
|
|
14
|
+
from pyvale.cameratools import CameraTools
|
|
16
15
|
|
|
17
16
|
|
|
18
17
|
# NOTE: This module is a feature under developement.
|
|
@@ -1,28 +1,15 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
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, field
|
|
9
8
|
import numpy as np
|
|
10
9
|
from scipy.spatial.transform import Rotation
|
|
11
10
|
|
|
12
11
|
|
|
13
12
|
# NOTE: This module is a feature under developement.
|
|
14
|
-
#
|
|
15
|
-
# - Camera Local Coords: Pixel positions in pixels/meters
|
|
16
|
-
# - Global Sim Coords: Transform from local pixel positions to sim coords in meters
|
|
17
|
-
# - For this transformation we need user to specify center of ROI in sim coords
|
|
18
|
-
# - There are going to be different ways to specify the camera properties
|
|
19
|
-
|
|
20
|
-
# For thin lens theory will need to know some combination of:
|
|
21
|
-
# - The focal length of the lense
|
|
22
|
-
# - The working distance
|
|
23
|
-
|
|
24
|
-
# Will need to create different ways for the user to automatically position the
|
|
25
|
-
# camera
|
|
26
13
|
|
|
27
14
|
|
|
28
15
|
@dataclass(slots=True)
|
|
@@ -1,14 +1,14 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
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, field
|
|
9
8
|
import numpy as np
|
|
10
9
|
from scipy.spatial.transform import Rotation
|
|
11
10
|
|
|
11
|
+
# NOTE: This module is a feature under developement.
|
|
12
12
|
|
|
13
13
|
@dataclass(slots=True)
|
|
14
14
|
class CameraData2D:
|