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.
- pyvale/__init__.py +12 -92
- pyvale/blender/__init__.py +23 -0
- pyvale/{pyvaleexceptions.py → blender/blenderexceptions.py} +0 -3
- pyvale/{blenderlightdata.py → blender/blenderlightdata.py} +3 -3
- pyvale/{blendermaterialdata.py → blender/blendermaterialdata.py} +1 -1
- pyvale/{blenderrenderdata.py → blender/blenderrenderdata.py} +5 -3
- pyvale/{blenderscene.py → blender/blenderscene.py} +33 -30
- pyvale/{blendertools.py → blender/blendertools.py} +14 -10
- pyvale/dataset/__init__.py +7 -0
- pyvale/dataset/dataset.py +443 -0
- pyvale/dic/__init__.py +20 -0
- pyvale/{dic2d.py → dic/dic2d.py} +31 -36
- pyvale/dic/dic2dconv.py +6 -0
- pyvale/{dic2dcpp.cp311-win_amd64.pyd → dic/dic2dcpp.cp311-win_amd64.pyd} +0 -0
- pyvale/{dicdataimport.py → dic/dicdataimport.py} +8 -8
- pyvale/{dicregionofinterest.py → dic/dicregionofinterest.py} +1 -1
- pyvale/{dicresults.py → dic/dicresults.py} +1 -1
- pyvale/{dicstrain.py → dic/dicstrain.py} +9 -9
- pyvale/examples/basics/{ex1_1_basicscalars_therm2d.py → ex1a_basicscalars_therm2d.py} +12 -9
- pyvale/examples/basics/{ex1_2_sensormodel_therm2d.py → ex1b_sensormodel_therm2d.py} +17 -14
- pyvale/examples/basics/{ex1_3_customsens_therm3d.py → ex1c_customsens_therm3d.py} +27 -24
- pyvale/examples/basics/{ex1_4_basicerrors_therm3d.py → ex1d_basicerrors_therm3d.py} +32 -29
- pyvale/examples/basics/{ex1_5_fielderrs_therm3d.py → ex1e_fielderrs_therm3d.py} +19 -15
- pyvale/examples/basics/{ex1_6_caliberrs_therm2d.py → ex1f_caliberrs_therm2d.py} +20 -16
- pyvale/examples/basics/{ex1_7_spatavg_therm2d.py → ex1g_spatavg_therm2d.py} +19 -16
- pyvale/examples/basics/{ex2_1_basicvectors_disp2d.py → ex2a_basicvectors_disp2d.py} +13 -10
- pyvale/examples/basics/{ex2_2_vectorsens_disp2d.py → ex2b_vectorsens_disp2d.py} +19 -15
- pyvale/examples/basics/{ex2_3_sensangle_disp2d.py → ex2c_sensangle_disp2d.py} +21 -18
- pyvale/examples/basics/{ex2_4_chainfielderrs_disp2d.py → ex2d_chainfielderrs_disp2d.py} +31 -29
- pyvale/examples/basics/{ex2_5_vectorfields3d_disp3d.py → ex2e_vectorfields3d_disp3d.py} +21 -18
- pyvale/examples/basics/{ex3_1_basictensors_strain2d.py → ex3a_basictensors_strain2d.py} +16 -14
- pyvale/examples/basics/{ex3_2_tensorsens2d_strain2d.py → ex3b_tensorsens2d_strain2d.py} +17 -14
- pyvale/examples/basics/{ex3_3_tensorsens3d_strain3d.py → ex3c_tensorsens3d_strain3d.py} +25 -22
- pyvale/examples/basics/{ex4_1_expsim2d_thermmech2d.py → ex4a_expsim2d_thermmech2d.py} +17 -14
- pyvale/examples/basics/{ex4_2_expsim3d_thermmech3d.py → ex4b_expsim3d_thermmech3d.py} +37 -34
- pyvale/examples/basics/ex5_nomesh.py +24 -0
- pyvale/examples/dic/ex1_2_blenderdeformed.py +174 -0
- pyvale/examples/dic/ex1_region_of_interest.py +6 -3
- pyvale/examples/dic/ex2_plate_with_hole.py +21 -18
- pyvale/examples/dic/ex3_plate_with_hole_strain.py +8 -6
- pyvale/examples/dic/ex4_dic_blender.py +17 -15
- pyvale/examples/dic/ex5_dic_challenge.py +19 -14
- pyvale/examples/genanalyticdata/ex1_1_scalarvisualisation.py +16 -10
- pyvale/examples/genanalyticdata/ex1_2_scalarcasebuild.py +3 -3
- pyvale/examples/genanalyticdata/ex2_1_analyticsensors.py +29 -23
- pyvale/examples/genanalyticdata/ex2_2_analyticsensors_nomesh.py +67 -0
- pyvale/examples/imagedef2d/ex_imagedef2d_todisk.py +12 -9
- pyvale/examples/mooseherder/ex0_create_moose_config.py +65 -0
- pyvale/examples/mooseherder/ex1a_modify_moose_input.py +71 -0
- pyvale/examples/mooseherder/ex1b_modify_gmsh_input.py +69 -0
- pyvale/examples/mooseherder/ex2a_run_moose_once.py +80 -0
- pyvale/examples/mooseherder/ex2b_run_gmsh_once.py +64 -0
- pyvale/examples/mooseherder/ex2c_run_both_once.py +114 -0
- pyvale/examples/mooseherder/ex3_run_moose_seq_para.py +157 -0
- pyvale/examples/mooseherder/ex4_run_gmsh-moose_seq_para.py +176 -0
- pyvale/examples/mooseherder/ex5_run_moose_paramulti.py +136 -0
- pyvale/examples/mooseherder/ex6_read_moose_exodus.py +163 -0
- pyvale/examples/mooseherder/ex7a_read_moose_herd_results.py +153 -0
- pyvale/examples/mooseherder/ex7b_read_multi_herd_results.py +116 -0
- pyvale/examples/mooseherder/ex7c_read_multi_gmshmoose_results.py +127 -0
- pyvale/examples/mooseherder/ex7d_readconfig_multi_gmshmoose_results.py +143 -0
- pyvale/examples/mooseherder/ex8_read_existing_sweep_output.py +72 -0
- pyvale/examples/renderblender/ex1_1_blenderscene.py +24 -20
- pyvale/examples/renderblender/ex1_2_blenderdeformed.py +22 -18
- pyvale/examples/renderblender/ex2_1_stereoscene.py +36 -29
- pyvale/examples/renderblender/ex2_2_stereodeformed.py +26 -20
- pyvale/examples/renderblender/ex3_1_blendercalibration.py +24 -17
- pyvale/examples/renderrasterisation/ex_rastenp.py +14 -12
- pyvale/examples/renderrasterisation/ex_rastercyth_oneframe.py +14 -15
- pyvale/examples/renderrasterisation/ex_rastercyth_static_cypara.py +13 -11
- pyvale/examples/renderrasterisation/ex_rastercyth_static_pypara.py +13 -11
- pyvale/mooseherder/__init__.py +32 -0
- pyvale/mooseherder/directorymanager.py +416 -0
- pyvale/mooseherder/exodusreader.py +763 -0
- pyvale/mooseherder/gmshrunner.py +163 -0
- pyvale/mooseherder/inputmodifier.py +236 -0
- pyvale/mooseherder/mooseconfig.py +226 -0
- pyvale/mooseherder/mooseherd.py +527 -0
- pyvale/mooseherder/mooserunner.py +303 -0
- pyvale/mooseherder/outputreader.py +22 -0
- pyvale/mooseherder/simdata.py +92 -0
- pyvale/mooseherder/simrunner.py +31 -0
- pyvale/mooseherder/sweepreader.py +356 -0
- pyvale/mooseherder/sweeptools.py +76 -0
- pyvale/sensorsim/__init__.py +82 -0
- pyvale/{camera.py → sensorsim/camera.py} +7 -7
- pyvale/{camerasensor.py → sensorsim/camerasensor.py} +7 -7
- pyvale/{camerastereo.py → sensorsim/camerastereo.py} +2 -2
- pyvale/{cameratools.py → sensorsim/cameratools.py} +4 -4
- pyvale/{cython → sensorsim/cython}/rastercyth.c +596 -596
- pyvale/{cython → sensorsim/cython}/rastercyth.cp311-win_amd64.pyd +0 -0
- pyvale/{cython → sensorsim/cython}/rastercyth.py +16 -17
- pyvale/{errorcalculator.py → sensorsim/errorcalculator.py} +1 -1
- pyvale/{errorintegrator.py → sensorsim/errorintegrator.py} +2 -2
- pyvale/{errorrand.py → sensorsim/errorrand.py} +4 -4
- pyvale/{errorsyscalib.py → sensorsim/errorsyscalib.py} +2 -2
- pyvale/{errorsysdep.py → sensorsim/errorsysdep.py} +2 -2
- pyvale/{errorsysfield.py → sensorsim/errorsysfield.py} +8 -8
- pyvale/{errorsysindep.py → sensorsim/errorsysindep.py} +3 -3
- pyvale/sensorsim/exceptions.py +8 -0
- pyvale/{experimentsimulator.py → sensorsim/experimentsimulator.py} +23 -3
- pyvale/{field.py → sensorsim/field.py} +1 -1
- pyvale/{fieldconverter.py → sensorsim/fieldconverter.py} +72 -19
- pyvale/sensorsim/fieldinterp.py +37 -0
- pyvale/sensorsim/fieldinterpmesh.py +124 -0
- pyvale/sensorsim/fieldinterppoints.py +55 -0
- pyvale/{fieldsampler.py → sensorsim/fieldsampler.py} +4 -4
- pyvale/{fieldscalar.py → sensorsim/fieldscalar.py} +28 -24
- pyvale/{fieldtensor.py → sensorsim/fieldtensor.py} +33 -31
- pyvale/{fieldvector.py → sensorsim/fieldvector.py} +33 -31
- pyvale/{imagedef2d.py → sensorsim/imagedef2d.py} +9 -5
- pyvale/{integratorfactory.py → sensorsim/integratorfactory.py} +6 -6
- pyvale/{integratorquadrature.py → sensorsim/integratorquadrature.py} +3 -3
- pyvale/{integratorrectangle.py → sensorsim/integratorrectangle.py} +3 -3
- pyvale/{integratorspatial.py → sensorsim/integratorspatial.py} +1 -1
- pyvale/{rastercy.py → sensorsim/rastercy.py} +5 -5
- pyvale/{rasternp.py → sensorsim/rasternp.py} +9 -9
- pyvale/{rasteropts.py → sensorsim/rasteropts.py} +1 -1
- pyvale/{renderer.py → sensorsim/renderer.py} +1 -1
- pyvale/{rendermesh.py → sensorsim/rendermesh.py} +5 -5
- pyvale/{renderscene.py → sensorsim/renderscene.py} +2 -2
- pyvale/{sensorarray.py → sensorsim/sensorarray.py} +1 -1
- pyvale/{sensorarrayfactory.py → sensorsim/sensorarrayfactory.py} +12 -12
- pyvale/{sensorarraypoint.py → sensorsim/sensorarraypoint.py} +10 -8
- pyvale/{sensordata.py → sensorsim/sensordata.py} +1 -1
- pyvale/{sensortools.py → sensorsim/sensortools.py} +2 -20
- pyvale/sensorsim/simtools.py +174 -0
- pyvale/{visualexpplotter.py → sensorsim/visualexpplotter.py} +3 -3
- pyvale/{visualimages.py → sensorsim/visualimages.py} +2 -2
- pyvale/{visualsimanimator.py → sensorsim/visualsimanimator.py} +4 -4
- pyvale/{visualsimplotter.py → sensorsim/visualsimplotter.py} +5 -5
- pyvale/{visualsimsensors.py → sensorsim/visualsimsensors.py} +12 -12
- pyvale/{visualtools.py → sensorsim/visualtools.py} +1 -1
- pyvale/{visualtraceplotter.py → sensorsim/visualtraceplotter.py} +2 -2
- pyvale/simcases/case17.geo +3 -0
- pyvale/simcases/case17.i +4 -4
- pyvale/simcases/run_1case.py +1 -9
- pyvale/simcases/run_all_cases.py +1 -1
- pyvale/simcases/run_build_case.py +1 -1
- pyvale/simcases/run_example_cases.py +1 -1
- pyvale/verif/__init__.py +12 -0
- pyvale/{analyticsimdatafactory.py → verif/analyticsimdatafactory.py} +2 -2
- pyvale/{analyticsimdatagenerator.py → verif/analyticsimdatagenerator.py} +2 -2
- pyvale/verif/psens.py +125 -0
- pyvale/verif/psensconst.py +18 -0
- pyvale/verif/psensmech.py +227 -0
- pyvale/verif/psensmultiphys.py +187 -0
- pyvale/verif/psensscalar.py +347 -0
- pyvale/verif/psenstensor.py +123 -0
- pyvale/verif/psensvector.py +116 -0
- {pyvale-2025.7.2.dist-info → pyvale-2025.8.1.dist-info}/METADATA +6 -7
- pyvale-2025.8.1.dist-info/RECORD +260 -0
- pyvale/dataset.py +0 -415
- pyvale/simtools.py +0 -67
- pyvale-2025.7.2.dist-info/RECORD +0 -212
- /pyvale/{blendercalibrationdata.py → blender/blendercalibrationdata.py} +0 -0
- /pyvale/{dicchecks.py → dic/dicchecks.py} +0 -0
- /pyvale/{dicspecklegenerator.py → dic/dicspecklegenerator.py} +0 -0
- /pyvale/{dicspecklequality.py → dic/dicspecklequality.py} +0 -0
- /pyvale/{dicstrainresults.py → dic/dicstrainresults.py} +0 -0
- /pyvale/{cameradata.py → sensorsim/cameradata.py} +0 -0
- /pyvale/{cameradata2d.py → sensorsim/cameradata2d.py} +0 -0
- /pyvale/{errordriftcalc.py → sensorsim/errordriftcalc.py} +0 -0
- /pyvale/{fieldtransform.py → sensorsim/fieldtransform.py} +0 -0
- /pyvale/{generatorsrandom.py → sensorsim/generatorsrandom.py} +0 -0
- /pyvale/{imagetools.py → sensorsim/imagetools.py} +0 -0
- /pyvale/{integratortype.py → sensorsim/integratortype.py} +0 -0
- /pyvale/{output.py → sensorsim/output.py} +0 -0
- /pyvale/{raster.py → sensorsim/raster.py} +0 -0
- /pyvale/{sensordescriptor.py → sensorsim/sensordescriptor.py} +0 -0
- /pyvale/{visualimagedef.py → sensorsim/visualimagedef.py} +0 -0
- /pyvale/{visualopts.py → sensorsim/visualopts.py} +0 -0
- /pyvale/{analyticmeshgen.py → verif/analyticmeshgen.py} +0 -0
- {pyvale-2025.7.2.dist-info → pyvale-2025.8.1.dist-info}/WHEEL +0 -0
- {pyvale-2025.7.2.dist-info → pyvale-2025.8.1.dist-info}/licenses/LICENSE +0 -0
- {pyvale-2025.7.2.dist-info → pyvale-2025.8.1.dist-info}/top_level.txt +0 -0
|
@@ -18,8 +18,11 @@ Test case: Scalar field point sensors (thermocouples) on a 2D thermal simulation
|
|
|
18
18
|
|
|
19
19
|
from pathlib import Path
|
|
20
20
|
import matplotlib.pyplot as plt
|
|
21
|
-
|
|
22
|
-
|
|
21
|
+
|
|
22
|
+
# Pyvale imports
|
|
23
|
+
import pyvale.sensorsim as sens
|
|
24
|
+
import pyvale.mooseherder as mh
|
|
25
|
+
import pyvale.dataset as dataset
|
|
23
26
|
|
|
24
27
|
#%%
|
|
25
28
|
# Here we load a pre-generated MOOSE finite element simulation dataset that
|
|
@@ -28,13 +31,13 @@ import pyvale as pyv
|
|
|
28
31
|
# to your own MOOSE simulation with exodus output (*.e). Note that the
|
|
29
32
|
# field_key must match the name of your variable in your MOOSE simulation.
|
|
30
33
|
# We use `mooseherder` to load the exodus file into a `SimData` object.
|
|
31
|
-
data_path =
|
|
34
|
+
data_path = dataset.thermal_2d_path()
|
|
32
35
|
sim_data = mh.ExodusReader(data_path).read_all_sim_data()
|
|
33
36
|
|
|
34
37
|
#%%
|
|
35
38
|
# Scale to mm to make 3D visualisation scaling easier as pyvista scales
|
|
36
39
|
# everything to unity
|
|
37
|
-
sim_data =
|
|
40
|
+
sim_data = sens.scale_length_units(scale=1000.0,
|
|
38
41
|
sim_data=sim_data,
|
|
39
42
|
disp_comps=None)
|
|
40
43
|
|
|
@@ -46,14 +49,14 @@ n_sens = (3,2,1)
|
|
|
46
49
|
x_lims = (0.0,100.0)
|
|
47
50
|
y_lims = (0.0,50.0)
|
|
48
51
|
z_lims = (0.0,0.0)
|
|
49
|
-
sens_pos =
|
|
52
|
+
sens_pos = sens.create_sensor_pos_array(n_sens,x_lims,y_lims,z_lims)
|
|
50
53
|
|
|
51
54
|
#%%
|
|
52
55
|
# This dataclass contains the parameters to build our sensor array. We can
|
|
53
56
|
# also customise the output frequency, the sensor area and the sensor
|
|
54
57
|
# orientation. For now we will use the defaults which assumes an ideal point
|
|
55
58
|
# sensor sampling at the simulation time steps.
|
|
56
|
-
sens_data =
|
|
59
|
+
sens_data = sens.SensorData(positions=sens_pos)
|
|
57
60
|
|
|
58
61
|
#%%
|
|
59
62
|
# Now that we have our sensor locations we can use the sensor factory to
|
|
@@ -63,7 +66,7 @@ sens_data = pyv.SensorData(positions=sens_pos)
|
|
|
63
66
|
# If you want to remove the simulated errors and just interpolate at the
|
|
64
67
|
# sensor locations then user `.thermocouples_no_errs()`.
|
|
65
68
|
field_key: str = "temperature"
|
|
66
|
-
tc_array =
|
|
69
|
+
tc_array = sens.SensorArrayFactory \
|
|
67
70
|
.thermocouples_basic_errs(sim_data,
|
|
68
71
|
sens_data,
|
|
69
72
|
elem_dims=2,
|
|
@@ -93,7 +96,7 @@ if not output_path.is_dir():
|
|
|
93
96
|
# This creates a pyvista visualisation of the sensor locations on the
|
|
94
97
|
# simulation mesh. The plot will can be shown in interactive mode by calling
|
|
95
98
|
# `pv_plot.show()`.
|
|
96
|
-
pv_plot =
|
|
99
|
+
pv_plot = sens.plot_point_sensors_on_sim(tc_array,field_key)
|
|
97
100
|
|
|
98
101
|
#%%
|
|
99
102
|
# We determined manually by moving camera in interative mode and then
|
|
@@ -125,7 +128,7 @@ print(80*"-"+"\n")
|
|
|
125
128
|
# markers shows the simulated sensor traces. In later examples we will see
|
|
126
129
|
# how to configure this plot but for now we note we that we are returned a
|
|
127
130
|
# matplotlib figure and axes object which allows for further customisation.
|
|
128
|
-
(fig,ax) =
|
|
131
|
+
(fig,ax) = sens.plot_time_traces(tc_array,field_key)
|
|
129
132
|
|
|
130
133
|
#%%
|
|
131
134
|
# We can also save the sensor trace plot as a vector and raster graphic
|
|
@@ -29,8 +29,11 @@ Test case: Scalar field point sensors (thermocouples) on a 2D thermal simulation
|
|
|
29
29
|
"""
|
|
30
30
|
|
|
31
31
|
import matplotlib.pyplot as plt
|
|
32
|
-
|
|
33
|
-
|
|
32
|
+
|
|
33
|
+
# Pyvale imports
|
|
34
|
+
import pyvale.sensorsim as sens
|
|
35
|
+
import pyvale.mooseherder as mh
|
|
36
|
+
import pyvale.dataset as dataset
|
|
34
37
|
|
|
35
38
|
|
|
36
39
|
#%%
|
|
@@ -40,14 +43,14 @@ import pyvale as pyv
|
|
|
40
43
|
# Here we load a pre-generated MOOSE finite element simulation dataset that
|
|
41
44
|
# comes packaged with pyvale. The simulation is a 2D rectangular plate with
|
|
42
45
|
# a bi-directional temperature gradient.
|
|
43
|
-
data_path =
|
|
46
|
+
data_path = dataset.thermal_2d_path()
|
|
44
47
|
sim_data = mh.ExodusReader(data_path).read_all_sim_data()
|
|
45
48
|
field_key: str = "temperature"
|
|
46
49
|
|
|
47
50
|
#%%
|
|
48
51
|
# Scale to mm to make 3D visualisation scaling easier as pyvista scales
|
|
49
52
|
# everything to unity
|
|
50
|
-
sim_data =
|
|
53
|
+
sim_data = sens.scale_length_units(scale=1000.0,
|
|
51
54
|
sim_data=sim_data,
|
|
52
55
|
disp_comps=None)
|
|
53
56
|
|
|
@@ -59,14 +62,14 @@ n_sens = (4,1,1)
|
|
|
59
62
|
x_lims = (0.0,100.0)
|
|
60
63
|
y_lims = (0.0,50.0)
|
|
61
64
|
z_lims = (0.0,0.0)
|
|
62
|
-
sens_pos =
|
|
65
|
+
sens_pos = sens.create_sensor_pos_array(n_sens,x_lims,y_lims,z_lims)
|
|
63
66
|
|
|
64
67
|
#%%
|
|
65
68
|
# This dataclass contains the parameters to build our sensor array. We can
|
|
66
69
|
# also customise the output frequency, the sensor area and the sensor
|
|
67
70
|
# orientation. For now we will use the defaults which assumes an ideal point
|
|
68
71
|
# sensor sampling at the simulation time steps.
|
|
69
|
-
sens_data =
|
|
72
|
+
sens_data = sens.SensorData(positions=sens_pos)
|
|
70
73
|
|
|
71
74
|
#%%
|
|
72
75
|
# Now that we have our sensor locations we can use the sensor factory to
|
|
@@ -74,7 +77,7 @@ sens_data = pyv.SensorData(positions=sens_pos)
|
|
|
74
77
|
# examples we will see how to customise sensor parameters and errors.
|
|
75
78
|
# This basic thermocouple array includes a 5% systematic and random error -
|
|
76
79
|
# We are specifically using exaggerated errors here for visualisation.
|
|
77
|
-
tc_array =
|
|
80
|
+
tc_array = sens.SensorArrayFactory \
|
|
78
81
|
.thermocouples_basic_errs(sim_data,
|
|
79
82
|
sens_data,
|
|
80
83
|
elem_dims=2,
|
|
@@ -111,16 +114,16 @@ print(80*"-")
|
|
|
111
114
|
print(f"Looking at the last {time_last} virtual measurements for sensor"
|
|
112
115
|
+f" {sens_print}:")
|
|
113
116
|
|
|
114
|
-
|
|
117
|
+
sens.print_measurements(tc_array,sens_print,comp_print,time_print)
|
|
115
118
|
|
|
116
119
|
print(80*"-")
|
|
117
120
|
print("If we call the `calc_measurements()` method then the errors are "
|
|
118
121
|
+ "re-calculated.")
|
|
119
122
|
measurements = tc_array.calc_measurements()
|
|
120
123
|
|
|
121
|
-
|
|
124
|
+
sens.print_measurements(tc_array,sens_print,comp_print,time_print)
|
|
122
125
|
|
|
123
|
-
(fig,ax) =
|
|
126
|
+
(fig,ax) = sens.plot_time_traces(tc_array,field_key)
|
|
124
127
|
ax.set_title("Exp 1: called calc_measurements()")
|
|
125
128
|
|
|
126
129
|
print(80*"-")
|
|
@@ -128,9 +131,9 @@ print("If we call the `get_measurements()` method then the errors are the "
|
|
|
128
131
|
+ "same:")
|
|
129
132
|
measurements = tc_array.get_measurements()
|
|
130
133
|
|
|
131
|
-
|
|
134
|
+
sens.print_measurements(tc_array,sens_print,comp_print,time_print)
|
|
132
135
|
|
|
133
|
-
(fig,ax) =
|
|
136
|
+
(fig,ax) = sens.plot_time_traces(tc_array,field_key)
|
|
134
137
|
ax.set_title("Exp 2: called get_measurements()")
|
|
135
138
|
|
|
136
139
|
print(80*"-")
|
|
@@ -138,9 +141,9 @@ print("If we call the `calc_measurements()` method again we generate / "
|
|
|
138
141
|
"sample new errors:")
|
|
139
142
|
measurements = tc_array.calc_measurements()
|
|
140
143
|
|
|
141
|
-
|
|
144
|
+
sens.print_measurements(tc_array,sens_print,comp_print,time_print)
|
|
142
145
|
|
|
143
|
-
(fig,ax) =
|
|
146
|
+
(fig,ax) = sens.plot_time_traces(tc_array,field_key)
|
|
144
147
|
ax.set_title("Exp 3: called calc_measurements()")
|
|
145
148
|
|
|
146
149
|
print(80*"-")
|
|
@@ -18,8 +18,11 @@ Test case: Scalar field point sensors (thermocouples) on a 3D thermal simulation
|
|
|
18
18
|
from pathlib import Path
|
|
19
19
|
import numpy as np
|
|
20
20
|
import matplotlib.pyplot as plt
|
|
21
|
-
|
|
22
|
-
|
|
21
|
+
|
|
22
|
+
# Pyvale imports
|
|
23
|
+
import pyvale.mooseherder as mh
|
|
24
|
+
import pyvale.sensorsim as sens
|
|
25
|
+
import pyvale.dataset as dataset
|
|
23
26
|
|
|
24
27
|
#%%
|
|
25
28
|
# To build our custom point sensor array we need to at minimum provide a
|
|
@@ -32,9 +35,9 @@ import pyvale as pyv
|
|
|
32
35
|
# based on the same thermal example we have used in the last two examples so
|
|
33
36
|
# we start by loading our simulation data:
|
|
34
37
|
|
|
35
|
-
data_path =
|
|
38
|
+
data_path = dataset.thermal_3d_path()
|
|
36
39
|
sim_data = mh.ExodusReader(data_path).read_all_sim_data()
|
|
37
|
-
sim_data =
|
|
40
|
+
sim_data = sens.scale_length_units(scale=1000.0,
|
|
38
41
|
sim_data=sim_data,
|
|
39
42
|
disp_comps=None)
|
|
40
43
|
|
|
@@ -43,7 +46,7 @@ sim_data = pyv.scale_length_units(scale=1000.0,
|
|
|
43
46
|
# field object to perform interpolation to the sensor locations at the
|
|
44
47
|
# desired sampling times.
|
|
45
48
|
field_key: str = "temperature"
|
|
46
|
-
t_field =
|
|
49
|
+
t_field = sens.FieldScalar(sim_data,
|
|
47
50
|
field_key=field_key,
|
|
48
51
|
elem_dims=3)
|
|
49
52
|
|
|
@@ -56,7 +59,7 @@ n_sens = (1,4,1)
|
|
|
56
59
|
x_lims = (12.5,12.5)
|
|
57
60
|
y_lims = (0.0,33.0)
|
|
58
61
|
z_lims = (0.0,12.0)
|
|
59
|
-
sens_pos =
|
|
62
|
+
sens_pos = sens.create_sensor_pos_array(n_sens,x_lims,y_lims,z_lims)
|
|
60
63
|
|
|
61
64
|
#%%
|
|
62
65
|
# We are also going to specify the times at which we would like to simulate
|
|
@@ -64,8 +67,8 @@ sens_pos = pyv.create_sensor_pos_array(n_sens,x_lims,y_lims,z_lims)
|
|
|
64
67
|
# to match the simulation time steps.
|
|
65
68
|
sample_times = np.linspace(0.0,np.max(sim_data.time),50)
|
|
66
69
|
|
|
67
|
-
sensor_data =
|
|
68
|
-
|
|
70
|
+
sensor_data = sens.SensorData(positions=sens_pos,
|
|
71
|
+
sample_times=sample_times)
|
|
69
72
|
|
|
70
73
|
#%%
|
|
71
74
|
# Finally, we can create a `SensorDescriptor` which will be used to label
|
|
@@ -73,20 +76,20 @@ sensor_data = pyv.SensorData(positions=sens_pos,
|
|
|
73
76
|
# examples.
|
|
74
77
|
use_auto_descriptor: str = "blank"
|
|
75
78
|
if use_auto_descriptor == "manual":
|
|
76
|
-
descriptor =
|
|
79
|
+
descriptor = sens.SensorDescriptor(name="Temperature",
|
|
77
80
|
symbol="T",
|
|
78
81
|
units = r"^{\circ}C",
|
|
79
82
|
tag = "TC")
|
|
80
83
|
elif use_auto_descriptor == "factory":
|
|
81
|
-
descriptor =
|
|
84
|
+
descriptor = sens.SensorDescriptorFactory.temperature_descriptor()
|
|
82
85
|
else:
|
|
83
|
-
descriptor =
|
|
86
|
+
descriptor = sens.SensorDescriptor()
|
|
84
87
|
|
|
85
88
|
#%%
|
|
86
89
|
# We can now build our custom point sensor array. This sensor array has no
|
|
87
90
|
# errors so if we call `get_measurements()` or `calc_measurements()` we will
|
|
88
91
|
# be able to extract the simulation truth values at the sensor locations.
|
|
89
|
-
tc_array =
|
|
92
|
+
tc_array = sens.SensorArrayPoint(sensor_data,
|
|
90
93
|
t_field,
|
|
91
94
|
descriptor)
|
|
92
95
|
|
|
@@ -101,7 +104,7 @@ output_path = Path.cwd() / "pyvale-output"
|
|
|
101
104
|
if not output_path.is_dir():
|
|
102
105
|
output_path.mkdir(parents=True, exist_ok=True)
|
|
103
106
|
|
|
104
|
-
pv_plot =
|
|
107
|
+
pv_plot = sens.plot_point_sensors_on_sim(tc_array,field_key)
|
|
105
108
|
|
|
106
109
|
pv_plot.camera_position = [(59.354, 43.428, 69.946),
|
|
107
110
|
(-2.858, 13.189, 4.523),
|
|
@@ -149,8 +152,8 @@ errors_on = {"sys": True,
|
|
|
149
152
|
|
|
150
153
|
error_chain = []
|
|
151
154
|
if errors_on["sys"]:
|
|
152
|
-
error_chain.append(
|
|
153
|
-
error_chain.append(
|
|
155
|
+
error_chain.append(sens.ErrSysOffset(offset=-10.0))
|
|
156
|
+
error_chain.append(sens.ErrSysUnif(low=-10.0,
|
|
154
157
|
high=10.0))
|
|
155
158
|
#%%
|
|
156
159
|
# This random error is generated by sampling from a normal distribution
|
|
@@ -159,8 +162,8 @@ if errors_on["sys"]:
|
|
|
159
162
|
# probability distribution
|
|
160
163
|
|
|
161
164
|
if errors_on["rand"]:
|
|
162
|
-
error_chain.append(
|
|
163
|
-
error_chain.append(
|
|
165
|
+
error_chain.append(sens.ErrRandNorm(std=5.0))
|
|
166
|
+
error_chain.append(sens.ErrRandUnifPercent(low_percent=-5.0,
|
|
164
167
|
high_percent=5.0))
|
|
165
168
|
|
|
166
169
|
#%%
|
|
@@ -171,11 +174,11 @@ if errors_on["rand"]:
|
|
|
171
174
|
# INDEPENDENT.
|
|
172
175
|
|
|
173
176
|
if len(error_chain) > 0:
|
|
174
|
-
err_int_opts =
|
|
175
|
-
error_integrator =
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
177
|
+
err_int_opts = sens.ErrIntOpts()
|
|
178
|
+
error_integrator = sens.ErrIntegrator(error_chain,
|
|
179
|
+
sensor_data,
|
|
180
|
+
tc_array.get_measurement_shape(),
|
|
181
|
+
err_int_opts=err_int_opts)
|
|
179
182
|
tc_array.set_error_integrator(error_integrator)
|
|
180
183
|
|
|
181
184
|
#%%
|
|
@@ -204,11 +207,11 @@ time_print = slice(measurements.shape[2]-time_last,measurements.shape[2])
|
|
|
204
207
|
print(f"These are the last {time_last} virtual measurements of sensor "
|
|
205
208
|
+ f"{sens_print}:")
|
|
206
209
|
|
|
207
|
-
|
|
210
|
+
sens.print_measurements(tc_array,sens_print,comp_print,time_print)
|
|
208
211
|
|
|
209
212
|
print(80*"-")
|
|
210
213
|
|
|
211
|
-
(fig,ax) =
|
|
214
|
+
(fig,ax) = sens.plot_time_traces(tc_array,field_key)
|
|
212
215
|
|
|
213
216
|
save_traces = output_path/"customsensors_ex1_3_sensortraces.png"
|
|
214
217
|
fig.savefig(save_traces, dpi=300, bbox_inches="tight")
|
|
@@ -28,32 +28,35 @@ to your error chain.
|
|
|
28
28
|
|
|
29
29
|
import numpy as np
|
|
30
30
|
import matplotlib.pyplot as plt
|
|
31
|
-
|
|
32
|
-
|
|
31
|
+
|
|
32
|
+
# Pyvale imports
|
|
33
|
+
import pyvale.mooseherder as mh
|
|
34
|
+
import pyvale.sensorsim as sens
|
|
35
|
+
import pyvale.dataset as dataset
|
|
33
36
|
|
|
34
37
|
|
|
35
38
|
#%%
|
|
36
39
|
# First we use everything we learned from the first three examples to build
|
|
37
40
|
# a thermocouple sensor array for the same 3D thermal simulation we have
|
|
38
41
|
# analysed in the previous example.
|
|
39
|
-
data_path =
|
|
42
|
+
data_path = dataset.thermal_3d_path()
|
|
40
43
|
sim_data = mh.ExodusReader(data_path).read_all_sim_data()
|
|
41
|
-
sim_data =
|
|
44
|
+
sim_data = sens.scale_length_units(scale=1000.0,
|
|
42
45
|
sim_data=sim_data,
|
|
43
46
|
disp_comps=None)
|
|
44
47
|
n_sens = (1,4,1)
|
|
45
48
|
x_lims = (12.5,12.5)
|
|
46
49
|
y_lims = (0.0,33.0)
|
|
47
50
|
z_lims = (0.0,12.0)
|
|
48
|
-
sens_pos =
|
|
51
|
+
sens_pos = sens.create_sensor_pos_array(n_sens,x_lims,y_lims,z_lims)
|
|
49
52
|
|
|
50
53
|
sample_times = np.linspace(0.0,np.max(sim_data.time),50) # | None
|
|
51
54
|
|
|
52
|
-
sensor_data =
|
|
55
|
+
sensor_data = sens.SensorData(positions=sens_pos,
|
|
53
56
|
sample_times=sample_times)
|
|
54
57
|
|
|
55
58
|
field_key: str = "temperature"
|
|
56
|
-
tc_array =
|
|
59
|
+
tc_array = sens.SensorArrayFactory \
|
|
57
60
|
.thermocouples_no_errs(sim_data,
|
|
58
61
|
sensor_data,
|
|
59
62
|
elem_dims=3,
|
|
@@ -73,61 +76,61 @@ err_chain = []
|
|
|
73
76
|
#
|
|
74
77
|
# These systematic errors provide a constant offset to all measurements in
|
|
75
78
|
# simulation units or as a percentage.
|
|
76
|
-
err_chain.append(
|
|
77
|
-
err_chain.append(
|
|
79
|
+
err_chain.append(sens.ErrSysOffset(offset=-10.0))
|
|
80
|
+
err_chain.append(sens.ErrSysOffsetPercent(offset_percent=-1.0))
|
|
78
81
|
|
|
79
82
|
#%%
|
|
80
83
|
# These systematic errors are sampled from a uniform or normal probability
|
|
81
84
|
# distribution either in simulation units or as a percentage.
|
|
82
|
-
err_chain.append(
|
|
85
|
+
err_chain.append(sens.ErrSysUnif(low=-1.0,
|
|
83
86
|
high=1.0))
|
|
84
|
-
err_chain.append(
|
|
87
|
+
err_chain.append(sens.ErrSysUnifPercent(low_percent=-1.0,
|
|
85
88
|
high_percent=1.0))
|
|
86
|
-
err_chain.append(
|
|
87
|
-
err_chain.append(
|
|
89
|
+
err_chain.append(sens.ErrSysNorm(std=1.0))
|
|
90
|
+
err_chain.append(sens.ErrSysNormPercent(std_percent=1.0))
|
|
88
91
|
|
|
89
92
|
#%%
|
|
90
93
|
# pyvale includes a series of random number generator objects that wrap the
|
|
91
94
|
# random number generators from numpy. These are named `Gen*` and can be
|
|
92
95
|
# used with an `ErrSysGen` or an `ErrSysGenPercent` object to create custom
|
|
93
96
|
# probability distribution sampling errors:
|
|
94
|
-
sys_gen =
|
|
97
|
+
sys_gen = sens.GenTriangular(left=-1.0,
|
|
95
98
|
mode=0.0,
|
|
96
99
|
right=1.0)
|
|
97
|
-
err_chain.append(
|
|
100
|
+
err_chain.append(sens.ErrSysGen(sys_gen))
|
|
98
101
|
|
|
99
102
|
#%%
|
|
100
103
|
# We can also build the equivalent of `ErrSysUnifPercent` above using a
|
|
101
104
|
# `Gen` object inserted into an `ErrSysGenPercent` object:
|
|
102
|
-
unif_gen =
|
|
105
|
+
unif_gen = sens.GenUniform(low=-1.0,
|
|
103
106
|
high=1.0)
|
|
104
|
-
err_chain.append(
|
|
107
|
+
err_chain.append(sens.ErrSysGenPercent(unif_gen))
|
|
105
108
|
|
|
106
109
|
#%%
|
|
107
110
|
# We can also add a series of random errors in a similar manner to the
|
|
108
111
|
# systematic errors above noting that these will generate a new error for
|
|
109
112
|
# each sensor and each time step whereas the systematic error sampling
|
|
110
113
|
# provides a constant shift over all sampling times for each sensor.
|
|
111
|
-
err_chain.append(
|
|
112
|
-
err_chain.append(
|
|
113
|
-
err_chain.append(
|
|
114
|
-
err_chain.append(
|
|
114
|
+
err_chain.append(sens.ErrRandNorm(std = 2.0))
|
|
115
|
+
err_chain.append(sens.ErrRandNormPercent(std_percent=2.0))
|
|
116
|
+
err_chain.append(sens.ErrRandUnif(low=-2.0,high=2.0))
|
|
117
|
+
err_chain.append(sens.ErrRandUnifPercent(low_percent=-2.0,
|
|
115
118
|
high_percent=2.0))
|
|
116
|
-
rand_gen =
|
|
119
|
+
rand_gen = sens.GenTriangular(left=-5.0,
|
|
117
120
|
mode=0.0,
|
|
118
121
|
right=5.0)
|
|
119
|
-
err_chain.append(
|
|
122
|
+
err_chain.append(sens.ErrRandGen(rand_gen))
|
|
120
123
|
|
|
121
124
|
#%%
|
|
122
125
|
# Finally we add some dependent systematic errors including rounding errors,
|
|
123
126
|
# digitisation and saturation. Note that the saturation error must be placed
|
|
124
127
|
# last in the error chain. Try changing some of these values to see how the
|
|
125
128
|
# sensor traces change - particularly the saturation error.
|
|
126
|
-
err_chain.append(
|
|
127
|
-
err_chain.append(
|
|
128
|
-
err_chain.append(
|
|
129
|
+
err_chain.append(sens.ErrSysRoundOff(sens.ERoundMethod.ROUND,0.1))
|
|
130
|
+
err_chain.append(sens.ErrSysDigitisation(bits_per_unit=2**16/100))
|
|
131
|
+
err_chain.append(sens.ErrSysSaturation(meas_min=0.0,meas_max=400.0))
|
|
129
132
|
|
|
130
|
-
err_int =
|
|
133
|
+
err_int = sens.ErrIntegrator(err_chain,
|
|
131
134
|
sensor_data,
|
|
132
135
|
tc_array.get_measurement_shape())
|
|
133
136
|
tc_array.set_error_integrator(err_int)
|
|
@@ -148,10 +151,10 @@ time_print = slice(measurements.shape[2]-time_last,measurements.shape[2])
|
|
|
148
151
|
print(f"These are the last {time_last} virtual measurements of sensor "
|
|
149
152
|
+ f"{sens_print}:")
|
|
150
153
|
|
|
151
|
-
|
|
154
|
+
sens.print_measurements(tc_array,sens_print,comp_print,time_print)
|
|
152
155
|
|
|
153
156
|
print(80*"-")
|
|
154
157
|
|
|
155
|
-
|
|
158
|
+
sens.plot_time_traces(tc_array,field_key)
|
|
156
159
|
plt.show()
|
|
157
160
|
|
|
@@ -24,8 +24,12 @@ Test case: Scalar field point sensors (thermocouples) on a 3D thermal simulation
|
|
|
24
24
|
from pathlib import Path
|
|
25
25
|
import numpy as np
|
|
26
26
|
import matplotlib.pyplot as plt
|
|
27
|
-
|
|
28
|
-
|
|
27
|
+
|
|
28
|
+
# Pyvale imports
|
|
29
|
+
import pyvale.mooseherder as mh
|
|
30
|
+
import pyvale.sensorsim as sens
|
|
31
|
+
import pyvale.dataset as dataset
|
|
32
|
+
|
|
29
33
|
|
|
30
34
|
#%%
|
|
31
35
|
# First we use everything we learned from the first three examples to build
|
|
@@ -33,9 +37,9 @@ import pyvale as pyv
|
|
|
33
37
|
# analysed in the previous examples. Then we will look at a new type of
|
|
34
38
|
# systematic error called a field error which requires additional
|
|
35
39
|
# interpolation of the underlying physical field to be measured.
|
|
36
|
-
data_path =
|
|
40
|
+
data_path = dataset.thermal_3d_path()
|
|
37
41
|
sim_data = mh.ExodusReader(data_path).read_all_sim_data()
|
|
38
|
-
sim_data =
|
|
42
|
+
sim_data = sens.scale_length_units(scale=1000.0,
|
|
39
43
|
sim_data=sim_data,
|
|
40
44
|
disp_comps=None)
|
|
41
45
|
|
|
@@ -43,15 +47,15 @@ n_sens = (1,4,1)
|
|
|
43
47
|
x_lims = (12.5,12.5)
|
|
44
48
|
y_lims = (0.0,33.0)
|
|
45
49
|
z_lims = (0.0,12.0)
|
|
46
|
-
sens_pos =
|
|
50
|
+
sens_pos = sens.create_sensor_pos_array(n_sens,x_lims,y_lims,z_lims)
|
|
47
51
|
|
|
48
52
|
sample_times = np.linspace(0.0,np.max(sim_data.time),50) # | None
|
|
49
53
|
|
|
50
|
-
sensor_data =
|
|
54
|
+
sensor_data = sens.SensorData(positions=sens_pos,
|
|
51
55
|
sample_times=sample_times)
|
|
52
56
|
|
|
53
57
|
field_key: str = "temperature"
|
|
54
|
-
tc_array =
|
|
58
|
+
tc_array = sens.SensorArrayFactory \
|
|
55
59
|
.thermocouples_no_errs(sim_data,
|
|
56
60
|
sensor_data,
|
|
57
61
|
elem_dims=3,
|
|
@@ -76,8 +80,8 @@ time_offset = np.full((sample_times.shape[0],),0.1)
|
|
|
76
80
|
#%%
|
|
77
81
|
# Using the `Gen*` random generators in pyvale we can randomly perturb the
|
|
78
82
|
# position or sampling times of our virtual sensors.
|
|
79
|
-
pos_rand =
|
|
80
|
-
time_rand =
|
|
83
|
+
pos_rand = sens.GenNormal(std=1.0) # units = mm
|
|
84
|
+
time_rand = sens.GenNormal(std=0.1) # units = s
|
|
81
85
|
|
|
82
86
|
#%%
|
|
83
87
|
# Now we put everything into our field error data class ready to build our
|
|
@@ -85,7 +89,7 @@ time_rand = pyv.GenNormal(std=0.1) # units = s
|
|
|
85
89
|
# to geta feel for the other types of supported field errors. We will look
|
|
86
90
|
# at the orientation and area averaging errors when we look at vector and
|
|
87
91
|
# tensor fields in later examples.
|
|
88
|
-
field_err_data =
|
|
92
|
+
field_err_data = sens.ErrFieldData(
|
|
89
93
|
pos_offset_xyz=pos_offset_xyz,
|
|
90
94
|
time_offset=time_offset,
|
|
91
95
|
pos_rand_xyz=(None,pos_rand,pos_rand),
|
|
@@ -105,9 +109,9 @@ err_chain = []
|
|
|
105
109
|
# A field error needs to know which field it should interpolate for error
|
|
106
110
|
# calculations so we provide the field from the sensor array as well as the
|
|
107
111
|
# field error error data class.
|
|
108
|
-
err_chain.append(
|
|
112
|
+
err_chain.append(sens.ErrSysField(tc_array.get_field(),
|
|
109
113
|
field_err_data))
|
|
110
|
-
err_int =
|
|
114
|
+
err_int = sens.ErrIntegrator(err_chain,
|
|
111
115
|
sensor_data,
|
|
112
116
|
tc_array.get_measurement_shape())
|
|
113
117
|
tc_array.set_error_integrator(err_int)
|
|
@@ -128,7 +132,7 @@ time_print = slice(measurements.shape[2]-time_last,measurements.shape[2])
|
|
|
128
132
|
print(f"These are the last {time_last} virtual measurements of sensor "
|
|
129
133
|
+ f"{sens_print}:")
|
|
130
134
|
|
|
131
|
-
|
|
135
|
+
sens.print_measurements(tc_array,sens_print,comp_print,time_print)
|
|
132
136
|
|
|
133
137
|
print(80*"-")
|
|
134
138
|
|
|
@@ -142,7 +146,7 @@ if not output_path.is_dir():
|
|
|
142
146
|
#%%
|
|
143
147
|
# If we analyse the time traces we can see offsets in the sensor value and
|
|
144
148
|
# the sampling times which we expect from our field error setup.
|
|
145
|
-
(fig,ax) =
|
|
149
|
+
(fig,ax) = sens.plot_time_traces(tc_array,field_key)
|
|
146
150
|
|
|
147
151
|
save_traces = output_path/"field_ex1_5_sensortraces.png"
|
|
148
152
|
fig.savefig(save_traces, dpi=300, bbox_inches="tight")
|
|
@@ -153,7 +157,7 @@ plt.show()
|
|
|
153
157
|
#%%
|
|
154
158
|
# It is also possible to view the perturbed sensor locations on the
|
|
155
159
|
# simulation mesh if we create a plot after running the sensor simulation.
|
|
156
|
-
pv_plot =
|
|
160
|
+
pv_plot = sens.plot_point_sensors_on_sim(tc_array,field_key)
|
|
157
161
|
pv_plot.camera_position = [(59.354, 43.428, 69.946),
|
|
158
162
|
(-2.858, 13.189, 4.523),
|
|
159
163
|
(-0.215, 0.948, -0.233)]
|
|
@@ -16,8 +16,12 @@ Test case: Scalar field point sensors (thermocouples) on a 2D thermal simulation
|
|
|
16
16
|
|
|
17
17
|
import numpy as np
|
|
18
18
|
import matplotlib.pyplot as plt
|
|
19
|
-
|
|
20
|
-
|
|
19
|
+
|
|
20
|
+
# Pyvale imports
|
|
21
|
+
import pyvale.mooseherder as mh
|
|
22
|
+
import pyvale.sensorsim as sens
|
|
23
|
+
import pyvale.dataset as dataset
|
|
24
|
+
|
|
21
25
|
|
|
22
26
|
#%%
|
|
23
27
|
# First we need to define some calibration functions. These functions must take
|
|
@@ -27,11 +31,11 @@ import pyvale as pyv
|
|
|
27
31
|
# we can calculate the error between them. The calibration functions shown below
|
|
28
32
|
# are simplified versions of the typical calibration curves for a K-type
|
|
29
33
|
# thermocouple.
|
|
30
|
-
def
|
|
34
|
+
def calib_assumed(signal: np.ndarray) -> np.ndarray:
|
|
31
35
|
return 24.3*signal + 0.616
|
|
32
36
|
|
|
33
37
|
|
|
34
|
-
def
|
|
38
|
+
def calib_truth(signal: np.ndarray) -> np.ndarray:
|
|
35
39
|
return -0.01897 + 25.41881*signal - 0.42456*signal**2 + 0.04365*signal**3
|
|
36
40
|
|
|
37
41
|
|
|
@@ -46,8 +50,8 @@ signal_calib_range = np.array((0.0,6.0),dtype=np.float64)
|
|
|
46
50
|
milli_volts = np.linspace(signal_calib_range[0],
|
|
47
51
|
signal_calib_range[1],
|
|
48
52
|
n_cal_divs)
|
|
49
|
-
temp_truth =
|
|
50
|
-
temp_assumed =
|
|
53
|
+
temp_truth = calib_truth(milli_volts)
|
|
54
|
+
temp_assumed = calib_assumed(milli_volts)
|
|
51
55
|
calib_error = temp_assumed - temp_truth
|
|
52
56
|
|
|
53
57
|
print()
|
|
@@ -66,9 +70,9 @@ print()
|
|
|
66
70
|
# Now let's go back and build the 2D thermal plate with simulated
|
|
67
71
|
# thermocouples that we analysed in the first two examples. We use this
|
|
68
72
|
# simulation as the temperatures are within our calibrated range.
|
|
69
|
-
data_path =
|
|
73
|
+
data_path = dataset.thermal_2d_path()
|
|
70
74
|
sim_data = mh.ExodusReader(data_path).read_all_sim_data()
|
|
71
|
-
sim_data =
|
|
75
|
+
sim_data = sens.scale_length_units(scale=1000.0,
|
|
72
76
|
sim_data=sim_data,
|
|
73
77
|
disp_comps=None)
|
|
74
78
|
|
|
@@ -76,15 +80,15 @@ n_sens = (4,1,1)
|
|
|
76
80
|
x_lims = (0.0,100.0)
|
|
77
81
|
y_lims = (0.0,50.0)
|
|
78
82
|
z_lims = (0.0,0.0)
|
|
79
|
-
sens_pos =
|
|
83
|
+
sens_pos = sens.create_sensor_pos_array(n_sens,x_lims,y_lims,z_lims)
|
|
80
84
|
|
|
81
85
|
sample_times = np.linspace(0.0,np.max(sim_data.time),50) # | None
|
|
82
86
|
|
|
83
|
-
sensor_data =
|
|
87
|
+
sensor_data = sens.SensorData(positions=sens_pos,
|
|
84
88
|
sample_times=sample_times)
|
|
85
89
|
|
|
86
90
|
field_key: str = "temperature"
|
|
87
|
-
tc_array =
|
|
91
|
+
tc_array = sens.SensorArrayFactory \
|
|
88
92
|
.thermocouples_no_errs(sim_data,
|
|
89
93
|
sensor_data,
|
|
90
94
|
elem_dims=2,
|
|
@@ -96,11 +100,11 @@ tc_array = pyv.SensorArrayFactory \
|
|
|
96
100
|
# that the truth calibration function must be inverted numerically so to
|
|
97
101
|
# increase accuracy the number of divisions can be increased. However, 1e4
|
|
98
102
|
# divisions should be suitable for most applications.
|
|
99
|
-
cal_err =
|
|
100
|
-
|
|
103
|
+
cal_err = sens.ErrSysCalibration(calib_assumed,
|
|
104
|
+
calib_truth,
|
|
101
105
|
signal_calib_range,
|
|
102
106
|
n_cal_divs=10000)
|
|
103
|
-
sys_err_int =
|
|
107
|
+
sys_err_int = sens.ErrIntegrator([cal_err],
|
|
104
108
|
sensor_data,
|
|
105
109
|
tc_array.get_measurement_shape())
|
|
106
110
|
tc_array.set_error_integrator(sys_err_int)
|
|
@@ -119,10 +123,10 @@ time_print = slice(measurements.shape[2]-time_last,measurements.shape[2])
|
|
|
119
123
|
print(f"These are the last {time_last} virtual measurements of sensor "
|
|
120
124
|
+ f"{sens_print}:")
|
|
121
125
|
|
|
122
|
-
|
|
126
|
+
sens.print_measurements(tc_array,sens_print,comp_print,time_print)
|
|
123
127
|
|
|
124
128
|
print(80*"-")
|
|
125
129
|
|
|
126
|
-
|
|
130
|
+
sens.plot_time_traces(tc_array,field_key)
|
|
127
131
|
plt.show()
|
|
128
132
|
|