Mechanics of Defect Evolution Library
Loading...
Searching...
No Matches
mdStackingFaultNoiseSample/main.py
Go to the documentation of this file.
1import os
2import sys
3#import vtk
4import glob
5import string
6import numpy as np
7import matplotlib.pyplot as plt
8
9#plt.rcParams["text.usetex"] = True
10import matplotlib as mpl
11import matplotlib.transforms as mtransforms
12
13sys.path.append("../../build/tools/pyMoDELib/")
14import pyMoDELib
15from scipy.signal import correlate2d
16from scipy.stats import norm
17from matplotlib import cm
18from matplotlib.colors import Normalize
19
20sys.path.append("../../python")
21from modlibUtils import *
22from pathlib import Path
23
24# Define all file templates (using pathlib for cross-platform paths)
25file_templates = {
26 "dd_file": Path("../../Library/DislocationDynamics/DD.txt"),
27 "noise_file": Path("../../Library/GlidePlaneNoise/MDStackingFault.txt"),
28 "material_file": Path("../../Library/Materials/AlMg5.txt"),
29 "elastic_deformation_file": Path(
30 "../../Library/ElasticDeformation/ElasticDeformation.txt"
31 ),
32 "mesh": Path("../../Library/Meshes/unitCube24.msh"),
33 "microstructure": Path(
34 "../../Library/Microstructures/periodicDipoleIndividual.txt"
35 ),
36}
37
38MDStackingFault_parameters = {
39 "variables": {
40 # Scalar parameters (use setInputVariable)
41 "type": "MDStackingFaultNoise",
42 "tag": 1,
43 "seed": 2,
44 "outputNoise": 1,
45 "noiseFile": "AlMg5_ISF.vtk",
46 # File paths (convert to absolute paths)
47 "correlationFile": Path(
48 "../../Library/GlidePlaneNoise/AlMg5_Cx_R100_ISF.vtk"
49 ).resolve(),
50 },
51 "vectors": {
52 # Vector parameters with comments (use setInputVector)
53 "gridSize": {
54 "value": np.array([60, 60, 1]),
55 "comment": "number of grid points in each direction",
56 },
57 "gridSpacing_SI": {
58 "value": np.array([1.0e-10, 1.0e-10, 1e-10]),
59 "comment": "grid spacing in each direction",
60 },
61 },
62 "copy_to": "inputFiles/MDStackingFault.txt",
63}
64
65Material_parameters = {
66 "variables": {
67 "enabledSlipSystems": "Shockley",
68 #'glidePlaneNoise': ['MDSolidSolution.txt', 'MDStackingFault.txt'],
69 "glidePlaneNoise": "MDStackingFault.txt",
70 "atomsPerUnitCell": "1",
71 "dislocationMobilityType": "default",
72 },
73 "copy_to": "inputFiles/AlMg5.txt",
74}
75
76Polycrystal_parameters = {
77 "parameters": {
78 "absoluteTemperature": 1,
79 "grain1globalX1": np.array([0, 1, 1]),
80 "grain1globalX3": np.array([-1, 1, -1]),
81 "boxEdges": np.array([[0, 1, 1], [-2, -1, 1], [-1, 1, -1]]),
82 "boxScaling": np.array([200, 200, 200]),
83 #'X0': np.array([0.5, 0.5, 0.5]),
84 "X0": np.array([0.0, 0.0, 0.0]),
85 "periodicFaceIDs": np.array([0, 1, 2, 3, 4, 5]),
86 "gridSpacing_SI": np.array([1.0e-10, 1.0e-10]),
87 }
88}
89
90
91def processInitialConfigurations() -> None:
92 # Copy all template files
93 print("\033[1;32mCopying template files...\033[0m")
94 for key, src_path in file_templates.items():
95 dest = f"inputFiles/{src_path.name}"
96 shutil.copy2(src_path.resolve(), dest)
97 # shutil.copy2(src_path, dest)
98 print(f"Created {dest}")
99
100 # print("\033[1;32mCreating ddFile\033[0m")
101
104
105 print("\033[1;32mCreating noiseFile\033[0m")
106 # copy noise file into inputFiles
107 shutil.copy2(
108 MDStackingFault_parameters["variables"]["correlationFile"], "inputFiles/"
109 )
110 # copy declared variables to the configuration txt file
111 for param, value in MDStackingFault_parameters["variables"].items():
112 if "correlationFile" in param:
113 relativePath = f"{str(value).split('/')[-1]}"
114 setInputVariable(MDStackingFault_parameters["copy_to"], param, relativePath)
115 else:
116 setInputVariable(MDStackingFault_parameters["copy_to"], param, str(value))
117 for param, data in MDStackingFault_parameters["vectors"].items():
118 setInputVector(
119 MDStackingFault_parameters["copy_to"], param, data["value"], data["comment"]
120 )
121
122 # Process material file
123 print("\033[1;32mCreating materialFile...\033[0m")
124 # print(Material_parameters['variables'].items())
125 matParams = Material_parameters["variables"]
126 setInputVariable(
127 Material_parameters["copy_to"],
128 "enabledSlipSystems",
129 matParams["enabledSlipSystems"],
130 )
131
132 # for gPlaneNoise in matParams['glidePlaneNoise']:
133 # setInputVariable(Material_parameters['copy_to'],'glidePlaneNoise',gPlaneNoise)
134 setInputVariable(
135 Material_parameters["copy_to"], "glidePlaneNoise", matParams["glidePlaneNoise"]
136 )
137
138 setInputVariable(
139 Material_parameters["copy_to"],
140 "atomsPerUnitCell",
141 matParams["atomsPerUnitCell"],
142 )
143 setInputVariable(
144 Material_parameters["copy_to"],
145 "dislocationMobilityType",
146 matParams["dislocationMobilityType"],
147 )
148
149 # Process polycrystal
150 # pf = PolyCrystalFile('FeCrAl_Fe.txt')
151 pf = PolyCrystalFile(Material_parameters["copy_to"].split("/")[-1])
152 # pf.meshFile='unitCube24.msh'
153 pf.meshFile = f'{str(file_templates["mesh"]).split("/")[-1]}'
154 for param, value in Polycrystal_parameters["parameters"].items():
155 setattr(pf, param, value)
156 pf.write("inputFiles")
157
158
159def constructDotGrid(NX, NY, unitVec1, unitVec2):
160 # Construct non-orthogonal dot grid based on the non-minimized atom structure
161 firstNearNeighborDist = 2.8
162 dotGrid = np.zeros((NX * NY, 2)) # each row contains x and y position of the dot
163 vec1 = unitVec1 * firstNearNeighborDist
164 vec2 = unitVec2 * firstNearNeighborDist
165 for yIdx in range(NY):
166 for xIdx in range(NX):
167 dotGrid[yIdx * NX + xIdx] = vec1 * xIdx + vec2 * yIdx
168 return dotGrid
169
170
171def initUnitVectors(originalCorrVTK: str):
172 latVector1 = None
173 latVector2 = None
174 copyFlag1 = False
175 copyFlag2 = False
176 with open(originalCorrVTK) as o:
177 for line in o:
178 if copyFlag1:
179 latVector1 = np.array(line.strip().split(), dtype=float)
180 copyFlag1 = False
181 elif copyFlag2:
182 latVector2 = np.array(line.strip().split(), dtype=float)
183 copyFlag2 = False
184 elif "VECTORS lattice_basis1 double" in line:
185 copyFlag1 = True
186 elif "VECTORS lattice_basis2 double" in line:
187 copyFlag2 = True
188
189 unitVec1 = latVector1 / np.linalg.norm(latVector1)
190 unitVec2 = latVector2 / np.linalg.norm(latVector2)
191 unitVec1 = unitVec1[:2] # drop the z axis value
192 unitVec2 = unitVec2[:2]
193 return unitVec1, unitVec2
194
195
196def circularShift(corrArray: np.ndarray, gridSize: np.ndarray) -> np.ndarray:
197 NX, NY = np.squeeze(gridSize[0]), np.squeeze(gridSize[1])
198 shiftY = NY / 2
199 shiftX = NX / 2
200 tempArr = np.zeros(NX * NY)
201 for y in np.arange(NY):
202 newY = int((y + shiftY) % NY)
203 for x in np.arange(NX):
204 newX = int((x + shiftX) % NX)
205 tempArr[newY * NX + newX] += corrArray[y * NX + x]
206 return tempArr
207
208
209def main() -> int:
210 # Preparing input files
211 folders = ["inputFiles"]
212 for x in folders:
213 # remove existing data
214 if os.path.exists(x):
215 shutil.rmtree(x)
216 # create necessary folder structure for the simulation
217 os.makedirs(x)
218
219 # set simulation parameters in inputFiles
220 processInitialConfigurations()
221
222 # setInputVariable(MDStackingFault_parameters['copy_to'], 'testNoiseSampling', str(1))
223 simulationDir = os.path.abspath(".")
224 ddBase = pyMoDELib.DefectiveCrystalBase(simulationDir)
225
226 matFile = "inputFiles/AlMg5.txt"
227 absoluteTemp = 1
228 mat = pyMoDELib.PolycrystallineMaterialBase(matFile, absoluteTemp)
229 b_SI = getValueInFile(f"{matFile}", "b_SI")
230 mu0_SI = getValueInFile(f"{matFile}", "mu0_SI")
231 rho_SI = getValueInFile(f"{matFile}", "rho_SI")
232
233 tag = "0"
234 originalCorrFile = "inputFiles/AlMg5_Cx_R100_ISF.vtk"
235 seed = 1
236 gridSize = np.array([100, 100, 1])
237 gridSpacing = np.array([1e-10, 1e-10, 1e-10]) / b_SI
238 latticeBasis = np.array([[1, 1], [1, 1]]).reshape(2, 2)
239
240 sfNoise = pyMoDELib.MDStackingFaultNoise(
241 mat,
242 tag,
243 originalCorrFile,
244 seed,
245 gridSize.reshape(3, 1),
246 gridSpacing.reshape(3, 1),
247 latticeBasis,
248 )
249
250 realizationNum = 100
251 sampledNoises = np.array(sfNoise.sampleAverageNoise(realizationNum))
252 std = np.std(sampledNoises)
253 print(f"std = {std} J/m2")
254
255 fig, axs = plt.subplots(1, 1, figsize=(8,6), dpi=200)
256 # (returns a veiw if possible), flattens the array for histogram
257 sampledNoises = sampledNoises.ravel()
258 axs.hist(sampledNoises, density=True, alpha=0.3, bins='auto', label=f"R{realizationNum}")
259 axs.grid(True)
260 axs.set_title(f"sampled SF noise")
261 axs.set_xlabel(f"")
262 axs.set_ylabel(f"")
263 axs.legend()
264 fig.savefig(f'sampledNoiseDistribution_R{realizationNum}.png')
265
266 return 0
267
268
269if __name__ == "__main__":
270 main()
REAL split