Mechanics of Defect Evolution Library
Loading...
Searching...
No Matches
plotLoops.py
Go to the documentation of this file.
1# /opt/local/bin/python3.14 plotLoops.py
2import sys
3import os
4import matplotlib.pyplot as plt
5import numpy as np
6sys.path.append("../../build/tools/pyMoDELib")
7import pyMoDELib
8sys.path.append("../../python/")
9from modlibUtils import *
10
11# 0. Collect preliminary information
12simulationDir=os.path.abspath(".")
13materialFile=getStringInFile('inputFiles/polycrystal.txt','materialFile')
14F,Flabels=readFfile(simulationDir+'/F')
15ddBase=pyMoDELib.DefectiveCrystalBase(simulationDir)
16b_SI=ddBase.poly.b_SI
17cs_SI=ddBase.poly.cs_SI
18configIO=pyMoDELib.DefectiveCrystalConfigIO(simulationDir+'/config')
19defectiveCrystal=pyMoDELib.DefectiveCrystal(ddBase)
20dislocationNetwork=defectiveCrystal.dislocationNetwork()
21runIDs=getFarray(F,Flabels,'runID')
22times=getFarray(F,Flabels,'time [b/cs]')*b_SI/cs_SI/3600 # time in hours
23
24# 1. Collect data from simulations
25loopRaii=[]
26loopTimes=[]
27loopPlanes=[] # basal or prismatic
28loopTypes=[] # vacancy or interstitial
29dislocationDensity=[]
30for k in range(0,len(runIDs)):
31 runID=int(runIDs[k])
32 time=times[k]
33 configIO.read(runID)
34 defectiveCrystal.initializeConfiguration(configIO)
35 networkLengthTuple=dislocationNetwork.networkLength()
36 dislocationDensity.append((networkLengthTuple[0]+networkLengthTuple[1]+networkLengthTuple[2]+networkLengthTuple[3])/ddBase.mesh.volume()/b_SI/b_SI)
37 for loopID in dislocationNetwork.loops():
38 loop=dislocationNetwork.loops().getRef(loopID)
39 planeID=loop.glidePlane.planeBaseID() # 0=basal, 1,2,3=prismatic
40 loopTypes.append(np.trace(loop.averagePlasticDistortion())<0.0)
41 r=np.sqrt(loop.slippedArea()/np.pi)*b_SI*1.0e9 # average radius of current loop
42 loopRaii.append(r)
43 loopTimes.append(time)
44 loopPlanes.append(planeID)
45# loopTypes.append(1)
46
47# Convert to numPy
48loopTimes = np.array(loopTimes)
49loopRaii = np.array(loopRaii)
50loopPlanes = np.array(loopPlanes)
51loopTypes = np.array(loopTypes)
52
53# 2. Create mappping for distinguishing loop types
54mapping ={
55 (0, 1): "basal vacancy",
56 (0, 0): "basal interstitial",
57 (1, 1): "prismatic vacancy", # (<a>1)
58 (1, 0): "prismatic interstial", # (<a>1)
59 (2, 1): "prismatic vacancy", # (<a>2)
60 (2, 0): "prismatic interstial", # (<a>2)
61 (3, 1): "prismatic vacancy", # (<a>3)
62 (3, 0): "prismatic interstial", # (<a>3)
63}
64
65# 3. Get UNIQUE strings and assign a unique color to each string
66unique_strings = sorted(list(set(mapping.values())))
67cmap = plt.colormaps['plasma']
68string_colors = {string: cmap(i / max(1, len(unique_strings) - 1))
69 for i, string in enumerate(unique_strings)}
70
71# 4. Plot by unique mapping values
72fig, axs = plt.subplots(1,1)
73# 4. Group data by the final String using an array mask
74for string_s in unique_strings:
75 # Build a mask that finds all (p, t) pairs mapping to this string S
76 string_mask = np.zeros(len(loopRaii), dtype=bool)
77
78 for (pk, tk), mapped_string in mapping.items():
79 if mapped_string == string_s:
80 # Accumulate all points matching this specific (p, t) pair
81 string_mask |= (loopPlanes == pk) & (loopTypes == tk)
82
83 # Plot all data points for this string category in one clean batch
84 axs.scatter(loopTimes[string_mask], loopRaii[string_mask],
85 color=string_colors[string_s],
86 label=string_s,
87 s=5, alpha=0.6)
88
89plt.legend(loc="upper right", markerscale=2)
90fig.savefig("loopRadii.pdf", bbox_inches='tight', format='pdf')
91
92#fig, axs = plt.subplots(1,1)
93#axs.plot(times,rho,0.1,color='k')
94#axs.set_xlabel('time [hours]')
95#axs.set_ylabel('dislocation density [1/m^2]')
96#fig.savefig("density.pdf", bbox_inches='tight', format='pdf')
97
98fig, axs = plt.subplots(1,1)
99axs.plot(times,dislocationDensity,0.1,color='k')
100axs.set_xlabel('time [hours]')
101axs.set_ylabel('dislocation density [1/m^2]')
102fig.savefig("density.pdf", bbox_inches='tight', format='pdf')
readFfile(folder)
getStringInFile(fileName, variable)
getFarray(F, Flabels, label)