.. DO NOT EDIT. .. THIS FILE WAS AUTOMATICALLY GENERATED BY SPHINX-GALLERY. .. TO MAKE CHANGES, EDIT THE SOURCE PYTHON FILE: .. "examples/basics/ex3_2_tensorsens2d_strain2d.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_ex3_2_tensorsens2d_strain2d.py: Basics: Custom tensor field sensors (strain gauges) in 2D ================================================================================ In this example we build a custom tensor field sensor array (i.e. a strain gauge array) in 2D. Note that this tutorial assumes you are familiar with the use of `pyvale` for scalar fields as described in the first set of examples. Test case: point strain sensors on a 2D plate with hole loaded in tension .. GENERATED FROM PYTHON SOURCE LINES 19-25 .. 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 26-30 First we load the same 2D solid mechanics simulation of a plate with a hole loaded in tension as a `SimData` object. We scale the units to mm from SI including the coordinates and displacement. Strain is unitless so we leave it alone. .. GENERATED FROM PYTHON SOURCE LINES 30-36 .. code-block:: Python data_path = pyv.DataSet.mechanical_2d_path() sim_data = mh.ExodusReader(data_path).read_all_sim_data() sim_data = pyv.scale_length_units(scale=1000.0, sim_data=sim_data, disp_comps=("disp_x","disp_y")) .. GENERATED FROM PYTHON SOURCE LINES 37-41 Here is the main difference when creating a tensor field sensor array. We create a tensor field where we need to specify the normal and deviatoric component string keys as they appear in our `SimData` object. We have a 2d simulation here so we have 2 normal components and 1 deviatoric (shear). .. GENERATED FROM PYTHON SOURCE LINES 41-50 .. code-block:: Python field_name = "strain" norm_comps = ("strain_xx","strain_yy") dev_comps = ("strain_xy",) strain_field = pyv.FieldTensor(sim_data, field_name=field_name, norm_comps=norm_comps, dev_comps=dev_comps, elem_dims=2) .. GENERATED FROM PYTHON SOURCE LINES 51-54 The setup of our sensor data object is exactly the same as for any other point sensor array. We could optionally specify the sample time to be None in which case the sensor will sample at the simulation time steps. .. GENERATED FROM PYTHON SOURCE LINES 54-65 .. code-block:: Python n_sens = (2,3,1) x_lims = (0.0,100.0) y_lims = (0.0,150.0) z_lims = (0.0,0.0) sens_pos = pyv.create_sensor_pos_array(n_sens,x_lims,y_lims,z_lims) sample_times = np.linspace(0.0,np.max(sim_data.time),50) sens_data = pyv.SensorData(positions=sens_pos, sample_times=sample_times) .. GENERATED FROM PYTHON SOURCE LINES 66-70 Here we create a descriptor that will be used to label visualisations of the sensor locations and time traces for our sensors. For the strain gauges we are modelling here we could also use the descriptor factory to get these defaults. .. GENERATED FROM PYTHON SOURCE LINES 70-76 .. code-block:: Python descriptor = pyv.SensorDescriptor(name="Strain", symbol=r"\varepsilon", units=r"-", tag="SG", components=("xx","yy","xy")) .. GENERATED FROM PYTHON SOURCE LINES 77-78 We build our point sensor array as normal. .. GENERATED FROM PYTHON SOURCE LINES 78-82 .. code-block:: Python straingauge_array = pyv.SensorArrayPoint(sens_data, strain_field, descriptor) .. GENERATED FROM PYTHON SOURCE LINES 83-85 We can add any errors we like to our error chain. Here we add some basic percentage errors. .. GENERATED FROM PYTHON SOURCE LINES 85-93 .. code-block:: Python error_chain = [] error_chain.append(pyv.ErrSysUnifPercent(low_percent=-2.0,high_percent=2.0)) error_chain.append(pyv.ErrRandNormPercent(std_percent=2.0)) error_int = pyv.ErrIntegrator(error_chain, sens_data, straingauge_array.get_measurement_shape()) straingauge_array.set_error_integrator(error_int) .. GENERATED FROM PYTHON SOURCE LINES 94-99 We run our virtual sensor simulation as normal. The only thing to note is that the second dimension of our measurement array will contain our tensor components in the order they are specified in the tuples with the normal components first followed by the deviatoric. In our case this will be (strain_xx,strain_yy,strain_xy). .. GENERATED FROM PYTHON SOURCE LINES 99-101 .. code-block:: Python measurements = straingauge_array.calc_measurements() .. GENERATED FROM PYTHON SOURCE LINES 102-104 We can plot a given component of our tensor field and display our sensor locations with respect to the field. .. GENERATED FROM PYTHON SOURCE LINES 104-108 .. code-block:: Python plot_field = "strain_yy" pv_plot = pyv.plot_point_sensors_on_sim(straingauge_array,plot_field) pv_plot.show(cpos="xy") .. GENERATED FROM PYTHON SOURCE LINES 109-110 We can also plot time traces for all components of the tensor field. .. GENERATED FROM PYTHON SOURCE LINES 110-114 .. code-block:: Python for cc in (norm_comps+dev_comps): pyv.plot_time_traces(straingauge_array,cc) plt.show() .. _sphx_glr_download_examples_basics_ex3_2_tensorsens2d_strain2d.py: .. only:: html .. container:: sphx-glr-footer sphx-glr-footer-example .. container:: sphx-glr-download sphx-glr-download-jupyter :download:`Download Jupyter notebook: ex3_2_tensorsens2d_strain2d.ipynb ` .. container:: sphx-glr-download sphx-glr-download-python :download:`Download Python source code: ex3_2_tensorsens2d_strain2d.py ` .. container:: sphx-glr-download sphx-glr-download-zip :download:`Download zipped: ex3_2_tensorsens2d_strain2d.zip ` .. only:: html .. rst-class:: sphx-glr-signature `Gallery generated by Sphinx-Gallery `_