Tabletop tests (Kent 2004)#
Model validation information
Performed by : Johan Iraeus
Reviewed by : Felix Ressi
Added to VIVA+ Validation Catalog on : November 30th, 2022
Last modified : November 23rd, 2023
Model version (this notebook run for): 0.3.2
© 2019-2024, OpenVT Organization (OVTO)
Available openly under under Creative Commons Attribution 4.0 International License
Experiment by Kent et al. (2004)#
Summary:#
The simulated outputs are compared to the references from PMHS tests reported by Kent et al. 2004 1
1 Kent, R., Lessley, D., and Sherwood, C. (2004), “Thoracic Response to Dynamic, Non-impact Loading from a Hub, Distributed Belt, Diagonal Belt, and Double Diagonal Belts”, in Stapp Car Crash Journal, ed. The Stapp Association (Warrendale, PA, United States: SAE International).
(figure shows diagonal belt loading condition with the VIVA+ 50F model)
Experiment#
Information on the subjects/specimens#
8 female specimen (average age: 69.8 yrs, average mass: 57.9 kg, average height: 163.8 kg)
7 male specimen (average age: 69.3 yrs, average mass: 80.3 kg, average height: 176.4 cm)
Loading and Boundary Conditions#
Tabletop tests with a hub, a diagonal belt and two diagonal belts (“X-belt”) were performed. First, sub-injurious tests were performed before a final injurious test for each specimen.
Positioning#
The VIVA+ model is used in the default seated position, with the arms positioned towards the side during gravity settling (during the first 350ms).
Responses recorded#
The reference values from the paper were digitalised and are incuded in the package. The are color coded in the plots to visualise female/male specimen.
Show code cell content
# Libraries for plotting
import matplotlib.pyplot as plt
import seaborn as sns
sns.set()
sns.set_style("whitegrid")
#sns.set_context("paper",
# font_scale=1.4
# )
#sns.color_palette("Blues", as_cmap=True)
#sns.color_palette("dark:salmon_r", as_cmap=True);
#sns.set_palette("Spectral")
#sns.color_palette("coolwarm", as_cmap=True)
plot50F = {"linestyle" :'-', "color" : 'r', 'linewidth' : 3}
plotExperimentFemale = {"linestyle" :'--', "color" : 'r', "alpha" : 0.7 }
plot50M = { "linestyle" :'-', "color" : 'b', 'linewidth' : 3}
plotExperimentMale = {"linestyle" :'--', "color" : 'b',"alpha" : 0.7,}
plotExperimentMale2 = {"linestyle" :':', "color" : 'b',"alpha" : 0.7,}
plotExperiment = {"linestyle" :'--', "color" : 'grey', "alpha" : 0.7 }
plt.rcParams['figure.dpi'] = 140
Show code cell content
# Import dynasaur library
from dynasaur.plugins.data_visualization_controller import DataVisualizationController
from dynasaur.plugins.criteria_controller import CriteriaController
Results#
Energies#
The energy balance is show in the figure below. The negative internal energy is from the pretension of the seat belt and the reposition springs (contributing to the model with “negative” energy)
Show code cell source
fig_energy, axs = plt.subplots(nrows=1, ncols=1, figsize=(4,2))
fig_energy.suptitle('Model Energies')
#plt.set_title('Simulation #1')
#plt.set_ylabel('Energies (J)')
plt.plot(simData_50F_Hub.MODEL.Hourglass_Energy_time.time, simData_50F_Hub.MODEL.Hourglass_Energy_time.hourglass_energy, label = "Hourglass Energy")
plt.plot(simData_50F_Hub.MODEL.Internal_Energy_time.time, simData_50F_Hub.MODEL.Internal_Energy_time.internal_energy, label = "Internal Energy")
plt.plot(simData_50F_Hub.MODEL.Kinetic_Energy_time.time, simData_50F_Hub.MODEL.Kinetic_Energy_time.kinetic_energy, label = "Kinetic Energy")
plt.plot(simData_50F_Hub.MODEL.Total_Energy_time.time, simData_50F_Hub.MODEL.Total_Energy_time.total_energy, label = "Total Energy")
plt.xlabel("Time [ms]")
plt.ylabel("Energy [kJ]")
plt.legend(loc='upper center', bbox_to_anchor=(0.5, -0.3),
fancybox=True, shadow=True, ncol=4)
filename_save = os.path.join(figures_dir, 'Kent_2004_energies.svg')
fig_energy.savefig(filename_save, format='svg', bbox_inches='tight')
filename_save = os.path.join(figures_dir, 'Kent_2004_energies.png')
fig_energy.savefig(filename_save, format='png', bbox_inches='tight')
Force-Deflection Plots#
The figures below compare the simulation predictions with the PMHS tests for the non-injurious load cases, for both the 50F and 50M models.
Show code cell content
# apply offset (remove part with gravity settling and positioning)
simData_50F_Hub_offset = simData_50F_Hub.iloc[350:,:]
simData_50F_Hub_offset_defl = simData_50F_Hub_offset['IMPACTOR']['Chest_deflection_vs_time']['displacement'] - simData_50F_Hub_offset['IMPACTOR']['Chest_deflection_vs_time']['displacement'].iloc[0]
simData_50F_Hub_offset_force = simData_50F_Hub_offset['IMPACTOR']['Contactforce_z_table_to_HBM_torso_CFC_180']['force'] - simData_50F_Hub_offset['IMPACTOR']['Contactforce_z_table_to_HBM_torso_CFC_180']['force'].iloc[0]
simData_50M_Hub_offset = simData_50M_Hub.iloc[350:,:]
simData_50M_Hub_offset_defl = simData_50M_Hub_offset['IMPACTOR']['Chest_deflection_vs_time']['displacement'] - simData_50M_Hub_offset['IMPACTOR']['Chest_deflection_vs_time']['displacement'].iloc[0]
simData_50M_Hub_offset_force = simData_50M_Hub_offset['IMPACTOR']['Contactforce_z_table_to_HBM_torso_CFC_180']['force'] - simData_50M_Hub_offset['IMPACTOR']['Contactforce_z_table_to_HBM_torso_CFC_180']['force'].iloc[0]
simData_50F_Belt_offset = simData_50F_Belt.iloc[350:,:]
simData_50F_Belt_offset_defl = simData_50F_Belt_offset['IMPACTOR']['Chest_deflection_vs_time']['displacement'] - simData_50F_Belt_offset['IMPACTOR']['Chest_deflection_vs_time']['displacement'].iloc[0]
simData_50F_Belt_offset_force = simData_50F_Belt_offset['IMPACTOR']['Contactforce_z_table_to_HBM_torso_CFC_180']['force'] - simData_50F_Belt_offset['IMPACTOR']['Contactforce_z_table_to_HBM_torso_CFC_180']['force'].iloc[0]
simData_50M_Belt_offset = simData_50M_Belt.iloc[350:,:]
simData_50M_Belt_offset_defl = simData_50M_Belt_offset['IMPACTOR']['Chest_deflection_vs_time']['displacement'] - simData_50M_Belt_offset['IMPACTOR']['Chest_deflection_vs_time']['displacement'].iloc[0]
simData_50M_Belt_offset_force = simData_50M_Belt_offset['IMPACTOR']['Contactforce_z_table_to_HBM_torso_CFC_180']['force'] - simData_50M_Belt_offset['IMPACTOR']['Contactforce_z_table_to_HBM_torso_CFC_180']['force'].iloc[0]
simData_50F_Xbelt_offset = simData_50F_Xbelt.iloc[350:,:]
simData_50F_Xbelt_offset_defl = simData_50F_Xbelt_offset['IMPACTOR']['Chest_deflection_vs_time']['displacement'] - simData_50F_Xbelt_offset['IMPACTOR']['Chest_deflection_vs_time']['displacement'].iloc[0]
simData_50F_Xbelt_offset_force = simData_50F_Xbelt_offset['IMPACTOR']['Contactforce_z_table_to_HBM_torso_CFC_180']['force'] - simData_50F_Xbelt_offset['IMPACTOR']['Contactforce_z_table_to_HBM_torso_CFC_180']['force'].iloc[0]
simData_50M_Xbelt_offset = simData_50M_Xbelt.iloc[350:,:]
simData_50M_Xbelt_offset_defl = simData_50M_Xbelt_offset['IMPACTOR']['Chest_deflection_vs_time']['displacement'] - simData_50M_Xbelt_offset['IMPACTOR']['Chest_deflection_vs_time']['displacement'].iloc[0]
simData_50M_Xbelt_offset_force = simData_50M_Xbelt_offset['IMPACTOR']['Contactforce_z_table_to_HBM_torso_CFC_180']['force'] - simData_50M_Xbelt_offset['IMPACTOR']['Contactforce_z_table_to_HBM_torso_CFC_180']['force'].iloc[0]
Show code cell source
fig_ft_Kent, (ax1, ax2, ax3) = plt.subplots(nrows=3, ncols=1, figsize=(7,8))
#plt.rcParams["figure.figsize"] = (20,10)
fig_ft_Kent.suptitle('Kent et al. 2004: Tabletop Tests')
ax1.plot(Hub_Exp.iloc[:,0:15:2], Hub_Exp.iloc[:,1:16:2]/1000, **plotExperimentFemale)
ax1.plot(Hub_Exp.iloc[:,16::2], Hub_Exp.iloc[:,17::2]/1000, **plotExperimentMale)
ax1.plot(simData_50F_Hub_offset_defl, -simData_50F_Hub_offset_force, label = "VIVA+ 50F", **plot50F)
ax1.plot(simData_50M_Hub_offset_defl, -simData_50M_Hub_offset_force, label = "VIVA+ 50M", **plot50M)
ax1.set(title="Hub Loading (unscaled posterior force)", xlabel ="Chest Compression [mm]", ylabel="Posterior Force [kN]")
ax1.set_xlim(0,60)
ax1.set_ylim(-0.5,3)
ax2.plot(simData_50F_Belt_offset_defl, -simData_50F_Belt_offset_force, **plot50F)
ax2.plot(simData_50M_Belt_offset_defl, -simData_50M_Belt_offset_force, **plot50M)
ax2.plot(Belt_Exp.iloc[:,0:15:2], Belt_Exp.iloc[:,1:16:2]/1000, **plotExperimentFemale)
ax2.plot(Belt_Exp.iloc[:,16::2], Belt_Exp.iloc[:,17::2]/1000, **plotExperimentMale)
ax2.set(title="Diagonal Belt Loading (unscaled posterior force)", xlabel ="Chest Compression [mm]", ylabel="Posterior Force [kN]")
ax2.set_xlim(0,60)
ax2.set_ylim(-0.5,3)
ax3.plot(simData_50F_Xbelt_offset_defl, -simData_50F_Xbelt_offset_force, **plot50F)
ax3.plot(simData_50M_Xbelt_offset_defl, -simData_50M_Xbelt_offset_force, **plot50M)
ax3.plot(Xbelt_Exp.iloc[:,0:15:2], Xbelt_Exp.iloc[:,1:16:2]/1000, **plotExperimentFemale)
ax3.plot(Xbelt_Exp.iloc[:,16::2], Xbelt_Exp.iloc[:,17::2]/1000, **plotExperimentMale)
ax3.set(title="X-Belt Loading (unscaled posterior force)", xlabel ="Chest Compression [mm]", ylabel="Posterior Force [kN]")
ax3.set_xlim(0,60)
ax3.set_ylim(-0.5,3)
fig_ft_Kent.legend(loc='center left', bbox_to_anchor=(1, 0.5))
fig_ft_Kent.tight_layout(pad=0.5)
plt.show()
filename_save = os.path.join(figures_dir, 'Kent_2004_force_deflection.svg')
fig_ft_Kent.savefig(filename_save, format='svg', bbox_inches='tight')
filename_save = os.path.join(figures_dir, 'Kent_2004_force_deflection.png')
fig_ft_Kent.savefig(filename_save, format='png', bbox_inches='tight')