106 """Six observable series + dose axis, from the run's own solution."""
107 pkl = run_dir /
'plots' /
'plot_data.pkl'
109 sys.exit(f
'no plots/plot_data.pkl in {run_dir} -- re-run the notebook '
110 f
'for this case, or point at a run directory that has one')
113 sys.path[:0] = [str(MOD.parent), str(MOD)]
114 d = pickle.load(open(pkl,
'rb'))
115 R, E = d[
'results'], d[
'input_data'].energetics
116 Om = float(R[
'Omega'])
117 b111, b100 = float(E[
'b_111']) * 1e-9, float(E[
'b_100']) * 1e-9
118 n111 = np.maximum(np.asarray(R[
'mean_n_111'], float), 0.0)
119 n100 = np.maximum(np.asarray(R[
'mean_n_100'], float), 0.0)
120 nv = np.maximum(np.asarray(R[
'mean_n_v'], float), 0.0)
121 return np.asarray(R[
'dose'], float), {
122 'N_loops_111': np.asarray(R[
'N_loops_111'], float),
123 'N_loops_100': np.asarray(R[
'N_loops_100'], float),
124 'N_voids': np.asarray(R[
'N_voids'], float),
125 'd_111_nm': 2 * np.sqrt(n111 * Om / (np.pi * b111)) * 1e9,
126 'd_100_nm': 2 * np.sqrt(n100 * Om / (np.pi * b100)) * 1e9,
127 'd_cavity_nm': 2 * (3 * nv * Om / (4 * np.pi)) ** (1 / 3) * 1e9,
185def draw(D, M, SER, which, annotated):
186 ycol =
'N' if which ==
'N' else 'd'
187 ylabel = (
r'Number density (m$^{-3}$)' if ycol ==
'N'
188 else 'Mean diameter (nm)')
189 datacol =
'Density [m^-3]' if ycol ==
'N' else 'Diameter [nm]'
190 fig, ax = plt.subplots(figsize=(11, 8))
194 for df, c, mk, nk, dk, _
in SER:
195 key = nk
if ycol ==
'N' else dk
199 ax.plot(D, M[key],
'-', color=c, marker=mk, ms=7,
200 mec=
'white', mew=1.0, zorder=4)
202 ax.plot(D, M[key],
'-', color=c, zorder=4)
204 s_all = df.dropna(subset=[
'Dose [dpa]', datacol])
210 s_all = s_all[s_all[datacol] <= DMAX]
219 if not annotated
and len(s_all) > 1:
220 x0, x1 = s_all[
'Dose [dpa]'].min(), s_all[
'Dose [dpa]'].max()
221 y0, y1 = s_all[datacol].min(), s_all[datacol].max()
222 if x1 > x0
and y1 > y0:
223 ax.add_patch(Rectangle((x0, y0), x1 - x0, y1 - y0,
224 facecolor=to_rgba(c, 0.10),
225 edgecolor=to_rgba(c, 0.8), lw=2.0,
226 ls=(0, (6, 4)), zorder=1))
228 for source, sub
in s_all.groupby(
'Source'):
229 ax.scatter(sub[
'Dose [dpa]'], sub[datacol], s=MS, marker=mk,
230 facecolors=SOURCE_COLOR.get(source, INK2),
231 edgecolors=
'white', linewidths=1.6, zorder=5)
232 if source
not in seen:
234 shapes.setdefault(source, [])
235 if mk
not in shapes[source]:
236 shapes[source].append(mk)
239 ax.set_xlabel(
'Dose (dpa)')
240 ax.set_ylabel(ylabel)
241 ax.set_xlim(left=XMIN)
248 ax.set_ylim(bottom=NMIN)
251 ax.grid(
True, which=
'major', color=GRID, lw=0.8, zorder=0)
252 ax.grid(
True, which=
'minor', color=GRID, lw=0.4, alpha=0.55, zorder=0)
253 ax.set_axisbelow(
True)
255 for sp
in ax.spines.values():
257 ax.tick_params(which=
'both', top=
True, right=
True, direction=
'out')
265 mh = [plt.Line2D([], [], color=c, lw=LW, marker=mk, ms=13, mec=
'white')
266 for _, c, mk, _, _, _
in SER]
267 ax.legend(mh, [s[5]
for s
in SER], frameon=
not annotated,
268 loc=
'best', labelcolor=INK,
269 handletextpad=0.8, borderaxespad=0.8)
270 order = ([s
for s
in SOURCE_COLOR
if s
in seen]
271 + [s
for s
in seen
if s
not in SOURCE_COLOR])
276 sh = [tuple(plt.Line2D([], [], lw=0, marker=mk, ms=14, mec=
'white', mew=1.6,
277 mfc=SOURCE_COLOR.get(s, INK2))
278 for mk
in shapes[s])
for s
in order]
279 nmax = max(len(h)
for h
in sh)
281 ax.annotate(
'line + small markers = model (markers at computed doses);\n'
282 'large markers = experiment',
283 xy=(0.015, 0.985), xycoords=
'axes fraction', va=
'top',
284 fontsize=13, color=INK2)
288 fig.legend(sh, order, ncol=4, loc=
'upper center',
289 bbox_to_anchor=(0.5, 0.04), frameon=
False, labelcolor=INK,
290 handler_map={tuple: HandlerTuple(ndivide=
None, pad=0.35)},
291 handlelength=1.0 * nmax, handletextpad=0.6, columnspacing=1.6)