pyvale 2025.7.1__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/dic/cpp/dicfourier.cpp +36 -4
- pyvale/dic/cpp/dicinterpolator.cpp +56 -1
- pyvale/dic/cpp/dicmain.cpp +24 -19
- pyvale/dic/cpp/dicoptimizer.cpp +6 -1
- pyvale/dic/cpp/dicscanmethod.cpp +32 -32
- pyvale/dic/cpp/dicsignalhandler.cpp +16 -0
- pyvale/dic/cpp/dicstrain.cpp +7 -3
- pyvale/dic/cpp/dicutil.cpp +79 -23
- pyvale/{dic2d.py → dic/dic2d.py} +51 -29
- pyvale/dic/dic2dconv.py +6 -0
- pyvale/dic/dic2dcpp.cp311-win_amd64.pyd +0 -0
- pyvale/{dicchecks.py → dic/dicchecks.py} +28 -16
- pyvale/dic/dicdataimport.py +370 -0
- pyvale/{dicregionofinterest.py → dic/dicregionofinterest.py} +169 -12
- pyvale/{dicresults.py → dic/dicresults.py} +4 -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.1.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/dic2dcpp.cp311-win_amd64.pyd +0 -0
- pyvale/dicdataimport.py +0 -247
- pyvale/simtools.py +0 -67
- pyvale-2025.7.1.dist-info/RECORD +0 -211
- /pyvale/{blendercalibrationdata.py → blender/blendercalibrationdata.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.1.dist-info → pyvale-2025.8.1.dist-info}/WHEEL +0 -0
- {pyvale-2025.7.1.dist-info → pyvale-2025.8.1.dist-info}/licenses/LICENSE +0 -0
- {pyvale-2025.7.1.dist-info → pyvale-2025.8.1.dist-info}/top_level.txt +0 -0
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
|
|
9
9
|
"""
|
|
10
10
|
DIC with images generated from a virtual blender experiment
|
|
11
|
-
|
|
11
|
+
------------------------------------------------------------
|
|
12
12
|
|
|
13
13
|
This example looks at taking the virtual experiments conducted using the blender
|
|
14
14
|
module and taking it one step further and performing a DIC calculation on the
|
|
@@ -24,9 +24,11 @@ changed.**
|
|
|
24
24
|
import matplotlib.pyplot as plt
|
|
25
25
|
from pathlib import Path
|
|
26
26
|
import numpy as np
|
|
27
|
-
import pyvale
|
|
28
27
|
import os
|
|
29
28
|
|
|
29
|
+
# Pyvale imports
|
|
30
|
+
import pyvale.dic as dic
|
|
31
|
+
|
|
30
32
|
#subset size
|
|
31
33
|
subset_size = 21
|
|
32
34
|
|
|
@@ -40,7 +42,7 @@ ref_img = "./blenderimages/reference.tiff"
|
|
|
40
42
|
def_img = "./blenderimages/blenderimage_*.tiff"
|
|
41
43
|
|
|
42
44
|
# Interactive ROI selection
|
|
43
|
-
roi =
|
|
45
|
+
roi = dic.RegionOfInterest(ref_img)
|
|
44
46
|
roi.interactive_selection(subset_size)
|
|
45
47
|
|
|
46
48
|
#output_path
|
|
@@ -49,21 +51,21 @@ if not output_path.is_dir():
|
|
|
49
51
|
output_path.mkdir(parents=True, exist_ok=True)
|
|
50
52
|
|
|
51
53
|
# DIC Calculation
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
54
|
+
dic.two_dimensional(reference=ref_img,
|
|
55
|
+
deformed=def_img,
|
|
56
|
+
roi_mask=roi.mask,
|
|
57
|
+
seed=roi.seed,
|
|
58
|
+
subset_size=subset_size,
|
|
59
|
+
subset_step=10,
|
|
60
|
+
shape_function="AFFINE",
|
|
61
|
+
max_displacement=20,
|
|
62
|
+
correlation_criteria="ZNSSD",
|
|
63
|
+
output_basepath=output_path,
|
|
64
|
+
output_prefix="blender_dic_")
|
|
63
65
|
|
|
64
66
|
# Import the Results
|
|
65
67
|
data_path = output_path / "blender_dic_*.csv"
|
|
66
|
-
dicdata =
|
|
68
|
+
dicdata = dic.data_import(data=data_path, delimiter=",",
|
|
67
69
|
layout='matrix', binary=False)
|
|
68
70
|
|
|
69
71
|
# %%
|
|
@@ -25,13 +25,18 @@ As always, we'll start with importing the required libraries:
|
|
|
25
25
|
|
|
26
26
|
import matplotlib.pyplot as plt
|
|
27
27
|
from pathlib import Path
|
|
28
|
-
|
|
28
|
+
|
|
29
|
+
# Pyvale imports
|
|
30
|
+
import pyvale.dataset as dataset
|
|
31
|
+
import pyvale.dic as dic
|
|
32
|
+
|
|
29
33
|
|
|
30
34
|
|
|
31
35
|
# %%
|
|
32
|
-
# There's a pair of DIC challenge images that come as part of the Pyvale install.
|
|
33
|
-
|
|
34
|
-
|
|
36
|
+
# There's a pair of DIC challenge images that come as part of the Pyvale install.
|
|
37
|
+
# We can preload them with:
|
|
38
|
+
ref_pattern = dataset.dic_challenge_ref()
|
|
39
|
+
def_pattern = dataset.dic_challenge_def()
|
|
35
40
|
subset_size = 17
|
|
36
41
|
|
|
37
42
|
|
|
@@ -41,7 +46,7 @@ subset_size = 17
|
|
|
41
46
|
# We can use :func:`roi.rect_boundary` to exclude a large border region so we
|
|
42
47
|
# only correlate along the horizontal at the midpoint for our selected subset
|
|
43
48
|
# size
|
|
44
|
-
roi =
|
|
49
|
+
roi = dic.RegionOfInterest(ref_image=ref_pattern)
|
|
45
50
|
subset_radius = subset_size // 2
|
|
46
51
|
roi.rect_boundary(left=50,right=50,top=250-subset_radius,bottom=250-subset_radius)
|
|
47
52
|
roi.show_image()
|
|
@@ -66,19 +71,19 @@ if not output_path.is_dir():
|
|
|
66
71
|
# the current working directory with a filename prefix of subset_size_19_*.txt
|
|
67
72
|
# If you are feeling adventorous you could investigate the effect of varying the
|
|
68
73
|
# subset size by placing the above and below sections in a loop.
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
74
|
+
dic.two_dimensional(reference=ref_pattern,
|
|
75
|
+
deformed=def_pattern,
|
|
76
|
+
roi_mask=roi.mask,
|
|
77
|
+
subset_size=subset_size,
|
|
78
|
+
subset_step=1,
|
|
79
|
+
seed=[3500,250],
|
|
80
|
+
max_displacement=10,
|
|
81
|
+
output_basepath=output_path)
|
|
77
82
|
|
|
78
83
|
# %%
|
|
79
84
|
# We can import the results in the standard way
|
|
80
85
|
data_path = output_path / "dic_results_DIC_Challenge*.csv"
|
|
81
|
-
dicdata =
|
|
86
|
+
dicdata = dic.data_import(data=data_path, layout='column',
|
|
82
87
|
binary=False, delimiter=",")
|
|
83
88
|
|
|
84
89
|
# &&
|
|
@@ -3,32 +3,38 @@
|
|
|
3
3
|
# License: MIT
|
|
4
4
|
# Copyright (C) 2025 The Computer Aided Validation Team
|
|
5
5
|
# ==============================================================================
|
|
6
|
-
|
|
6
|
+
import numpy as np
|
|
7
7
|
import matplotlib.pyplot as plt
|
|
8
|
-
import pyvale
|
|
8
|
+
import pyvale.verif as va
|
|
9
9
|
|
|
10
10
|
def main() -> None:
|
|
11
11
|
|
|
12
|
-
(sim_data,data_gen) =
|
|
12
|
+
(sim_data,data_gen) = va.AnalyticCaseFactory.scalar_linear_2d()
|
|
13
13
|
|
|
14
14
|
(grid_x,grid_y,grid_field) = data_gen.get_visualisation_grid()
|
|
15
15
|
|
|
16
|
+
print()
|
|
17
|
+
print(f"{np.min(grid_field.flatten())=}")
|
|
18
|
+
print(f"{np.max(grid_field.flatten())=}")
|
|
19
|
+
print()
|
|
20
|
+
|
|
16
21
|
fig, ax = plt.subplots()
|
|
17
22
|
cs = ax.contourf(grid_x,grid_y,grid_field)
|
|
18
23
|
cbar = fig.colorbar(cs)
|
|
19
24
|
plt.axis('scaled')
|
|
20
25
|
|
|
21
26
|
|
|
22
|
-
(sim_data,data_gen) =
|
|
27
|
+
# (sim_data,data_gen) = va.AnalyticCaseFactory.scalar_quadratic_2d()
|
|
23
28
|
|
|
24
|
-
(grid_x,grid_y,grid_field) = data_gen.get_visualisation_grid()
|
|
29
|
+
# (grid_x,grid_y,grid_field) = data_gen.get_visualisation_grid()
|
|
25
30
|
|
|
26
|
-
fig, ax = plt.subplots()
|
|
27
|
-
cs = ax.contourf(grid_x,grid_y,grid_field)
|
|
28
|
-
cbar = fig.colorbar(cs)
|
|
29
|
-
plt.axis('scaled')
|
|
31
|
+
# fig, ax = plt.subplots()
|
|
32
|
+
# cs = ax.contourf(grid_x,grid_y,grid_field)
|
|
33
|
+
# cbar = fig.colorbar(cs)
|
|
34
|
+
# plt.axis('scaled')
|
|
35
|
+
|
|
36
|
+
# plt.show()
|
|
30
37
|
|
|
31
|
-
plt.show()
|
|
32
38
|
|
|
33
39
|
|
|
34
40
|
if __name__ == '__main__':
|
|
@@ -7,11 +7,11 @@
|
|
|
7
7
|
import numpy as np
|
|
8
8
|
import matplotlib.pyplot as plt
|
|
9
9
|
import sympy
|
|
10
|
-
import pyvale
|
|
10
|
+
import pyvale.verif as va
|
|
11
11
|
|
|
12
12
|
def main() -> None:
|
|
13
13
|
|
|
14
|
-
case_data =
|
|
14
|
+
case_data = va.AnalyticData2D()
|
|
15
15
|
case_data.length_x = 10.0
|
|
16
16
|
case_data.length_y = 7.5
|
|
17
17
|
n_elem_mult = 10
|
|
@@ -27,7 +27,7 @@ def main() -> None:
|
|
|
27
27
|
case_data.offsets_time = (0.0,)
|
|
28
28
|
|
|
29
29
|
|
|
30
|
-
data_gen =
|
|
30
|
+
data_gen = va.AnalyticSimDataGen(case_data)
|
|
31
31
|
sim_data = data_gen.generate_sim_data()
|
|
32
32
|
|
|
33
33
|
(grid_x,grid_y,grid_field) = data_gen.get_visualisation_grid()
|
|
@@ -6,23 +6,29 @@
|
|
|
6
6
|
|
|
7
7
|
import matplotlib.pyplot as plt
|
|
8
8
|
import numpy as np
|
|
9
|
-
import pyvale
|
|
9
|
+
import pyvale as pyv
|
|
10
|
+
import pyvale.verif as va
|
|
10
11
|
|
|
11
12
|
def main() -> None:
|
|
12
|
-
|
|
13
|
+
# 10x7.5 plate with bi-directional field gradient
|
|
14
|
+
# 40x30 elements [x,y]
|
|
15
|
+
# Field slope of 20/lengX in X
|
|
16
|
+
# Field slope of 10/lengY in Y
|
|
17
|
+
# Field max in top corner of 220, field min in bottom corner 20
|
|
18
|
+
(sim_data,_) = va.AnalyticCaseFactory.scalar_linear_2d()
|
|
13
19
|
|
|
14
|
-
descriptor =
|
|
20
|
+
descriptor = pyv.SensorDescriptorFactory.temperature_descriptor()
|
|
15
21
|
|
|
16
22
|
field_key = 'scalar'
|
|
17
|
-
t_field =
|
|
18
|
-
|
|
19
|
-
|
|
23
|
+
t_field = pyv.FieldScalar(sim_data,
|
|
24
|
+
field_key=field_key,
|
|
25
|
+
elem_dims=2)
|
|
20
26
|
|
|
21
27
|
n_sens = (4,1,1)
|
|
22
28
|
x_lims = (0.0,10.0)
|
|
23
29
|
y_lims = (0.0,7.5)
|
|
24
30
|
z_lims = (0.0,0.0)
|
|
25
|
-
sens_pos =
|
|
31
|
+
sens_pos = pyv.create_sensor_pos_array(n_sens,x_lims,y_lims,z_lims)
|
|
26
32
|
|
|
27
33
|
use_sim_time = False
|
|
28
34
|
if use_sim_time:
|
|
@@ -30,10 +36,10 @@ def main() -> None:
|
|
|
30
36
|
else:
|
|
31
37
|
sample_times = np.linspace(0.0,np.max(sim_data.time),50)
|
|
32
38
|
|
|
33
|
-
sensor_data =
|
|
39
|
+
sensor_data = pyv.SensorData(positions=sens_pos,
|
|
34
40
|
sample_times=sample_times)
|
|
35
41
|
|
|
36
|
-
tc_array =
|
|
42
|
+
tc_array = pyv.SensorArrayPoint(sensor_data,
|
|
37
43
|
t_field,
|
|
38
44
|
descriptor)
|
|
39
45
|
|
|
@@ -43,37 +49,37 @@ def main() -> None:
|
|
|
43
49
|
|
|
44
50
|
error_chain = []
|
|
45
51
|
if errors_on['indep_sys']:
|
|
46
|
-
error_chain.append(
|
|
47
|
-
error_chain.append(
|
|
52
|
+
error_chain.append(pyv.ErrSysOffset(offset=-5.0))
|
|
53
|
+
error_chain.append(pyv.ErrSysUnif(low=-5.0,
|
|
48
54
|
high=5.0))
|
|
49
|
-
gen_norm =
|
|
55
|
+
gen_norm = pyv.GenNormal(std=1.0)
|
|
50
56
|
|
|
51
57
|
if errors_on['rand']:
|
|
52
|
-
error_chain.append(
|
|
53
|
-
error_chain.append(
|
|
58
|
+
error_chain.append(pyv.ErrRandNormPercent(std_percent=1.0))
|
|
59
|
+
error_chain.append(pyv.ErrRandUnifPercent(low_percent=-1.0,
|
|
54
60
|
high_percent=1.0))
|
|
55
61
|
|
|
56
62
|
if errors_on['dep_sys']:
|
|
57
|
-
error_chain.append(
|
|
58
|
-
error_chain.append(
|
|
63
|
+
error_chain.append(pyv.ErrSysDigitisation(bits_per_unit=2**8/100))
|
|
64
|
+
error_chain.append(pyv.ErrSysSaturation(meas_min=0.0,meas_max=300.0))
|
|
59
65
|
|
|
60
66
|
if len(error_chain) > 0:
|
|
61
|
-
error_integrator =
|
|
67
|
+
error_integrator = pyv.ErrIntegrator(error_chain,
|
|
62
68
|
sensor_data,
|
|
63
69
|
tc_array.get_measurement_shape())
|
|
64
70
|
tc_array.set_error_integrator(error_integrator)
|
|
65
71
|
|
|
66
72
|
measurements = tc_array.get_measurements()
|
|
67
73
|
|
|
68
|
-
|
|
69
|
-
(0,1), # Sensor 1
|
|
70
|
-
(0,1), # Component 1: scalar field = 1 component
|
|
71
|
-
(measurements.shape[2]-5,measurements.shape[2]))
|
|
74
|
+
pyv.print_measurements(tc_array,
|
|
75
|
+
slice(0,1), # Sensor 1
|
|
76
|
+
slice(0,1), # Component 1: scalar field = 1 component
|
|
77
|
+
slice (measurements.shape[2]-5,measurements.shape[2]))
|
|
72
78
|
|
|
73
|
-
(fig,_) =
|
|
79
|
+
(fig,_) = pyv.plot_time_traces(tc_array,field_key)
|
|
74
80
|
plt.show()
|
|
75
81
|
|
|
76
|
-
pv_plot =
|
|
82
|
+
pv_plot = pyv.plot_point_sensors_on_sim(tc_array,field_key)
|
|
77
83
|
pv_plot.show(cpos="xy")
|
|
78
84
|
|
|
79
85
|
if __name__ == '__main__':
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
# ==============================================================================
|
|
2
|
+
# pyvale: the python validation engine
|
|
3
|
+
# License: MIT
|
|
4
|
+
# Copyright (C) 2025 The Computer Aided Validation Team
|
|
5
|
+
# ==============================================================================
|
|
6
|
+
import copy
|
|
7
|
+
import matplotlib.pyplot as plt
|
|
8
|
+
import numpy as np
|
|
9
|
+
import pyvale.sensorsim as sens
|
|
10
|
+
import pyvale.verif as va
|
|
11
|
+
|
|
12
|
+
def main() -> None:
|
|
13
|
+
# 10x7.5 plate with bi-directional field gradient
|
|
14
|
+
# 40x30 elements [x,y]
|
|
15
|
+
# Field slope of 20/lengX in X
|
|
16
|
+
# Field slope of 10/lengY in Y
|
|
17
|
+
# Field max in top corner of 220, field min in bottom corner 20
|
|
18
|
+
(sim_data,_) = va.AnalyticCaseFactory.scalar_linear_2d()
|
|
19
|
+
sim_data_nomesh = copy.deepcopy(sim_data)
|
|
20
|
+
sim_data_nomesh.connect = None
|
|
21
|
+
|
|
22
|
+
descriptor = sens.SensorDescriptorFactory.temperature_descriptor()
|
|
23
|
+
|
|
24
|
+
field_key = 'scalar'
|
|
25
|
+
scal_field = sens.FieldScalar(sim_data,
|
|
26
|
+
field_key=field_key,
|
|
27
|
+
elem_dims=2)
|
|
28
|
+
|
|
29
|
+
# scal_field_nm = sens.FieldScalar(sim_data_nomesh,
|
|
30
|
+
# field_key=field_key,
|
|
31
|
+
# elem_dims=2)
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
n_sens = (4,1,1)
|
|
35
|
+
x_lims = (0.0,10.0)
|
|
36
|
+
y_lims = (0.0,7.5)
|
|
37
|
+
z_lims = (0.0,0.0)
|
|
38
|
+
sens_pos = sens.create_sensor_pos_array(n_sens,x_lims,y_lims,z_lims)
|
|
39
|
+
|
|
40
|
+
use_sim_time = False
|
|
41
|
+
if use_sim_time:
|
|
42
|
+
sample_times = None
|
|
43
|
+
else:
|
|
44
|
+
sample_times = np.linspace(0.0,np.max(sim_data.time),50)
|
|
45
|
+
|
|
46
|
+
sensor_data = sens.SensorData(positions=sens_pos,
|
|
47
|
+
sample_times=sample_times)
|
|
48
|
+
|
|
49
|
+
tc_array = sens.SensorArrayPoint(sensor_data,
|
|
50
|
+
scal_field,
|
|
51
|
+
descriptor)
|
|
52
|
+
|
|
53
|
+
measurements = tc_array.get_measurements()
|
|
54
|
+
|
|
55
|
+
sens.print_measurements(tc_array,
|
|
56
|
+
slice(0,1), # Sensor 1
|
|
57
|
+
slice(0,1), # Component 1: scalar field = 1 component
|
|
58
|
+
slice (measurements.shape[2]-5,measurements.shape[2]))
|
|
59
|
+
|
|
60
|
+
# (fig,_) = sens.plot_time_traces(tc_array,field_key)
|
|
61
|
+
# plt.show()
|
|
62
|
+
|
|
63
|
+
# pv_plot = sens.plot_point_sensors_on_sim(tc_array,field_key)
|
|
64
|
+
# pv_plot.show(cpos="xy")
|
|
65
|
+
|
|
66
|
+
if __name__ == '__main__':
|
|
67
|
+
main()
|
|
@@ -7,16 +7,19 @@
|
|
|
7
7
|
|
|
8
8
|
from pathlib import Path
|
|
9
9
|
import numpy as np
|
|
10
|
-
|
|
11
|
-
|
|
10
|
+
|
|
11
|
+
# Pyvale Imports
|
|
12
|
+
import pyvale.sensorsim as sens
|
|
13
|
+
import pyvale.mooseherder as mh
|
|
14
|
+
import pyvale.dataset as dataset
|
|
12
15
|
|
|
13
16
|
|
|
14
17
|
def main() -> None:
|
|
15
|
-
sim_path =
|
|
18
|
+
sim_path = dataset.mechanical_2d_path()
|
|
16
19
|
sim_data = mh.ExodusReader(sim_path).read_all_sim_data()
|
|
17
20
|
|
|
18
|
-
image_path =
|
|
19
|
-
image_speckle =
|
|
21
|
+
image_path = dataset.dic_pattern_5mpx_path()
|
|
22
|
+
image_speckle = sens.ImageTools.load_image_greyscale(image_path)
|
|
20
23
|
|
|
21
24
|
save_path = Path.cwd()/"pyvale-output"
|
|
22
25
|
if not save_path.is_dir():
|
|
@@ -36,12 +39,12 @@ def main() -> None:
|
|
|
36
39
|
print(80*"-")
|
|
37
40
|
|
|
38
41
|
|
|
39
|
-
cam_data =
|
|
42
|
+
cam_data = sens.CameraData2D(pixels_count=np.array((1040,1540)),
|
|
40
43
|
leng_per_px=0.1e-3,
|
|
41
44
|
bits=8,
|
|
42
45
|
roi_cent_world=np.mean(coords,axis=0),
|
|
43
46
|
subsample=3)
|
|
44
|
-
id_opts =
|
|
47
|
+
id_opts = sens.ImageDefOpts(save_path=save_path,
|
|
45
48
|
crop_on=True,
|
|
46
49
|
add_static_ref=True)
|
|
47
50
|
|
|
@@ -51,7 +54,7 @@ def main() -> None:
|
|
|
51
54
|
image_mask,
|
|
52
55
|
image_input,
|
|
53
56
|
disp_x,
|
|
54
|
-
disp_y) =
|
|
57
|
+
disp_y) = sens.ImageDef2D.preprocess(cam_data,
|
|
55
58
|
image_speckle,
|
|
56
59
|
coords,
|
|
57
60
|
connectivity,
|
|
@@ -65,7 +68,7 @@ def main() -> None:
|
|
|
65
68
|
print(f"{disp.shape=}")
|
|
66
69
|
|
|
67
70
|
|
|
68
|
-
|
|
71
|
+
sens.ImageDef2D.deform_images_to_disk(cam_data,
|
|
69
72
|
upsampled_image,
|
|
70
73
|
coords,
|
|
71
74
|
connectivity,
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
# ==============================================================================
|
|
2
|
+
# pyvale: the python validation engine
|
|
3
|
+
# License: MIT
|
|
4
|
+
# Copyright (C) 2025 The Computer Aided Validation Team
|
|
5
|
+
# ==============================================================================
|
|
6
|
+
|
|
7
|
+
"""
|
|
8
|
+
Creating a configuration file
|
|
9
|
+
================================================================================
|
|
10
|
+
|
|
11
|
+
In this example we generate a json config file which help mooseherder find the
|
|
12
|
+
paths to moose apps we want to use in the future.
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
**Installing moose**: To run future examples you will need to have moose
|
|
16
|
+
on your system. As moose supports unix operating systems windows users will need
|
|
17
|
+
to use windows subsystem for linux (WSL). We use the proteus moose build which
|
|
18
|
+
can be found here: https://github.com/aurora-multiphysics/proteus. Build scripts
|
|
19
|
+
for common linux distributions can be found in the 'scripts' directory of the
|
|
20
|
+
repo. You can also create your own moose build using instructions here:
|
|
21
|
+
https://mooseframework.inl.gov/.
|
|
22
|
+
|
|
23
|
+
We start by importing what we need for this example.
|
|
24
|
+
"""
|
|
25
|
+
|
|
26
|
+
#%%#
|
|
27
|
+
# We start with imports for paths and for our moose configuration object.
|
|
28
|
+
from pathlib import Path
|
|
29
|
+
|
|
30
|
+
# Pyvale imports
|
|
31
|
+
from pyvale.mooseherder import MooseConfig
|
|
32
|
+
|
|
33
|
+
#%%
|
|
34
|
+
# A moose configuration is a dictionary with these three keys "main_path",
|
|
35
|
+
# "app_path" and "app_name". The first two keys retur resolved paths for moose
|
|
36
|
+
# and the app you are using. The last key returns the string used call your
|
|
37
|
+
# moose app on the command line. Once we have this dictionary we can build our
|
|
38
|
+
# moose config object which will perform some checks for us to see if the
|
|
39
|
+
# configuration is valid.
|
|
40
|
+
config = {'main_path': Path.home()/ 'moose',
|
|
41
|
+
'app_path': Path.home() / 'proteus',
|
|
42
|
+
'app_name': 'proteus-opt'}
|
|
43
|
+
|
|
44
|
+
moose_config = MooseConfig(config)
|
|
45
|
+
|
|
46
|
+
#%%
|
|
47
|
+
# We are going to save our moose configuration to the default output path for
|
|
48
|
+
# pyvale so if this default output path does not exist we create it. Then all we
|
|
49
|
+
# need to do is call the save configuration method and give it a path and file
|
|
50
|
+
# name for the json we want to save.
|
|
51
|
+
output_path = Path.cwd() / "pyvale-output"
|
|
52
|
+
if not output_path.is_dir():
|
|
53
|
+
output_path.mkdir(parents=True, exist_ok=True)
|
|
54
|
+
|
|
55
|
+
config_path = Path.cwd() / 'moose-config.json'
|
|
56
|
+
moose_config.save_config(config_path)
|
|
57
|
+
|
|
58
|
+
#%%
|
|
59
|
+
# Now we have our moose configuration we can use it to run moose with
|
|
60
|
+
# mooseherder's mooserunner and mooseherd classes which we will see in later
|
|
61
|
+
# examples. For now we will move on to demonstrate how mooseherder modifies
|
|
62
|
+
# input files for gmsh and moose.
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
# ==============================================================================
|
|
2
|
+
# pyvale: the python validation engine
|
|
3
|
+
# License: MIT
|
|
4
|
+
# Copyright (C) 2025 The Computer Aided Validation Team
|
|
5
|
+
# ==============================================================================
|
|
6
|
+
|
|
7
|
+
"""
|
|
8
|
+
Modifying moose input files
|
|
9
|
+
================================================================================
|
|
10
|
+
|
|
11
|
+
In this example we will use mooseherder's input modifier to programmatically
|
|
12
|
+
change variables in a moose .i input script.
|
|
13
|
+
|
|
14
|
+
We start by importing the packages we need for this example.
|
|
15
|
+
"""
|
|
16
|
+
|
|
17
|
+
from pathlib import Path
|
|
18
|
+
|
|
19
|
+
# Pyvale imports
|
|
20
|
+
import pyvale.dataset as dataset
|
|
21
|
+
from pyvale.mooseherder import InputModifier
|
|
22
|
+
|
|
23
|
+
#%%
|
|
24
|
+
# We use the input file for a simple thermo-mechanical cube with higher order
|
|
25
|
+
# quads. We pass this to our input modifier specifying the moose comment
|
|
26
|
+
# character(s) as '#' and moose input files do not have a line end character so
|
|
27
|
+
# we pass an empty string. In the next example we will modify a gmsh script
|
|
28
|
+
# where we will need to specify a line ending character.
|
|
29
|
+
moose_input = dataset.element_case_input_path(dataset.EElemTest.HEX20)
|
|
30
|
+
moose_mod = InputModifier(moose_input, comment_chars="#", end_chars="")
|
|
31
|
+
|
|
32
|
+
#%%
|
|
33
|
+
# Note that the input modifier class only looks for variables between specified
|
|
34
|
+
# sentinel characters in comment lines which starts with '_*' and ends with '**'
|
|
35
|
+
# . An example of what variable block can be found in the moose input file.
|
|
36
|
+
#
|
|
37
|
+
# We then print the variables found in the moose input file to the console which
|
|
38
|
+
# are returned to us as a dictionary keyed by the variables string name in the
|
|
39
|
+
# file:
|
|
40
|
+
print(moose_mod.get_vars())
|
|
41
|
+
print()
|
|
42
|
+
|
|
43
|
+
#%%
|
|
44
|
+
# We can update variables using the input modifier, we just need to create a
|
|
45
|
+
# dictionary keyed by the variable name we want to change and the value we want
|
|
46
|
+
# the variable to take. If the variable does not exist in the input file then an
|
|
47
|
+
# error will be raised. Here we will change the number of elements in 'x' and
|
|
48
|
+
# the elastic modulus.
|
|
49
|
+
new_vars = {"nElemX": 4, "EMod": 3.3e9}
|
|
50
|
+
moose_mod.update_vars(new_vars)
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
#%%
|
|
54
|
+
# Let's check that the variables in the dictionary have been updated to match
|
|
55
|
+
# what we have changed:
|
|
56
|
+
print(moose_mod.get_vars())
|
|
57
|
+
print()
|
|
58
|
+
|
|
59
|
+
#%%
|
|
60
|
+
# Now we want to save the modified input file so we first create the standard
|
|
61
|
+
# pyvale-output directory if it does not exist. Then we write the file to that
|
|
62
|
+
# directory with suitable file name. Have a look at the file in the
|
|
63
|
+
# pyvale-output directory to verify the variables have been changed.
|
|
64
|
+
|
|
65
|
+
output_path = Path.cwd() / "pyvale-output"
|
|
66
|
+
if not output_path.is_dir():
|
|
67
|
+
output_path.mkdir(parents=True, exist_ok=True)
|
|
68
|
+
|
|
69
|
+
moose_save = output_path/"moose-mod-vars.i"
|
|
70
|
+
moose_mod.write_file(moose_save)
|
|
71
|
+
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
# ==============================================================================
|
|
2
|
+
# pyvale: the python validation engine
|
|
3
|
+
# License: MIT
|
|
4
|
+
# Copyright (C) 2025 The Computer Aided Validation Team
|
|
5
|
+
# ==============================================================================
|
|
6
|
+
|
|
7
|
+
"""
|
|
8
|
+
Modifying gmsh input files
|
|
9
|
+
================================================================================
|
|
10
|
+
|
|
11
|
+
In this example we will use mooseherder's input modifier to programmatically
|
|
12
|
+
change variables in a gmsh .geo script.
|
|
13
|
+
|
|
14
|
+
We start by importing the packages we need for this example.
|
|
15
|
+
"""
|
|
16
|
+
|
|
17
|
+
from pathlib import Path
|
|
18
|
+
|
|
19
|
+
# Pyvale imports
|
|
20
|
+
import pyvale.dataset as dataset
|
|
21
|
+
from pyvale.mooseherder import InputModifier
|
|
22
|
+
|
|
23
|
+
#%%
|
|
24
|
+
# We are going to use a gmsh geo file that is for a 2D rectangular plate with a
|
|
25
|
+
# hole in the center which we retrieve from pyvale's simulation library. We then
|
|
26
|
+
# use this to create an input modifier which has the correct comment string '//'
|
|
27
|
+
# for gmsh and the required line terminator ";".
|
|
28
|
+
gmsh_input = dataset.sim_case_gmsh_file_path(case_num=17)
|
|
29
|
+
gmsh_mod = InputModifier(gmsh_input, "//", ";")
|
|
30
|
+
|
|
31
|
+
#%%
|
|
32
|
+
# Note that the input modifier class only looks for variables between specified
|
|
33
|
+
# sentinel characters in comment lines which starts with '_*' and ends with '**'
|
|
34
|
+
# . An example variable block can be found in the gmsh input file.
|
|
35
|
+
#
|
|
36
|
+
# We then print the variables found in the gmsh input file to the console which
|
|
37
|
+
# are returned to us as a dictionary keyed by the variables string name in the
|
|
38
|
+
# file:
|
|
39
|
+
print(gmsh_mod.get_vars())
|
|
40
|
+
print()
|
|
41
|
+
|
|
42
|
+
#%%
|
|
43
|
+
# We can update the variables in the input modifier using a dictionary keyed by
|
|
44
|
+
# the variable names we want to change and the values being what we want to
|
|
45
|
+
# change them to. We do not have to use numeric values for these we can use
|
|
46
|
+
# expressions in strings.
|
|
47
|
+
new_vars = {"plate_width": 150e-3, "plate_height": "plate_width + 100e-3"}
|
|
48
|
+
gmsh_mod.update_vars(new_vars)
|
|
49
|
+
|
|
50
|
+
#%%
|
|
51
|
+
# Now we print the variables that are currently in the input modifier to check
|
|
52
|
+
# our modification worked.
|
|
53
|
+
print(gmsh_mod.get_vars())
|
|
54
|
+
print()
|
|
55
|
+
|
|
56
|
+
#%%
|
|
57
|
+
# Finally we want to save the modified input file to disk so we can run it with
|
|
58
|
+
# gmsh. First we create the standard pyvale-output directory so we can save the
|
|
59
|
+
# file there. Then we save the gmsh input file to the directory with a suitable
|
|
60
|
+
# name. Have a look at the file in the directory to ensure our modifications
|
|
61
|
+
# have worked.
|
|
62
|
+
|
|
63
|
+
output_path = Path.cwd() / "pyvale-output"
|
|
64
|
+
if not output_path.is_dir():
|
|
65
|
+
output_path.mkdir(parents=True, exist_ok=True)
|
|
66
|
+
|
|
67
|
+
gmsh_save = output_path/"gmsh-mod-vars.geo"
|
|
68
|
+
gmsh_mod.write_file(gmsh_save)
|
|
69
|
+
|