pyvale 2025.7.1__cp311-cp311-musllinux_1_2_i686.whl → 2025.8.1__cp311-cp311-musllinux_1_2_i686.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/{dic2dcpp.cpython-311-i386-linux-musl.so → dic/dic2dcpp.cpython-311-i386-linux-musl.so} +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.cpython-311-i386-linux-musl.so +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 +263 -0
- pyvale/dataset.py +0 -415
- pyvale/dicdataimport.py +0 -247
- pyvale/simtools.py +0 -67
- pyvale-2025.7.1.dist-info/RECORD +0 -214
- /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
pyvale/dataset.py
DELETED
|
@@ -1,415 +0,0 @@
|
|
|
1
|
-
#===============================================================================
|
|
2
|
-
# pyvale: the python validation engine
|
|
3
|
-
# License: MIT
|
|
4
|
-
# Copyright (C) 2025 The Computer Aided Validation Team
|
|
5
|
-
#===============================================================================
|
|
6
|
-
|
|
7
|
-
"""
|
|
8
|
-
Accesors for data that comes pre-packaged with pyvale for demonstrating its
|
|
9
|
-
functionality. This includes moose simulation outputs as exodus files, input
|
|
10
|
-
files for moose and gmsh for additional simulation cases, and images required
|
|
11
|
-
for testing the image deformation and digital image correlation modules.
|
|
12
|
-
"""
|
|
13
|
-
|
|
14
|
-
from enum import Enum
|
|
15
|
-
from pathlib import Path
|
|
16
|
-
from importlib.resources import files
|
|
17
|
-
|
|
18
|
-
# TODO: finish doc strings for last functions
|
|
19
|
-
|
|
20
|
-
SIM_CASE_COUNT = 26
|
|
21
|
-
"""Constant describing the number of simulation test case input files for moose
|
|
22
|
-
and gmsh that come packaged with pyvale.
|
|
23
|
-
"""
|
|
24
|
-
|
|
25
|
-
class EElemTest(Enum):
|
|
26
|
-
"""Enumeration used to specify different 3D element types for extracting
|
|
27
|
-
specific test simulation datasets.
|
|
28
|
-
"""
|
|
29
|
-
|
|
30
|
-
TET4 = "TET4"
|
|
31
|
-
"""Tetrahedral element, linear with 4 nodes.
|
|
32
|
-
"""
|
|
33
|
-
|
|
34
|
-
TET10 = "TET10"
|
|
35
|
-
"""Tetrahedral element, quadratic with 10 nodes.
|
|
36
|
-
"""
|
|
37
|
-
|
|
38
|
-
TET14 = "TET14"
|
|
39
|
-
"""Tetrahedral element, quadratic with 14 nodes.
|
|
40
|
-
"""
|
|
41
|
-
|
|
42
|
-
HEX8 = "HEX8"
|
|
43
|
-
"""Hexahedral element, linear with 8 nodes.
|
|
44
|
-
"""
|
|
45
|
-
|
|
46
|
-
HEX20 = "HEX20"
|
|
47
|
-
"""Hexahedral element, quadratic with 20 nodes.
|
|
48
|
-
"""
|
|
49
|
-
|
|
50
|
-
HEX27 = "HEX27"
|
|
51
|
-
"""Hexahedral element, quadratic with 27 nodes.
|
|
52
|
-
"""
|
|
53
|
-
|
|
54
|
-
def __str__(self):
|
|
55
|
-
return self.value
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
class DataSetError(Exception):
|
|
59
|
-
"""Custom error class for file io errors associated with retrieving datasets
|
|
60
|
-
and files packaged with pyvale.
|
|
61
|
-
"""
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
class DataSet:
|
|
65
|
-
@staticmethod
|
|
66
|
-
def sim_case_input_file_path(case_num: int) -> Path:
|
|
67
|
-
"""Gets the path to MOOSE input file (*.i) for a particular simulation
|
|
68
|
-
case.
|
|
69
|
-
|
|
70
|
-
Parameters
|
|
71
|
-
----------
|
|
72
|
-
case_num : int
|
|
73
|
-
Integer defining the case number to be retrieved. Must be greater
|
|
74
|
-
than 0 and less than the number of simulation cases.
|
|
75
|
-
|
|
76
|
-
Returns
|
|
77
|
-
-------
|
|
78
|
-
Path
|
|
79
|
-
Path object to the MOOSE *.i file for the selected simulation case.
|
|
80
|
-
|
|
81
|
-
Raises
|
|
82
|
-
------
|
|
83
|
-
DataSetError
|
|
84
|
-
Raised if an invalid simulation case number is specified.
|
|
85
|
-
"""
|
|
86
|
-
if case_num <= 0:
|
|
87
|
-
raise DataSetError("Simulation case number must be greater than 0")
|
|
88
|
-
elif case_num > SIM_CASE_COUNT:
|
|
89
|
-
raise DataSetError("Simulation case number must be less than " \
|
|
90
|
-
+ f"{SIM_CASE_COUNT}")
|
|
91
|
-
|
|
92
|
-
case_num_str = str(case_num).zfill(2)
|
|
93
|
-
case_file = f"case{case_num_str}.i"
|
|
94
|
-
return Path(files("pyvale.simcases").joinpath(case_file))
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
@staticmethod
|
|
98
|
-
def sim_case_gmsh_file_path(case_num: int) -> Path | None:
|
|
99
|
-
"""Gets the path to Gmsh input file (*.geo) for a particular simulation
|
|
100
|
-
case. Note that not all simulation cases use Gmsh for geometry and mesh
|
|
101
|
-
generation. If the specified simulation case does not have an associated
|
|
102
|
-
Gmsh *.geo file. In this case 'None' is returned
|
|
103
|
-
|
|
104
|
-
Parameters
|
|
105
|
-
----------
|
|
106
|
-
case_num : int
|
|
107
|
-
Integer defining the case number to be retrieved. Must be greater
|
|
108
|
-
than 0 and less than the number of simulation cases.
|
|
109
|
-
|
|
110
|
-
Returns
|
|
111
|
-
-------
|
|
112
|
-
Path | None
|
|
113
|
-
Path object to the Gmsh *.geo file for the selected simulation case.
|
|
114
|
-
Returns None if there is no *.geo for this simulation case.
|
|
115
|
-
|
|
116
|
-
Raises
|
|
117
|
-
------
|
|
118
|
-
DataSetError
|
|
119
|
-
Raised if an invalid simulation case number is specified.
|
|
120
|
-
"""
|
|
121
|
-
if case_num <= 0:
|
|
122
|
-
raise DataSetError("Simulation case number must be greater than 0")
|
|
123
|
-
elif case_num > SIM_CASE_COUNT:
|
|
124
|
-
raise DataSetError("Simulation case number must be less than " \
|
|
125
|
-
+ f"{SIM_CASE_COUNT}")
|
|
126
|
-
|
|
127
|
-
case_num_str = str(case_num).zfill(2)
|
|
128
|
-
case_file = f"case{case_num_str}.geo"
|
|
129
|
-
case_path = Path(files("pyvale.simcases").joinpath(case_file))
|
|
130
|
-
|
|
131
|
-
if case_path.is_file():
|
|
132
|
-
return case_path
|
|
133
|
-
|
|
134
|
-
return None
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
@staticmethod
|
|
138
|
-
def dic_pattern_5mpx_path() -> Path:
|
|
139
|
-
"""Path to a 5 mega-pixel speckle pattern image (2464 x 2056 pixels)
|
|
140
|
-
with 8 bit resolution stored as a *.tiff. Speckles are sampled by
|
|
141
|
-
5 pixels. A gaussian blur has been applied to the image to remove sharp
|
|
142
|
-
transitions from black to white.
|
|
143
|
-
|
|
144
|
-
Path
|
|
145
|
-
Path to the *.tiff file containing the speckle pattern.
|
|
146
|
-
"""
|
|
147
|
-
return Path(files("pyvale.data")
|
|
148
|
-
.joinpath("optspeckle_2464x2056px_spec5px_8bit_gblur1px.tiff"))
|
|
149
|
-
|
|
150
|
-
@staticmethod
|
|
151
|
-
def thermal_2d_path() -> Path:
|
|
152
|
-
"""Path to a MOOSE simulation output in exodus format. This case is a
|
|
153
|
-
thermal problem solving for a scalar temperature field. The geometry is
|
|
154
|
-
a 2D plate (in x,y) with a heat flux applied on one edge and a heat
|
|
155
|
-
transfer coefficient applied on the opposite edge inducing a temperature
|
|
156
|
-
gradient along the x axis of the plate.
|
|
157
|
-
|
|
158
|
-
The simulation parameters can be found in the corresponding MOOSE input
|
|
159
|
-
file: case13.i which can be retrieved using `sim_case_input_file_path`
|
|
160
|
-
in this class.
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
Returns
|
|
164
|
-
-------
|
|
165
|
-
Path
|
|
166
|
-
Path to the exodus (*.e) output file for this simulation case.
|
|
167
|
-
"""
|
|
168
|
-
return Path(files("pyvale.data").joinpath("case13_out.e"))
|
|
169
|
-
|
|
170
|
-
@staticmethod
|
|
171
|
-
def thermal_3d_path() -> Path:
|
|
172
|
-
"""Path to a MOOSE simulation output in exodus format. This case is a 3D
|
|
173
|
-
thermal problem solving for a scalar temperature field. The model is a
|
|
174
|
-
divertor armour monoblock composed of a tungsten block bonded to a
|
|
175
|
-
copper-chromium-zirconium pipe with a pure copper interlayer. A heat
|
|
176
|
-
flux is applied to the top surface of the block and a heat transfer
|
|
177
|
-
coefficient for cooling water is applied to the inner surface of the
|
|
178
|
-
pipe inducing a temperature gradient from the top of the block to the
|
|
179
|
-
pipe.
|
|
180
|
-
|
|
181
|
-
The simulation parameters can be found in the corresponding MOOSE input
|
|
182
|
-
file: case16.i which can be retrieved using `sim_case_input_file_path`
|
|
183
|
-
in this class. Note that this case uses a Gmsh *.geo file for geometry
|
|
184
|
-
and mesh creation.
|
|
185
|
-
|
|
186
|
-
Returns
|
|
187
|
-
-------
|
|
188
|
-
Path
|
|
189
|
-
Path to the exodus (*.e) output file for this simulation case.
|
|
190
|
-
"""
|
|
191
|
-
return Path(files("pyvale.data").joinpath("case16_out.e"))
|
|
192
|
-
|
|
193
|
-
@staticmethod
|
|
194
|
-
def mechanical_2d_path() -> Path:
|
|
195
|
-
"""Path to a MOOSE simulation output in exodus format. This case is a 2D
|
|
196
|
-
plate with a hole in the center with the bottom edge fixed and a
|
|
197
|
-
displacement applied to the top edge. This is a mechanical problem and
|
|
198
|
-
solves for the displacement vector field and the tensorial strain field.
|
|
199
|
-
|
|
200
|
-
The simulation parameters can be found in the corresponding MOOSE input
|
|
201
|
-
file: case17.i which can be retrieved using `sim_case_input_file_path`
|
|
202
|
-
in this class. Note that this case uses a Gmsh *.geo file for geometry
|
|
203
|
-
and mesh creation.
|
|
204
|
-
|
|
205
|
-
Returns
|
|
206
|
-
-------
|
|
207
|
-
Path
|
|
208
|
-
Path to the exodus (*.e) output file for this simulation case.
|
|
209
|
-
"""
|
|
210
|
-
return Path(files("pyvale.data").joinpath("case17_out.e"))
|
|
211
|
-
|
|
212
|
-
@staticmethod
|
|
213
|
-
def thermomechanical_2d_path() -> Path:
|
|
214
|
-
"""Path to a MOOSE simulation output in exodus format. This case is a
|
|
215
|
-
thermo-mechanical analysis of a 2D plate with a heat flux applied on one
|
|
216
|
-
edge and a heat transfer coefficient applied on the opposing edge. The
|
|
217
|
-
mechanical deformation results from thermal expansion due to the imposed
|
|
218
|
-
temperature gradient. This model is solved for the scalar temperature
|
|
219
|
-
field, vector displacement and tensor strain field.
|
|
220
|
-
|
|
221
|
-
Returns
|
|
222
|
-
-------
|
|
223
|
-
Path
|
|
224
|
-
Path to the exodus (*.e) output file for this simulation case.
|
|
225
|
-
"""
|
|
226
|
-
return Path(files("pyvale.data").joinpath("case18_1_out.e"))
|
|
227
|
-
|
|
228
|
-
@staticmethod
|
|
229
|
-
def thermomechanical_3d_path() -> Path:
|
|
230
|
-
"""Path to a MOOSE simulation output in exodus format. This case is a
|
|
231
|
-
thermo-mechanical analysis of a 3D monoblock divertor armour with a heat
|
|
232
|
-
flux applied on the top surface and a heat transfer coefficient applied
|
|
233
|
-
on the inner surface of the pipe. The mechanical deformation results
|
|
234
|
-
from thermal expansion due to the imposed temperature gradient.
|
|
235
|
-
This model is solved for the scalar temperature field, vector
|
|
236
|
-
displacement and tensor strain field.
|
|
237
|
-
|
|
238
|
-
Returns
|
|
239
|
-
-------
|
|
240
|
-
Path
|
|
241
|
-
Path to the exodus (*.e) output file for this simulation case.
|
|
242
|
-
"""
|
|
243
|
-
return Path(files("pyvale.data").joinpath("case16_out.e"))
|
|
244
|
-
|
|
245
|
-
@staticmethod
|
|
246
|
-
def thermomechanical_2d_experiment_paths() -> list[Path]:
|
|
247
|
-
"""Path to a MOOSE simulation output in exodus format. This case is a
|
|
248
|
-
thermo-mechanical analysis of a 2D plate with a heat flux applied on one
|
|
249
|
-
edge and a heat transfer coefficient applied on the opposing edge. The
|
|
250
|
-
mechanical deformation results from thermal expansion due to the imposed
|
|
251
|
-
temperature gradient. This model is solved for the scalar temperature
|
|
252
|
-
field, vector temperature and tensor strain field.
|
|
253
|
-
|
|
254
|
-
Here we analyse 3 separate experiments where the thermal conductivity of
|
|
255
|
-
the material is perturbed from the nominal case by +/-10%.
|
|
256
|
-
|
|
257
|
-
The simulation parameters can be found in the corresponding MOOSE input
|
|
258
|
-
file: case18.i which can be retrieved using `sim_case_input_file_path`
|
|
259
|
-
in this class.
|
|
260
|
-
|
|
261
|
-
Returns
|
|
262
|
-
-------
|
|
263
|
-
Path
|
|
264
|
-
Path to the exodus (*.e) output file for this simulation case.
|
|
265
|
-
"""
|
|
266
|
-
return [Path(files("pyvale.data").joinpath("case18_1_out.e")),
|
|
267
|
-
Path(files("pyvale.data").joinpath("case18_2_out.e")),
|
|
268
|
-
Path(files("pyvale.data").joinpath("case18_3_out.e"))]
|
|
269
|
-
|
|
270
|
-
@staticmethod
|
|
271
|
-
def render_mechanical_3d_path() -> Path:
|
|
272
|
-
"""Path to a MOOSE simulation output in exodus format. This case is a
|
|
273
|
-
purely mechanical test case in 3D meant for testing image rendering
|
|
274
|
-
algorithms for digital image correlation simulation. The simulation
|
|
275
|
-
consists of a linear elastic thin plate with a hole loaded in tension.
|
|
276
|
-
The simulation uses linear tetrahedral elements for rendering tests.
|
|
277
|
-
|
|
278
|
-
Returns
|
|
279
|
-
-------
|
|
280
|
-
Path
|
|
281
|
-
Path to the exodus (*.e) output file for this simulation case.
|
|
282
|
-
"""
|
|
283
|
-
return Path(files("pyvale.data").joinpath("case26_out.e"))
|
|
284
|
-
|
|
285
|
-
@staticmethod
|
|
286
|
-
def render_simple_block_path() -> Path:
|
|
287
|
-
"""Path to a MOOSE simulation output in exodus format. This case is a
|
|
288
|
-
a simple rectangular block in 3D loaded in tension. It uses a minimum
|
|
289
|
-
number of elements and is intended purely for testing image rendering
|
|
290
|
-
algorithms. This simulation uses linear tetrahedral elements.
|
|
291
|
-
|
|
292
|
-
Returns
|
|
293
|
-
-------
|
|
294
|
-
Path
|
|
295
|
-
Path to the exodus (*.e) output file for this simulation case.
|
|
296
|
-
"""
|
|
297
|
-
return Path(files("pyvale.data").joinpath("case25_out.e"))
|
|
298
|
-
|
|
299
|
-
@staticmethod
|
|
300
|
-
def element_case_path(elem_type: EElemTest) -> Path:
|
|
301
|
-
"""Path to a MOOSE simulation output in exodus format. This case is a
|
|
302
|
-
10mm cube undergoing thermo-mechanical loading solved for the
|
|
303
|
-
temperature displacement and strain fields. This case is solved using a
|
|
304
|
-
variety of tetrahedral and hexahedral elements with linear or quadratic
|
|
305
|
-
shapes functions. These simulation cases are intended for testing
|
|
306
|
-
purposes and contain a minimal number of elements.
|
|
307
|
-
|
|
308
|
-
Parameters
|
|
309
|
-
----------
|
|
310
|
-
elem_type : EElemTest
|
|
311
|
-
Enumeration specifying the element type for this test case.
|
|
312
|
-
|
|
313
|
-
Returns
|
|
314
|
-
-------
|
|
315
|
-
Path
|
|
316
|
-
Path to the exodus (*.e) output file for this simulation case.
|
|
317
|
-
"""
|
|
318
|
-
return Path(files("pyvale.data")
|
|
319
|
-
.joinpath(f"case00_{elem_type.value}_out.e"))
|
|
320
|
-
|
|
321
|
-
@staticmethod
|
|
322
|
-
def dic_plate_with_hole_ref() -> Path:
|
|
323
|
-
"""Path to the reference image for the plate with hole example.
|
|
324
|
-
1040x1540 image in .tiff format.
|
|
325
|
-
|
|
326
|
-
Parameters
|
|
327
|
-
----------
|
|
328
|
-
elem_type : EElemTest
|
|
329
|
-
Enumeration specifying the element type for this test case.
|
|
330
|
-
|
|
331
|
-
Returns
|
|
332
|
-
-------
|
|
333
|
-
Path
|
|
334
|
-
Path to the reference image (*.tiff).
|
|
335
|
-
"""
|
|
336
|
-
return Path(files("pyvale.data")
|
|
337
|
-
.joinpath("plate_hole_ref0000.tiff"))
|
|
338
|
-
|
|
339
|
-
@staticmethod
|
|
340
|
-
def dic_plate_with_hole_def() -> Path:
|
|
341
|
-
"""Path to the deformed images for the plate with hole example.
|
|
342
|
-
1040x1540 image in .tiff format.
|
|
343
|
-
|
|
344
|
-
Parameters
|
|
345
|
-
----------
|
|
346
|
-
elem_type : EElemTest
|
|
347
|
-
Enumeration specifying the element type for this test case.
|
|
348
|
-
|
|
349
|
-
Returns
|
|
350
|
-
-------
|
|
351
|
-
Path
|
|
352
|
-
Path to the reference image (*.tiff).
|
|
353
|
-
"""
|
|
354
|
-
return Path(files("pyvale.data")
|
|
355
|
-
.joinpath("plate_hole_def*.tiff"))
|
|
356
|
-
|
|
357
|
-
@staticmethod
|
|
358
|
-
def dic_plate_rigid_ref() -> Path:
|
|
359
|
-
"""Path to the reference image for the plate with hole example.
|
|
360
|
-
1040x1540 image in .tiff format.
|
|
361
|
-
|
|
362
|
-
Parameters
|
|
363
|
-
----------
|
|
364
|
-
elem_type : EElemTest
|
|
365
|
-
Enumeration specifying the element type for this test case.
|
|
366
|
-
|
|
367
|
-
Returns
|
|
368
|
-
-------
|
|
369
|
-
Path
|
|
370
|
-
Path to the reference image (*.tiff).
|
|
371
|
-
"""
|
|
372
|
-
return Path(files("pyvale.data")
|
|
373
|
-
.joinpath("plate_rigid_ref0000.tiff"))
|
|
374
|
-
|
|
375
|
-
@staticmethod
|
|
376
|
-
def dic_plate_rigid_def() -> Path:
|
|
377
|
-
"""Path to the deformed images for the plate with hole example.
|
|
378
|
-
1040x1540 image in .tiff format.
|
|
379
|
-
|
|
380
|
-
Returns
|
|
381
|
-
-------
|
|
382
|
-
Path
|
|
383
|
-
Path to the reference image (*.tiff).
|
|
384
|
-
"""
|
|
385
|
-
return Path(files("pyvale.data")
|
|
386
|
-
.joinpath("plate_rigid_def*.tiff"))
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
@staticmethod
|
|
391
|
-
def dic_challenge_ref() -> Path:
|
|
392
|
-
"""Path to the reference images for the 2D dic challenge.
|
|
393
|
-
|
|
394
|
-
Returns
|
|
395
|
-
-------
|
|
396
|
-
Path
|
|
397
|
-
Path to the reference image (*.tiff).
|
|
398
|
-
"""
|
|
399
|
-
return Path(files("pyvale.data")
|
|
400
|
-
.joinpath("DIC_Challenge_Star_Noise_Ref.tif"))
|
|
401
|
-
|
|
402
|
-
@staticmethod
|
|
403
|
-
def dic_challenge_def() -> Path:
|
|
404
|
-
"""Path to the reference images for the 2D dic challenge.
|
|
405
|
-
|
|
406
|
-
Returns
|
|
407
|
-
-------
|
|
408
|
-
Path
|
|
409
|
-
Path to the reference image (*.tiff).
|
|
410
|
-
"""
|
|
411
|
-
return Path(files("pyvale.data")
|
|
412
|
-
.joinpath("DIC_Challenge_Star_Noise_Def.tif"))
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
pyvale/dicdataimport.py
DELETED
|
@@ -1,247 +0,0 @@
|
|
|
1
|
-
# ================================================================================
|
|
2
|
-
# pyvale: the python validation engine
|
|
3
|
-
# License: MIT
|
|
4
|
-
# Copyright (C) 2025 The Computer Aided Validation Team
|
|
5
|
-
# ================================================================================
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
import numpy as np
|
|
10
|
-
import glob
|
|
11
|
-
import os
|
|
12
|
-
from pathlib import Path
|
|
13
|
-
|
|
14
|
-
# import cython module
|
|
15
|
-
from pyvale.dicresults import DICResults
|
|
16
|
-
|
|
17
|
-
"""
|
|
18
|
-
Module responsible for handling importing of DIC results from completed
|
|
19
|
-
calculations.
|
|
20
|
-
"""
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
def dic_data_import(data: str | Path,
|
|
24
|
-
binary: bool = False,
|
|
25
|
-
layout: str = "matrix",
|
|
26
|
-
delimiter: str = " ") -> DICResults:
|
|
27
|
-
"""
|
|
28
|
-
Import DIC result data from human readable text or binary files.
|
|
29
|
-
|
|
30
|
-
Parameters
|
|
31
|
-
----------
|
|
32
|
-
|
|
33
|
-
data : str or pathlib.Path
|
|
34
|
-
Path pattern to the data files (can include wildcards). Default is "./".
|
|
35
|
-
|
|
36
|
-
layout : str, optional
|
|
37
|
-
Format of the output data layout: "column" (flat array per frame) or "matrix"
|
|
38
|
-
(reshaped grid per frame). Default is "column".
|
|
39
|
-
|
|
40
|
-
binary : bool, optional
|
|
41
|
-
If True, expects files in a specific binary format. If False, expects text data.
|
|
42
|
-
Default is False.
|
|
43
|
-
|
|
44
|
-
delimiter : str, optional
|
|
45
|
-
Delimiter used in text data files. Ignored if binary=True. Default is a single space.
|
|
46
|
-
|
|
47
|
-
Returns
|
|
48
|
-
-------
|
|
49
|
-
DICResults
|
|
50
|
-
A named container with the following fields:
|
|
51
|
-
- ss_x, ss_y (grid arrays if layout=="matrix"; otherwise, 1D integer arrays)
|
|
52
|
-
- u, v, m, converged, cost, ftol, xtol, niter (arrays with shape depending on layout)
|
|
53
|
-
- filenames (python list)
|
|
54
|
-
|
|
55
|
-
Raises
|
|
56
|
-
------
|
|
57
|
-
ValueError:
|
|
58
|
-
If `layout` is not "column" or "matrix", or text data has insufficient columns,
|
|
59
|
-
or binary rows are malformed.
|
|
60
|
-
|
|
61
|
-
FileNotFoundError:
|
|
62
|
-
If no matching data files are found.
|
|
63
|
-
"""
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
print("")
|
|
67
|
-
print("Attempting DIC Data import...")
|
|
68
|
-
print("")
|
|
69
|
-
|
|
70
|
-
# convert to str
|
|
71
|
-
if isinstance(data, Path):
|
|
72
|
-
data = str(data)
|
|
73
|
-
|
|
74
|
-
files = sorted(glob.glob(data))
|
|
75
|
-
filenames = files
|
|
76
|
-
if not files:
|
|
77
|
-
raise FileNotFoundError(f"No results found in: {data}")
|
|
78
|
-
|
|
79
|
-
print(f"Found {len(files)} files containing DIC results:")
|
|
80
|
-
for file in files:
|
|
81
|
-
print(f" - {file}")
|
|
82
|
-
print("")
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
# Read first file to define reference coordinates
|
|
86
|
-
read_data = read_binary if binary else read_text
|
|
87
|
-
ss_x_ref, ss_y_ref, *fields = read_data(files[0], delimiter=delimiter)
|
|
88
|
-
frames = [list(fields)]
|
|
89
|
-
|
|
90
|
-
for file in files[1:]:
|
|
91
|
-
ss_x, ss_y, *f = read_data(file, delimiter)
|
|
92
|
-
if not (np.array_equal(ss_x_ref, ss_x) and np.array_equal(ss_y_ref, ss_y)):
|
|
93
|
-
raise ValueError("Mismatch in coordinates across frames.")
|
|
94
|
-
frames.append(f)
|
|
95
|
-
|
|
96
|
-
# Stack fields into arrays
|
|
97
|
-
arrays = [np.stack([frame[i] for frame in frames]) for i in range(8)]
|
|
98
|
-
|
|
99
|
-
if layout == "matrix":
|
|
100
|
-
x_unique = np.unique(ss_x_ref)
|
|
101
|
-
y_unique = np.unique(ss_y_ref)
|
|
102
|
-
X, Y = np.meshgrid(x_unique, y_unique)
|
|
103
|
-
shape = (len(files), len(y_unique), len(x_unique))
|
|
104
|
-
arrays = [to_grid(a,shape,ss_x_ref, ss_y_ref, x_unique,y_unique) for a in arrays]
|
|
105
|
-
return DICResults(X, Y, *arrays, filenames)
|
|
106
|
-
else:
|
|
107
|
-
return DICResults(ss_x_ref, ss_y_ref, *arrays, filenames)
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
def read_binary(file: str, delimiter: str):
|
|
114
|
-
"""
|
|
115
|
-
Read a binary DIC result file and extract DIC fields.
|
|
116
|
-
|
|
117
|
-
Assumes a fixed binary structure with each row containing:
|
|
118
|
-
- 2 × int32 (subset coordinates)
|
|
119
|
-
- 6 × float64 (u, v, match quality, cost, ftol, xtol)
|
|
120
|
-
- 1 × int32 (number of iterations)
|
|
121
|
-
|
|
122
|
-
Parameters
|
|
123
|
-
----------
|
|
124
|
-
file : str
|
|
125
|
-
Path to the binary result file.
|
|
126
|
-
|
|
127
|
-
delimiter : str
|
|
128
|
-
Ignored for binary data (included for API consistency).
|
|
129
|
-
|
|
130
|
-
Returns
|
|
131
|
-
-------
|
|
132
|
-
tuple of np.ndarray
|
|
133
|
-
Arrays corresponding to:
|
|
134
|
-
(ss_x, ss_y, u, v, m, cost, ftol, xtol, niter)
|
|
135
|
-
|
|
136
|
-
Raises
|
|
137
|
-
------
|
|
138
|
-
ValueError
|
|
139
|
-
If the binary file size does not align with expected row size.
|
|
140
|
-
"""
|
|
141
|
-
|
|
142
|
-
row_size = (3 * 4 + 6 * 8)
|
|
143
|
-
with open(file, "rb") as f:
|
|
144
|
-
raw = f.read()
|
|
145
|
-
if len(raw) % row_size != 0:
|
|
146
|
-
raise ValueError("Binary file has incomplete rows.")
|
|
147
|
-
rows = len(raw) // row_size
|
|
148
|
-
arr = np.frombuffer(raw, dtype=np.uint8).reshape(rows, row_size)
|
|
149
|
-
def extract(col, dtype, start): return np.frombuffer(arr[:, start:start+col], dtype=dtype)
|
|
150
|
-
ss_x = extract(4, np.int32, 0)
|
|
151
|
-
ss_y = extract(4, np.int32, 4)
|
|
152
|
-
u = extract(8, np.float64, 8)
|
|
153
|
-
v = extract(8, np.float64, 16)
|
|
154
|
-
m = extract(8, np.float64, 24)
|
|
155
|
-
conv = extract(1, np.bool_, 25)
|
|
156
|
-
cost = extract(8, np.float64, 33)
|
|
157
|
-
ftol = extract(8, np.float64, 41)
|
|
158
|
-
xtol = extract(8, np.float64, 49)
|
|
159
|
-
niter = extract(4, np.int32, 57)
|
|
160
|
-
return ss_x, ss_y, u, v, m, conv, cost, ftol, xtol, niter
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
def read_text(file: str, delimiter: str):
|
|
166
|
-
"""
|
|
167
|
-
Read a human-readable text DIC result file and extract DIC fields.
|
|
168
|
-
|
|
169
|
-
Expects at least 9 columns:
|
|
170
|
-
[ss_x, ss_y, u, v, m, conv, cost, ftol, xtol, niter]
|
|
171
|
-
|
|
172
|
-
Parameters
|
|
173
|
-
----------
|
|
174
|
-
file : str
|
|
175
|
-
Path to the text result file.
|
|
176
|
-
|
|
177
|
-
delimiter : str
|
|
178
|
-
Delimiter used in the text file (e.g., space, tab, comma).
|
|
179
|
-
|
|
180
|
-
Returns
|
|
181
|
-
-------
|
|
182
|
-
tuple of np.ndarray
|
|
183
|
-
Arrays corresponding to:
|
|
184
|
-
(ss_x, ss_y, u, v, m, conv, cost, ftol, xtol, niter)
|
|
185
|
-
|
|
186
|
-
Raises
|
|
187
|
-
------
|
|
188
|
-
ValueError
|
|
189
|
-
If the text file has fewer than 9 columns.
|
|
190
|
-
"""
|
|
191
|
-
|
|
192
|
-
data = np.loadtxt(file, delimiter=delimiter, skiprows=1)
|
|
193
|
-
if data.shape[1] < 9:
|
|
194
|
-
raise ValueError("Text data must have at least 9 columns.")
|
|
195
|
-
return (
|
|
196
|
-
data[:, 0].astype(np.int32), # ss_x
|
|
197
|
-
data[:, 1].astype(np.int32), # ss_y
|
|
198
|
-
data[:, 2], data[:, 3], data[:, 4], # u, v, mag
|
|
199
|
-
data[:, 5].astype(np.bool_), # convergence
|
|
200
|
-
data[:, 6], data[:, 7], data[:,8], # cost, ftol, xtol
|
|
201
|
-
data[:, 9].astype(np.int32) #niter
|
|
202
|
-
)
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
def to_grid(data, shape, ss_x_ref, ss_y_ref, x_unique, y_unique):
|
|
209
|
-
"""
|
|
210
|
-
Reshape a 2D DIC field from flat (column) format into grid (matrix) format.
|
|
211
|
-
|
|
212
|
-
This is used when output layout is specified as "matrix".
|
|
213
|
-
Maps values using reference subset coordinates (ss_x_ref, ss_y_ref).
|
|
214
|
-
|
|
215
|
-
Parameters
|
|
216
|
-
ol
|
|
217
|
-
----------
|
|
218
|
-
data : np.ndarray
|
|
219
|
-
Array of shape (n_frames, n_points) to be reshaped into (n_frames, height, width).
|
|
220
|
-
|
|
221
|
-
shape : tuple
|
|
222
|
-
Target shape of output array: (n_frames, height, width).
|
|
223
|
-
|
|
224
|
-
ss_x_ref : np.ndarray
|
|
225
|
-
X coordinates of subset centers.
|
|
226
|
-
|
|
227
|
-
ss_y_ref : np.ndarray
|
|
228
|
-
Y coordinates of subset centers.
|
|
229
|
-
|
|
230
|
-
x_unique : np.ndarray
|
|
231
|
-
Sorted unique X coordinates in the grid.
|
|
232
|
-
|
|
233
|
-
y_unique : np.ndarray
|
|
234
|
-
Sorted unique Y coordinates in the grid.
|
|
235
|
-
|
|
236
|
-
Returns
|
|
237
|
-
-------
|
|
238
|
-
np.ndarray
|
|
239
|
-
Reshaped array with shape `shape`, filled with NaNs where no data exists.
|
|
240
|
-
"""
|
|
241
|
-
|
|
242
|
-
grid = np.full(shape, np.nan)
|
|
243
|
-
for i, (x, y) in enumerate(zip(ss_x_ref, ss_y_ref)):
|
|
244
|
-
x_idx = np.where(x_unique == x)[0][0]
|
|
245
|
-
y_idx = np.where(y_unique == y)[0][0]
|
|
246
|
-
grid[:, y_idx, x_idx] = data[:, i]
|
|
247
|
-
return grid
|