Figure 10#
Imports#
import matplotlib
import matplotlib.pyplot as plt
import numpy
import dolfin_estim as destim
import dolfin_mech as dmech
### disable deprecation warning to avoid heavy output
import warnings
from ffc.quadrature.deprecation import QuadratureRepresentationDeprecationWarning
warnings.simplefilter("ignore", QuadratureRepresentationDeprecationWarning)
Parameters#
Geometry and varying parameters#
mesh_size = 0.1 ### mesh size for the resolution
l = 0.6 ### characteristic length of the cube
delta_lst = [1000, 10, 5, 2.5, 1.7, 1.1, 0.9, 0.099] ### list of wave lengths chosen
noise_lst = [0.0, 0.01, 0.05, 0.1] ### noise levels chosen
Material behavior#
params = {
"E":1., # kPa
"nu":0.3} # [-]
mat_params = {"model":"CGNH", "parameters":params} ### hyperelastic law
Loading#
load_params_boundary = {"type":"pres", "f":0.3} ### studied in the case of a boundary force, f = 3 kPa
Generating plots#
Helpers#
cube_params = {"X0":0.2, "Y0":0.2, "X1":0.8, "Y1":0.8, "l":0.01} # exact solution --without noise-- computed on a very fine mesh for better resolution, computed here and not in dolfin_estim in order to avoid heavy computations
u, v = dmech.run_RivlinCube_Hyperelasticity(
dim = 2,
cube_params = cube_params,
mat_params = mat_params,
step_params = {"dt_ini":1/20},
const_params = {"type":"blox"},
load_params = load_params_boundary,
get_results = 1,
res_basename = "./")
SNR_lst = [] ### defining SNRs -- Signal-to-Noise ratios--
for noise in noise_lst:
if noise == 0.:
SNR_lst.append(40.) ### setting the SNR arbitrarily when should be +∞
else:
SNR_lst.append(1/noise)
def writing_results_to_pdf(results_all = [], delta_lst = [], SNR_lst = []): ### function to write results --boxplots--
fig, ax = plt.subplots()
### plotting parameters
plt.rc("xtick", labelsize = 20)
plt.rc("ytick", labelsize = 20)
plt.rc("legend", fontsize = 12)
plt.xlabel("Signal to Noise Ratio (SNR)", fontsize = 12)
plt.ylabel("Estimation error (%)", fontsize = 12)
fig.set_size_inches(10, 6)
plt.grid()
plt.xlim([5, 2000.])
plt.ylim([-100, 100.])
nb_deltas = len(delta_lst)
spacing = numpy.linspace(-0.0305*(nb_deltas//2), 0.0305*(nb_deltas//2), nb_deltas) ### spacing between the different boxplots
color_lst = matplotlib.cm.viridis(numpy.linspace(0, 1, len(delta_lst))) #### colors in the viridis scale
count_spacing = 0
for delta in delta_lst:
results_delta = results_all[str(delta_lst[count_spacing])] ### getting results for each value of delta, stored into the dictionary "results_delta"
down_up_lst = [[abs(results_delta["E_-"][i]-results_delta["E_average"][i])for i in range(len(results_delta["noise"]))], [abs(results_delta["E_+"][i]-results_delta["E_average"][i]) for i in range(len(results_delta["noise"]))]] #### to create y-error bars, defining up and down whisker
mean_lst = [results_delta["E_average"][i] for i in range(len(results_delta["noise"]))]
SNR_lst_scaled = [SNR_lst[i]*numpy.exp((spacing[count_spacing]))**numpy.log(10) for i in range(len(SNR_lst))] ### to include spacing, that will remain even with the log scale
plt.errorbar(SNR_lst_scaled, mean_lst, yerr = down_up_lst, capsize = 4, fmt = "s", ecolor = color_lst[-1], markeredgecolor = color_lst[-1], markerfacecolor = color_lst[-1], label = r'$\Delta$'+" = " +'{0:.1f}'.format(delta)+"l")
plt.gca().set_xscale('log') ### plotting y-error bars
color_lst = color_lst[:-1] ### different color for each error bar
count_spacing+= 1
ax.set_xticks([])
ax.set_xticks([], minor = True)
plt.xticks(SNR_lst, ['$\infty$', 100, 20, 10])
plt.legend(loc = "upper right", fontsize = 13, ncol = 2)
plt.savefig("./different_values_beta_VFM_plane_waves.pdf", bbox_inches = 'tight')
plt.show()
Plots#
results_all = {}
for delta in delta_lst: ### for each value of the period
### creating arrays and lists to store results
results_std = {}
results = {}
noise_results = []
E_all = []
results_std["noise"] = noise_lst
E_average, E_plus, E_minus = [], [], []
for noise in noise_lst:
E_results = []
for i in range(1, 50): #### many iterations for convergence of the distribution
noise_results.append(noise)
E = destim.identifying_parameter(method = "VFM", delta = delta*l, load_type = "boundary_force", load_params = load_params_boundary, mesh_size = mesh_size, cube_params = cube_params, refine = False, noise_from_images = False, noise = noise, u_params = {"u":u, "v":v}) # this computation was only conducted for a boundary force test, without refining the mesh, and with synthetic data generated by adding noise to displacements
E_error = (E-1)*100 ### computing the error compared to the ground truth, i.e., E = 1 kPa
E_all.append(E_error)
E_results.append(E_error)
E_average.append(numpy.average(E_results))
E_plus.append(numpy.average(E_results)+numpy.std(E_results))
E_minus.append(numpy.average(E_results)-numpy.std(E_results))
results_std["E_+"] = E_plus
results_std["E_-"] = E_minus
results_std["E_average"] = E_average
results_all[str(delta)] = results_std
results["noise"] = noise_results
results["E"] = E_all
writing_results_to_pdf(results_all = results_all, delta_lst = delta_lst, SNR_lst = SNR_lst)