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
|
@@ -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
|
+
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
# ==============================================================================
|
|
2
|
+
# pyvale: the python validation engine
|
|
3
|
+
# License: MIT
|
|
4
|
+
# Copyright (C) 2025 The Computer Aided Validation Team
|
|
5
|
+
# ==============================================================================
|
|
6
|
+
|
|
7
|
+
"""
|
|
8
|
+
Running MOOSE once
|
|
9
|
+
================================================================================
|
|
10
|
+
|
|
11
|
+
In this example we will run a single moose simulation from a moose input .i file
|
|
12
|
+
using a 'runner' object.
|
|
13
|
+
|
|
14
|
+
**Installing moose**: To run this example you will need to have installed moose
|
|
15
|
+
on your system. As moose supports unix operating systems windows users will need
|
|
16
|
+
to use windows subsystem for linux (WSL). We use the proteus moose build which
|
|
17
|
+
can be found here: https://github.com/aurora-multiphysics/proteus. Build scripts
|
|
18
|
+
for common linux distributions can be found in the 'scripts' directory of the
|
|
19
|
+
repo. You can also create your own moose build using instructions here:
|
|
20
|
+
https://mooseframework.inl.gov/.
|
|
21
|
+
|
|
22
|
+
We start by importing what we need for this example.
|
|
23
|
+
"""
|
|
24
|
+
|
|
25
|
+
import time
|
|
26
|
+
from pathlib import Path
|
|
27
|
+
|
|
28
|
+
#pyvale imports
|
|
29
|
+
import pyvale.dataset as dataset
|
|
30
|
+
from pyvale.mooseherder import (MooseConfig,
|
|
31
|
+
MooseRunner)
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
#%%
|
|
35
|
+
# First we build our moose configuration which gives the location of our main
|
|
36
|
+
# moose build, our moose app and the name of the app to use when called on the
|
|
37
|
+
# command line.
|
|
38
|
+
config = {'main_path': Path.home()/ 'moose',
|
|
39
|
+
'app_path': Path.home() / 'proteus',
|
|
40
|
+
'app_name': 'proteus-opt'}
|
|
41
|
+
moose_config = MooseConfig(config)
|
|
42
|
+
|
|
43
|
+
#%%
|
|
44
|
+
# We can now build a runner object using our configuration. We can then set some
|
|
45
|
+
# options for the run including parallelisation and if we should redirect
|
|
46
|
+
# terminal output to file. For smaller simulations we are better off using
|
|
47
|
+
# threads for paralleisation as they reduce overhead compared to MPI tasks.
|
|
48
|
+
moose_runner = MooseRunner(moose_config)
|
|
49
|
+
|
|
50
|
+
moose_runner.set_run_opts(n_tasks = 1,
|
|
51
|
+
n_threads = 8,
|
|
52
|
+
redirect_out = False)
|
|
53
|
+
|
|
54
|
+
#%%
|
|
55
|
+
# Let's grab a simple thermo-mechanical cube test case from pyvale's moose
|
|
56
|
+
# simulation library and we will set this as the input file to run with our
|
|
57
|
+
# 'runner'.
|
|
58
|
+
moose_input = dataset.element_case_input_path(dataset.EElemTest.HEX20)
|
|
59
|
+
moose_runner.set_input_file(moose_input)
|
|
60
|
+
|
|
61
|
+
#%%
|
|
62
|
+
# Our moose runner will pass a list of strings which form the command line to
|
|
63
|
+
# run our moose simulation. We print the list of command line arguments here so
|
|
64
|
+
# we can check we are correctly calling our input file with the run options we
|
|
65
|
+
# want.
|
|
66
|
+
print(moose_runner.get_arg_list())
|
|
67
|
+
print()
|
|
68
|
+
|
|
69
|
+
#%%
|
|
70
|
+
# To run our moose simulation we just need to call 'run', here we will time our
|
|
71
|
+
# moose run and then print the solve time to the terminal
|
|
72
|
+
start_time = time.perf_counter()
|
|
73
|
+
moose_runner.run()
|
|
74
|
+
run_time = time.perf_counter() - start_time
|
|
75
|
+
|
|
76
|
+
print()
|
|
77
|
+
print("-"*80)
|
|
78
|
+
print(f'MOOSE run time = {run_time:.3f} seconds')
|
|
79
|
+
print("-"*80)
|
|
80
|
+
print()
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
# ==============================================================================
|
|
2
|
+
# pyvale: the python validation engine
|
|
3
|
+
# License: MIT
|
|
4
|
+
# Copyright (C) 2025 The Computer Aided Validation Team
|
|
5
|
+
# ==============================================================================
|
|
6
|
+
|
|
7
|
+
"""
|
|
8
|
+
Running Gmsh once
|
|
9
|
+
================================================================================
|
|
10
|
+
|
|
11
|
+
In this example we will run a gmsh script to generate a mesh file using the
|
|
12
|
+
GmshRunner class.
|
|
13
|
+
|
|
14
|
+
**Installing gmsh**: For this example you will need to have a gmsh executable
|
|
15
|
+
which can be downloaded and installed from here: https://gmsh.info/#Download
|
|
16
|
+
|
|
17
|
+
We start by importing what we need for this example.
|
|
18
|
+
"""
|
|
19
|
+
|
|
20
|
+
import time
|
|
21
|
+
from pathlib import Path
|
|
22
|
+
|
|
23
|
+
#pyvale imports
|
|
24
|
+
import pyvale.dataset as dataset
|
|
25
|
+
from pyvale.mooseherder import GmshRunner
|
|
26
|
+
|
|
27
|
+
#%%
|
|
28
|
+
# First we need to create a 'runner' for gmsh which needs to know the path to
|
|
29
|
+
# the gmsh executable. You will need to replace this path with the path to where
|
|
30
|
+
# you have install gmsh on your system.
|
|
31
|
+
gmsh_path = Path.home() / 'gmsh/bin/gmsh'
|
|
32
|
+
gmsh_runner = GmshRunner(gmsh_path)
|
|
33
|
+
|
|
34
|
+
#%%
|
|
35
|
+
# Next we grab a gmsh file from pyvale simulation library and we set this as the
|
|
36
|
+
# input file for our runner.
|
|
37
|
+
gmsh_input = dataset.sim_case_gmsh_file_path(case_num=17)
|
|
38
|
+
gmsh_runner.set_input_file(gmsh_input)
|
|
39
|
+
|
|
40
|
+
#%%
|
|
41
|
+
# Now we can run gmsh to generate our mesh using the run method, the parse only
|
|
42
|
+
# flag means we will run gmsh head less and not open the gmsh GUI but terminal
|
|
43
|
+
# output will still be written to stdout.
|
|
44
|
+
#
|
|
45
|
+
# We also use our performance timer to time how long our mesh generation takes
|
|
46
|
+
# and then we print this to the console. Note that parallelisation options for
|
|
47
|
+
# gmsh can be controlled in the gmsh .geo script file.
|
|
48
|
+
start_time = time.perf_counter()
|
|
49
|
+
gmsh_runner.run(gmsh_input,parse_only=True)
|
|
50
|
+
run_time = time.perf_counter() - start_time
|
|
51
|
+
|
|
52
|
+
print()
|
|
53
|
+
print("-"*80)
|
|
54
|
+
print(f'Gmsh run time = {run_time :.3f} seconds')
|
|
55
|
+
print("-"*80)
|
|
56
|
+
print()
|
|
57
|
+
|
|
58
|
+
#%%
|
|
59
|
+
# The GmshRunner and the MooseRunner implement the SimRunner abstract base
|
|
60
|
+
# class. Later on when we will see that we can use this to run a list of
|
|
61
|
+
# different sim runners in order using MooseHerd workflow manager. This allows
|
|
62
|
+
# us to first build our mesh with gmsh and then run a moose simulation using
|
|
63
|
+
# that mesh. We can also implement our own SimRunner's to add additional pre or
|
|
64
|
+
# post processing steps to our simulation chain.
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
# ==============================================================================
|
|
2
|
+
# pyvale: the python validation engine
|
|
3
|
+
# License: MIT
|
|
4
|
+
# Copyright (C) 2025 The Computer Aided Validation Team
|
|
5
|
+
# ==============================================================================
|
|
6
|
+
|
|
7
|
+
"""
|
|
8
|
+
Run Gmsh then MOOSE once
|
|
9
|
+
================================================================================
|
|
10
|
+
|
|
11
|
+
In this example we use a gmsh runner followed by a moose runner to generate our
|
|
12
|
+
mesh and then run a moose simulation using this mesh. The moose input file needs
|
|
13
|
+
to know the name of the gmsh .msh file which is specified in the gmsh .geo
|
|
14
|
+
script when the Save command is called. It is possible to use the input
|
|
15
|
+
modifiers we have seen previously to update this file name as a variable in the
|
|
16
|
+
moose input script but for this example we have set things manually inside the
|
|
17
|
+
moose input script.
|
|
18
|
+
|
|
19
|
+
**Installing moose**: To run this example you will need to have installed moose
|
|
20
|
+
on your system. As moose supports unix operating systems windows users will need
|
|
21
|
+
to use windows subsystem for linux (WSL). We use the proteus moose build which
|
|
22
|
+
can be found here: https://github.com/aurora-multiphysics/proteus. Build scripts
|
|
23
|
+
for common linux distributions can be found in the 'scripts' directory of the
|
|
24
|
+
repo. You can also create your own moose build using instructions here:
|
|
25
|
+
https://mooseframework.inl.gov/.
|
|
26
|
+
|
|
27
|
+
**Installing gmsh**: For this example you will need to have a gmsh executable
|
|
28
|
+
which can be downloaded and installed from here: https://gmsh.info/#Download
|
|
29
|
+
|
|
30
|
+
We start by importing what we need for this example.
|
|
31
|
+
"""
|
|
32
|
+
|
|
33
|
+
import time
|
|
34
|
+
import shutil
|
|
35
|
+
from pathlib import Path
|
|
36
|
+
|
|
37
|
+
#pyvale imports
|
|
38
|
+
import pyvale.dataset as dataset
|
|
39
|
+
from pyvale.mooseherder import (MooseConfig,
|
|
40
|
+
GmshRunner,
|
|
41
|
+
MooseRunner)
|
|
42
|
+
|
|
43
|
+
#%%
|
|
44
|
+
# We need to make sure the output .msh file from gmsh can be found by our moose
|
|
45
|
+
# input script so we are going to put them in our standard pyvale-output
|
|
46
|
+
# directory in our current working directory. First we grab the paths for the
|
|
47
|
+
# .geo and .i and then we copy them to the pyvale-output directory where we will
|
|
48
|
+
# run our simulation from. We then print the paths to we can see where the files
|
|
49
|
+
# are - try opening them with your text editor of choice so you can see how the
|
|
50
|
+
# name of the mesh is specified in the gmsh .geo as the .msh output and the then
|
|
51
|
+
# how the name is matched in the moose .i to read the .msh to run the sim.
|
|
52
|
+
|
|
53
|
+
output_path = Path.cwd() / "pyvale-output"
|
|
54
|
+
if not output_path.is_dir():
|
|
55
|
+
output_path.mkdir(parents=True, exist_ok=True)
|
|
56
|
+
|
|
57
|
+
gmsh_file = dataset.sim_case_gmsh_file_path(case_num=17)
|
|
58
|
+
gmsh_input = output_path / gmsh_file.name
|
|
59
|
+
|
|
60
|
+
moose_file = dataset.sim_case_input_file_path(case_num=17)
|
|
61
|
+
moose_input = output_path / moose_file.name
|
|
62
|
+
|
|
63
|
+
shutil.copyfile(moose_file,moose_input)
|
|
64
|
+
shutil.copyfile(gmsh_file,gmsh_input)
|
|
65
|
+
|
|
66
|
+
print(f"\n{moose_input.resolve()=}")
|
|
67
|
+
print(f"{gmsh_input.resolve()=}\n")
|
|
68
|
+
|
|
69
|
+
#%%
|
|
70
|
+
# We need to run gmsh first to generate our .msh file so we set it up and run it
|
|
71
|
+
# in exactly the same way as we have done in the previous example. We pass the
|
|
72
|
+
# path to the gmsh executable to our runner. We then set our input file and call
|
|
73
|
+
# run to generate the mesh.
|
|
74
|
+
gmsh_path = Path.home() / 'gmsh/bin/gmsh'
|
|
75
|
+
gmsh_runner = GmshRunner(gmsh_path)
|
|
76
|
+
|
|
77
|
+
gmsh_runner.set_input_file(gmsh_input)
|
|
78
|
+
|
|
79
|
+
gmsh_start = time.perf_counter()
|
|
80
|
+
gmsh_runner.run(parse_only=True)
|
|
81
|
+
gmsh_run_time = time.perf_counter()-gmsh_start
|
|
82
|
+
|
|
83
|
+
#%%
|
|
84
|
+
# Now that we have our mesh we can run our moose simulation. We will setup and
|
|
85
|
+
# run moose in exactly the same was as in a previous example. First, we setup
|
|
86
|
+
# our moose configuration and pass this to our runner. We then set our run /
|
|
87
|
+
# parallelisation options before calling run to extecute the simulation.
|
|
88
|
+
config = {'main_path': Path.home()/ 'moose',
|
|
89
|
+
'app_path': Path.home() / 'proteus',
|
|
90
|
+
'app_name': 'proteus-opt'}
|
|
91
|
+
moose_config = MooseConfig(config)
|
|
92
|
+
|
|
93
|
+
moose_runner = MooseRunner(moose_config)
|
|
94
|
+
|
|
95
|
+
moose_runner.set_run_opts(n_tasks = 1,
|
|
96
|
+
n_threads = 4,
|
|
97
|
+
redirect_out = True)
|
|
98
|
+
|
|
99
|
+
moose_runner.set_input_file(moose_input)
|
|
100
|
+
|
|
101
|
+
moose_start = time.perf_counter()
|
|
102
|
+
moose_runner.run()
|
|
103
|
+
moose_run_time = time.perf_counter() - moose_start
|
|
104
|
+
|
|
105
|
+
#%%
|
|
106
|
+
# Finally we print the execution times of both runners and print these to the
|
|
107
|
+
# console.
|
|
108
|
+
print("-"*80)
|
|
109
|
+
print(f'Gmsh run time = {gmsh_run_time:.2f} seconds')
|
|
110
|
+
print(f'MOOOSE run time = {moose_run_time:.2f} seconds')
|
|
111
|
+
print("-"*80)
|
|
112
|
+
print()
|
|
113
|
+
|
|
114
|
+
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
# ==============================================================================
|
|
2
|
+
# pyvale: the python validation engine
|
|
3
|
+
# License: MIT
|
|
4
|
+
# Copyright (C) 2025 The Computer Aided Validation Team
|
|
5
|
+
# ==============================================================================
|
|
6
|
+
|
|
7
|
+
"""
|
|
8
|
+
Running a parameter sweep of a MOOSE simulation
|
|
9
|
+
================================================================================
|
|
10
|
+
|
|
11
|
+
In this example we will perform a parameter sweep of a moose simulation showing
|
|
12
|
+
the capability of the 'herder' workflow manager which can be passed a list of
|
|
13
|
+
'input modifiers' and 'runners'. The 'herder' will then use the 'input
|
|
14
|
+
modifiers' to update simulation parameters and then call the respective 'runner'
|
|
15
|
+
using the modified input file. In this example we will also see that the
|
|
16
|
+
'herder' can be used to execute a parameter sweep sequentially or in parallel.
|
|
17
|
+
|
|
18
|
+
**Installing moose**: To run this example you will need to have installed moose
|
|
19
|
+
on your system. As moose supports unix operating systems windows users will need
|
|
20
|
+
to use windows subsystem for linux (WSL). We use the proteus moose build which
|
|
21
|
+
can be found here: https://github.com/aurora-multiphysics/proteus. Build scripts
|
|
22
|
+
for common linux distributions can be found in the 'scripts' directory of the
|
|
23
|
+
repo. You can also create your own moose build using instructions here:
|
|
24
|
+
https://mooseframework.inl.gov/.
|
|
25
|
+
|
|
26
|
+
We start by importing what we need for this example.
|
|
27
|
+
"""
|
|
28
|
+
|
|
29
|
+
from pathlib import Path
|
|
30
|
+
import numpy as np
|
|
31
|
+
|
|
32
|
+
#pyvale imports
|
|
33
|
+
import pyvale.dataset as dataset
|
|
34
|
+
from pyvale.mooseherder import (MooseHerd,
|
|
35
|
+
MooseRunner,
|
|
36
|
+
InputModifier,
|
|
37
|
+
DirectoryManager,
|
|
38
|
+
MooseConfig,
|
|
39
|
+
sweep_param_grid)
|
|
40
|
+
|
|
41
|
+
#%%
|
|
42
|
+
# First we are going to setup an input modifier and a runner for our moose
|
|
43
|
+
# simulation. Here we need to make sure that when we set our moose
|
|
44
|
+
# parallelisation options we leave enough threads for all the simulations that
|
|
45
|
+
# are running at once base on our CPU. It is also helpful to redirect stdout to
|
|
46
|
+
# file so that our terminal does not become a mess when we start running our
|
|
47
|
+
# simulations in parallel.
|
|
48
|
+
moose_input = dataset.element_case_input_path(dataset.EElemTest.HEX20)
|
|
49
|
+
moose_modifier = InputModifier(moose_input,'#','')
|
|
50
|
+
|
|
51
|
+
config = {'main_path': Path.home()/ 'moose',
|
|
52
|
+
'app_path': Path.home() / 'proteus',
|
|
53
|
+
'app_name': 'proteus-opt'}
|
|
54
|
+
moose_config = MooseConfig(config)
|
|
55
|
+
|
|
56
|
+
moose_runner = MooseRunner(moose_config)
|
|
57
|
+
moose_runner.set_run_opts(n_tasks = 1,
|
|
58
|
+
n_threads = 2,
|
|
59
|
+
redirect_out = True)
|
|
60
|
+
|
|
61
|
+
#%%
|
|
62
|
+
# Now we are going to create a directory manager which will be used to make sure
|
|
63
|
+
# our simulations are run in separate directories. We then create our herd
|
|
64
|
+
# workflow manager with our list of runners and corresponding input modifiers.
|
|
65
|
+
# In our case we are only running moose so our lists have a single item. The
|
|
66
|
+
# last thing we do is specify the number of simulations we want to run in
|
|
67
|
+
# parallel, for this case we match the number of directories.
|
|
68
|
+
num_para_sims: int = 4
|
|
69
|
+
dir_manager = DirectoryManager(n_dirs=num_para_sims)
|
|
70
|
+
herd = MooseHerd([moose_runner],[moose_modifier],dir_manager)
|
|
71
|
+
herd.set_num_para_sims(n_para=num_para_sims)
|
|
72
|
+
|
|
73
|
+
#%%
|
|
74
|
+
# We need somewhere to run our simulations and store the output so we create our
|
|
75
|
+
# standard pyvale output directory and then we set this as the base directory
|
|
76
|
+
# for our directory manager. We clear any old output directories and then create
|
|
77
|
+
# new ones ready to write our simulation output to.
|
|
78
|
+
output_path = Path.cwd() / "pyvale-output"
|
|
79
|
+
if not output_path.is_dir():
|
|
80
|
+
output_path.mkdir(parents=True, exist_ok=True)
|
|
81
|
+
|
|
82
|
+
dir_manager.set_base_dir(output_path)
|
|
83
|
+
dir_manager.reset_dirs()
|
|
84
|
+
|
|
85
|
+
#%%
|
|
86
|
+
# We now need to generate the parameter combinations we want to run using our
|
|
87
|
+
# 'herd'. This is given as a list of list of dictionaries where the outer list
|
|
88
|
+
# corresponds to the unique simulation chain, the inner list corresponds to each
|
|
89
|
+
# simulation runner in the chain, and the dicitionary contains key value pairs
|
|
90
|
+
# where the keys are the variables names to edit in the input file. For this
|
|
91
|
+
# case we only have moose in our simulation chain so our inner list will only
|
|
92
|
+
# have a length of one but in the next example we will see how we can combine
|
|
93
|
+
# a parameter sweep with gmsh->moose sweeping all possible combinations of
|
|
94
|
+
# variables for both simulation tools.
|
|
95
|
+
#
|
|
96
|
+
# For now we are going to use a helper function from mooseherder which will
|
|
97
|
+
# generate all possible combination for us in the correct data format. We just
|
|
98
|
+
# provide a dictionary of lists of unique parameters we want to analyse. Finally
|
|
99
|
+
# we print the unique combinations of parameters to the terminal as well as the
|
|
100
|
+
# total number of simulations to check everything is working as expected.
|
|
101
|
+
|
|
102
|
+
moose_params = {"nElemX": (2,3,4),
|
|
103
|
+
"lengX": np.array([10e-3,15e-3]),
|
|
104
|
+
"PRatio":(0.3,)}
|
|
105
|
+
params = [moose_params,]
|
|
106
|
+
sweep_params = sweep_param_grid(params)
|
|
107
|
+
|
|
108
|
+
print("\nParameter sweep variables by simulation:")
|
|
109
|
+
for ii,pp in enumerate(sweep_params):
|
|
110
|
+
print(f"Sim: {ii}, Params [moose,]: {pp}")
|
|
111
|
+
|
|
112
|
+
print()
|
|
113
|
+
print(f"Total simulations = {len(sweep_params)}")
|
|
114
|
+
print()
|
|
115
|
+
|
|
116
|
+
#%%
|
|
117
|
+
# The run once function of the herd allows us to run a particular single
|
|
118
|
+
# simulation chain from anywhere in the sweep. This is useful for debugging when
|
|
119
|
+
# you want to rerun a single case to see the output or what went wrong. The herd
|
|
120
|
+
# also stores the solution time for each single iteration so we will store this
|
|
121
|
+
# to estimate how long the whole sweep should take when solving sequentially.
|
|
122
|
+
herd.run_once(0,sweep_params[0])
|
|
123
|
+
time_run_once = herd.get_iter_time()
|
|
124
|
+
|
|
125
|
+
|
|
126
|
+
#%%
|
|
127
|
+
# We can run the whole parameter sweep sequentially (one by one) using the run
|
|
128
|
+
# sequential function of the herd. We also store the total solution time
|
|
129
|
+
# for all simulation chains so that we can compare to a parallel run later. Note
|
|
130
|
+
# that it can be beneficial to run sequentially if you are using the herd within
|
|
131
|
+
# another loop or if one of the steps in your simulation chain is expensive and
|
|
132
|
+
# that step needs the computational resource.
|
|
133
|
+
herd.run_sequential(sweep_params)
|
|
134
|
+
time_run_seq = herd.get_sweep_time()
|
|
135
|
+
|
|
136
|
+
#%%
|
|
137
|
+
# Finally, we can run our parameter sweep in parallel. We need a main guard here
|
|
138
|
+
# as we use the multi-processing package. We also store the sweep time for this
|
|
139
|
+
# case to compare our sequential to parallel run time.
|
|
140
|
+
if __name__ == "__main__":
|
|
141
|
+
herd.run_para(sweep_params)
|
|
142
|
+
time_run_para = herd.get_sweep_time()
|
|
143
|
+
|
|
144
|
+
#%%
|
|
145
|
+
# Now that we have run all cases we can compare run times for a single
|
|
146
|
+
# simulation multiplied by the total number of simulations against runnning the
|
|
147
|
+
# sweep in parallel
|
|
148
|
+
print("-"*80)
|
|
149
|
+
print(f'Run time (one iter) = {time_run_once:.3f} seconds')
|
|
150
|
+
print(f'Est. time (one iter x num sims) = {(time_run_once*len(sweep_params)):.3f} seconds')
|
|
151
|
+
print()
|
|
152
|
+
print(f'Run time (seq) = {time_run_seq:.3f} seconds')
|
|
153
|
+
print(f'Run time (para) = {time_run_para:.3f} seconds')
|
|
154
|
+
print("-"*80)
|
|
155
|
+
print()
|
|
156
|
+
|
|
157
|
+
|