.. DO NOT EDIT. .. THIS FILE WAS AUTOMATICALLY GENERATED BY SPHINX-GALLERY. .. TO MAKE CHANGES, EDIT THE SOURCE PYTHON FILE: .. "examples/basics/ex4_1_expsim2d_thermmech2d.py" .. LINE NUMBERS ARE GIVEN BELOW. .. only:: html .. note:: :class: sphx-glr-download-link-note :ref:`Go to the end ` to download the full example code. .. rst-class:: sphx-glr-example-title .. _sphx_glr_examples_basics_ex4_1_expsim2d_thermmech2d.py: Basics: Multi-physics experiment simulation in 2D ================================================================================ In previous examples we have built our virtual sensor array and used this to run a single simulated experiment. However, we will generally want to run many simulated experiments and perform statistical analysis on the results. In this example we demonstrate how `pyvale` can be used to run a set of simulated experiments with a series of sensor arrays, one measuring temperature and the other measuring strain. We also show how this analysis can be performed over a set of input physics simulations. Note that this tutorial assumes you are familiar with the use of `pyvale` for scalar and tensor fields as described in the previous examples. Test case: thermo-mechanical analysis of a 2D plate with a temperature gradient. .. GENERATED FROM PYTHON SOURCE LINES 23-29 .. code-block:: Python import numpy as np import matplotlib.pyplot as plt import mooseherder as mh import pyvale as pyv .. GENERATED FROM PYTHON SOURCE LINES 30-35 Here we get a list of paths to a set of 3 simulations in this case the simulation is a 2D plate with a heat flux on one edge and a heat transfer coefficient on the other. The mechanical deformation is a result of thermal expansion. The 3 simulation cases cover a nominal thermal and a perturbation of +/-10%. .. GENERATED FROM PYTHON SOURCE LINES 35-38 .. code-block:: Python data_paths = pyv.DataSet.thermomechanical_2d_experiment_paths() elem_dims: int = 2 .. GENERATED FROM PYTHON SOURCE LINES 39-42 We now loop over the paths and load each into a `SimData` object. We then scale our length units to mm and append the simulation to a list which we will use to perform our simulated experiments. .. GENERATED FROM PYTHON SOURCE LINES 42-51 .. code-block:: Python disp_comps = ("disp_x","disp_y") sim_list = [] for pp in data_paths: sim_data = mh.ExodusReader(pp).read_all_sim_data() sim_data = pyv.scale_length_units(scale=1000.0, sim_data=sim_data, disp_comps=disp_comps) sim_list.append(sim_data) .. GENERATED FROM PYTHON SOURCE LINES 52-54 We will use the same sampling times for both the thermal and strain sensor arrays as well as the same positions. .. GENERATED FROM PYTHON SOURCE LINES 54-56 .. code-block:: Python sample_times = np.linspace(0.0,np.max(sim_data.time),50) .. GENERATED FROM PYTHON SOURCE LINES 57-59 We place 4 thermal sensors along the mid line of the plate in the direction of the temperature gradient. .. GENERATED FROM PYTHON SOURCE LINES 59-68 .. code-block:: Python n_sens = (4,1,1) x_lims = (0.0,100.0) y_lims = (0.0,50.0) z_lims = (0.0,0.0) tc_sens_pos = pyv.create_sensor_pos_array(n_sens,x_lims,y_lims,z_lims) tc_sens_data = pyv.SensorData(positions=tc_sens_pos, sample_times=sample_times) .. GENERATED FROM PYTHON SOURCE LINES 69-74 We use the sensor array factory to give us thermocouples with basic 2% errors with uniform systematic error and normal random error. Note that we need to provide a `SimData` object to create our sensor array but when we run our experiment the field object that relies on this will switch the sim data for the required simulation in our list. .. GENERATED FROM PYTHON SOURCE LINES 74-82 .. code-block:: Python tc_field_name = "temperature" tc_array = pyv.SensorArrayFactory \ .thermocouples_basic_errs(sim_list[0], tc_sens_data, elem_dims=elem_dims, field_name=tc_field_name, errs_pc=2.0) .. GENERATED FROM PYTHON SOURCE LINES 83-84 We place 3 strain gauges along the direction of the temperature gradient. .. GENERATED FROM PYTHON SOURCE LINES 84-89 .. code-block:: Python n_sens = (3,1,1) sg_sens_pos = pyv.create_sensor_pos_array(n_sens,x_lims,y_lims,z_lims) sg_sens_data = pyv.SensorData(positions=sg_sens_pos, sample_times=sample_times) .. GENERATED FROM PYTHON SOURCE LINES 90-91 We use the factory to give us a basic strain gauge array as well. .. GENERATED FROM PYTHON SOURCE LINES 91-103 .. code-block:: Python sg_field_name = "strain" sg_norm_comps = ("strain_xx","strain_yy") sg_dev_comps = ("strain_xy",) sg_array = pyv.SensorArrayFactory \ .strain_gauges_basic_errs(sim_list[0], sg_sens_data, elem_dims=elem_dims, field_name=sg_field_name, norm_comps=sg_norm_comps, dev_comps=sg_dev_comps, errs_pc=2.0) .. GENERATED FROM PYTHON SOURCE LINES 104-108 Now we have our list of simulations and the two sensor arrays we want to apply to the simulations. We create a list of our two sensor arrays and use this to create an experiment simulator while specifying how many simulate experiments we want to run per simulation and sensor array. .. GENERATED FROM PYTHON SOURCE LINES 108-113 .. code-block:: Python sensor_arrays = [tc_array,sg_array] exp_sim = pyv.ExperimentSimulator(sim_list, sensor_arrays, num_exp_per_sim=1000) .. GENERATED FROM PYTHON SOURCE LINES 114-120 We can now run our experiments for all our sensor arrays. We are returned a list of numpy arrays. The index in the list corresponds to the position of the sensor array in the list. So if we want our thermocouple results we want exp_data[0] and for our strain gauges exp_data[1]. The numpy array has the following shape: (n_sims,n_exps,n_sensors,n_field_comps,n_time_steps) .. GENERATED FROM PYTHON SOURCE LINES 120-122 .. code-block:: Python exp_data = exp_sim.run_experiments() .. GENERATED FROM PYTHON SOURCE LINES 123-130 We can also calculate summary statistics for each sensor array which is returned as a list where the position corresponds to the sensor array as in our experimental data. The experiment stats object contains numpy arrays for each statistic that is collapsed over the number of experiments. The statistics we can acces include: mean, standard deviation minimum, maximum, median, median absolute deviation and the 25% and 75% quartiles. See the `ExperimentStats` data class for details. .. GENERATED FROM PYTHON SOURCE LINES 130-132 .. code-block:: Python exp_stats = exp_sim.calc_stats() .. GENERATED FROM PYTHON SOURCE LINES 133-135 We will index into and print the shape of our exp_data and exp_stats lists to demonstrate how this works in practice: .. GENERATED FROM PYTHON SOURCE LINES 135-159 .. code-block:: Python print(80*"=") print("exp_data and exp_stats are lists where the index is the sensor array") print("position in the list as field components are not consistent dims.\n") print(80*"-") print("Thermal sensor array @ exp_data[0]") print(80*"-") print("shape=(n_sims,n_exps,n_sensors,n_field_comps,n_time_steps)") print(f"{exp_data[0].shape=}") print() print("Stats are calculated over all experiments (axis=1)") print("shape=(n_sims,n_sensors,n_field_comps,n_time_steps)") print(f"{exp_stats[0].max.shape=}") print() print(80*"-") print("Mechanical sensor array @ exp_data[1]") print(80*"-") print("shape=(n_sims,n_exps,n_sensors,n_field_comps,n_time_steps)") print(f"{exp_data[1].shape=}") print() print("shape=(n_sims,n_sensors,n_field_comps,n_time_steps)") print(f"{exp_stats[1].max.shape=}") print(80*"=") .. GENERATED FROM PYTHON SOURCE LINES 160-166 We also have specific plotting tools which allow us to visualise the uncertainty bounds for our sensor traces. The defaults plot options show the mean sensor trace and uncertainty bounds of 3 times the stanard deviation. In the next example we will see how to control these plots. For now we will plot the temperature traces for the first simulation and the strain traces for the third simulation in our list of SimData objects. .. GENERATED FROM PYTHON SOURCE LINES 166-178 .. code-block:: Python (fig,ax) = pyv.plot_exp_traces(exp_sim, component="temperature", sens_array_num=0, sim_num=0) (fig,ax) = pyv.plot_exp_traces(exp_sim, component="strain_yy", sens_array_num=1, sim_num=2) plt.show() .. _sphx_glr_download_examples_basics_ex4_1_expsim2d_thermmech2d.py: .. only:: html .. container:: sphx-glr-footer sphx-glr-footer-example .. container:: sphx-glr-download sphx-glr-download-jupyter :download:`Download Jupyter notebook: ex4_1_expsim2d_thermmech2d.ipynb ` .. container:: sphx-glr-download sphx-glr-download-python :download:`Download Python source code: ex4_1_expsim2d_thermmech2d.py ` .. container:: sphx-glr-download sphx-glr-download-zip :download:`Download zipped: ex4_1_expsim2d_thermmech2d.zip ` .. only:: html .. rst-class:: sphx-glr-signature `Gallery generated by Sphinx-Gallery `_