Coverage for dragonfly_sim/utils/data_handler.py: 36%
66 statements
« prev ^ index » next coverage.py v7.16.2, created at 2026-10-17 03:37 +0000
« prev ^ index » next coverage.py v7.16.2, created at 2026-10-17 03:37 +0000
1import os
2import numpy as np
3from matplotlib import pyplot as plt
5def split_list_of_tuples_into_separate_lists(inp_list, iter_acceptance_list=None):
6 list_of_lists = []
7 for i in range(len(inp_list[0])):
8 single_list_i = [element[i] for element in inp_list]
10 if i == 0 and iter_acceptance_list is not None:
11 elements_to_include = np.isin(single_list_i, iter_acceptance_list)
13 if iter_acceptance_list is not None:
14 single_list_i = list(np.array(single_list_i)[elements_to_include])
16 list_of_lists += [single_list_i]
17 return list_of_lists
20class DataStore():
21 def __init__(self):
22 # Initialize arrays that store outputs
24 # Relative residual norms eta = ||r||/||u||. These, not absolute norms,
25 # are what to plot or threshold on: eta is free of the sqrt(n_dofs) and
26 # state-magnitude factors that make absolute norms incomparable
27 # between meshes.
28 self.fom_relative_residuals = []
30 # objective function histories
31 self.FOM_force_coefficients = []
32 # Dimensional (unnormalized) FOM lift/drag/moment forces, same
33 # (eval_idx, D, L, M_1, ...) tuple layout and eval_idx indexing as
34 # FOM_force_coefficients' (eval_idx, c_d, c_l, c_m_1, ...), with one
35 # moment entry per moment of the postprocessor, in its order.
36 self.FOM_forces = []
38 # Parameter vector histories
39 self.parameter_vectors_per_iteration = []
41 # Wall times of the full-order model
42 self.FOM_walltime = []
44 # POD reduced-order model (core/reduced_order_model.py), per ROM solve:
45 # wall time, eta, (eval_idx, c_d, c_l, c_m_1, ...) like
46 # FOM_force_coefficients, whether eta met the acceptance threshold,
47 # and (eval_idx, dc_d, dc_l, dc_m_1, ...) ROM - FOM when the FOM also ran;
48 # the snapshot singular values after every snapshot added
49 self.ROM_walltime = []
50 self.rom_relative_residuals = []
51 self.ROM_force_coefficients = []
52 self.ROM_meets_threshold = []
53 self.rom_coefficient_errors = []
54 self.global_snapshot_sing_vals_per_iteration = []
56 # Per adjoint solve (one per output row of a derivative evaluation):
57 # (eval_idx, 'rom' or 'fom', wall time). 'rom' is the reduced adjoint
58 # of an accepted ROM solution, 'fom' the full-order adjoint.
59 self.adjoint_solves = []
61 # Number of DoFs in simulation
62 self.fe_dofs = 0
63 # Number of design parameters in optimization
64 self.num_var = 0
66 def compile_store_in_dict(self):
67 data_dict = {}
68 for data in vars(self):
69 # print(data)
70 # print(self.__dict__[str(data)])
71 data_dict[str(data)] = self.__dict__[str(data)]
72 return data_dict
74 def write_store_to_numpy_file(self, save_folder="Result_dicts", save_filename="POD_deployment.npy"):
75 save_location = save_folder + "/" + save_filename
76 os.makedirs(save_folder, exist_ok=True)
77 # create dictionary with all data
78 data_dict = self.compile_store_in_dict()
79 # save data_dict to location
80 np.save(save_location, data_dict)
81 print("Saved data dictionary to {}".format(save_location))
83 def open_dict_and_import_data(self, file_folder="Result_dicts", filename="POD_deployment.npy"):
84 file_location = file_folder + "/" + filename
85 data_dict = np.load(file_location, allow_pickle=True)
86 data_dict = data_dict.item()
87 for key, value in data_dict.items():
88 setattr(self, key, value)
90 # TODO: Add routine to unpack input list(s) for plotting, move actual plotting routines to separate utility file
93def plot_walltime_boxplots(data_stores, data_legend, yrange=(0, 3), show_yaxis_label=True):
94 # One boxplot of the full-order-model wall times per data store, with a
95 # horizontal line at the mean wall time pooled over all data stores
96 fom_walltime_list = []
97 for data_store in data_stores:
98 _, FOM_walltime = zip(*data_store.FOM_walltime)
99 fom_walltime_list += [np.array(FOM_walltime)]
101 fig = plt.figure(figsize=(2.2,3.))
102 ax = fig.add_subplot(111)
104 fom_walltime_mean = np.mean(np.concatenate(fom_walltime_list))
105 ax.plot([0.5, len(data_stores)+0.5], [fom_walltime_mean, fom_walltime_mean], 'k', linewidth=3)
107 ax.boxplot(fom_walltime_list, widths=0.8)
109 # adding horizontal grid lines
110 ax.yaxis.grid(True)
111 # ax.set_yscale("log")
112 ax.set_xticks([y + 1 for y in range(len(fom_walltime_list))],
113 labels=data_legend)
114 # ax.set_xlabel(r'Solver')
115 if show_yaxis_label:
116 ax.set_ylabel(r'Total wall time [s]')
117 # else:
118 # # frame = plt.gca()
119 # ax.axes.yaxis.set_ticklabels([])
121 ax.tick_params(axis='x', labelrotation=45)
123 for tick in ax.xaxis.get_major_ticks():
124 tick.label1.set_horizontalalignment('center')
126 ax.set_ylim(yrange[0], yrange[1])
128 plt.subplots_adjust(left=0.23, right=0.955, bottom=0.19, top=0.95)
129 # plt.rcParams.update({'font.size': 22})
130 plt.show()
133# def plot_force_coefficients(data_stores)