Mechanics of Defect Evolution Library
Loading...
Searching...
No Matches
analyticalSolidSolutionCorrelations/main.py
Go to the documentation of this file.
1import os
2import sys
3import glob
4import string
5import numpy as np
6import matplotlib.pyplot as plt
7
8plt.rcParams["text.usetex"] = True
9import matplotlib as mpl
10import matplotlib.transforms as mtransforms
11
12sys.path.append("../../build/tools/pyMoDELib/")
13import pyMoDELib
14from scipy.signal import correlate2d
15from scipy.stats import norm
16from matplotlib import cm
17from matplotlib.colors import Normalize
18
19sys.path.append("../../python")
20from modlibUtils import *
21from pathlib import Path
22
23# Define all file templates (using pathlib for cross-platform paths)
24file_templates = {
25 "dd_file": Path("../../Library/DislocationDynamics/DD.txt"),
26 "noise_file": Path("../../Library/GlidePlaneNoise/AnalyticalSolidSolutionNoise.txt"),
27 "material_file": Path("../../Library/Materials/AlMg5.txt"),
28 "elastic_deformation_file": Path(
29 "../../Library/ElasticDeformation/ElasticDeformation.txt"
30 ),
31 "mesh": Path("../../Library/Meshes/unitCube24.msh"),
32 "microstructure": Path(
33 "../../Library/Microstructures/periodicDipoleIndividual.txt"
34 ),
35}
36
37AnalyticalSolidSolution_parameters = {
38 "variables": {
39 # Scalar parameters (use setInputVariable)
40 "type": "AnalyticalSolidSolutionNoise",
41 "tag": 1,
42 "seed": 2,
43 "outputNoise": 1,
44 "a_cai_SI": 1,
45 },
46 "vectors": {
47 # Vector parameters with comments (use setInputVector)
48 "gridSize": {
49 "value": np.array([100, 100, 1]),
50 "comment": "number of grid points in each direction",
51 },
52 "gridSpacing_SI": {
53 "value": np.array([1.0e-10, 1.0e-10, 1e-10]),
54 "comment": "grid spacing in each direction",
55 },
56 },
57 "copy_to": "inputFiles/AnalyticalSolidSolutionNoise.txt",
58}
59
60Material_parameters = {
61 "variables": {
62 "enabledSlipSystems": "Shockley",
63 #'glidePlaneNoise': ['MDSolidSolution.txt', 'MDStackingFault.txt'],
64 "glidePlaneNoise": "AnalyticalSolidSolutionNoise.txt",
65 "atomsPerUnitCell": "1",
66 "dislocationMobilityType": "default",
67 },
68 "copy_to": "inputFiles/AlMg5.txt",
69}
70
71Polycrystal_parameters = {
72 "parameters": {
73 "absoluteTemperature": 1,
74 "grain1globalX1": np.array([0, 1, 1]),
75 "grain1globalX3": np.array([-1, 1, -1]),
76 "boxEdges": np.array([[0, 1, 1], [-2, -1, 1], [-1, 1, -1]]),
77 "boxScaling": np.array([200, 200, 200]),
78 #'X0': np.array([0.5, 0.5, 0.5]),
79 "X0": np.array([0.0, 0.0, 0.0]),
80 "periodicFaceIDs": np.array([0, 1, 2, 3, 4, 5]),
81 "gridSpacing_SI": np.array([1.0e-10, 1.0e-10]),
82 }
83}
84
86 # Copy all template files
87 print("\033[1;32mCopying template files...\033[0m")
88 for key, src_path in file_templates.items():
89 dest = f"inputFiles/{src_path.name}"
90 shutil.copy2(src_path.resolve(), dest)
91 # shutil.copy2(src_path, dest)
92 print(f"Created {dest}")
93
94 # print("\033[1;32mCreating ddFile\033[0m")
95
98
99 print("\033[1;32mCreating noiseFile\033[0m")
100 # copy declared variables to the configuration txt file
101 for param, value in AnalyticalSolidSolution_parameters["variables"].items():
102 if "correlationFile" in param:
103 relativePath = f"{str(value).split('/')[-1]}"
104 setInputVariable(AnalyticalSolidSolution_parameters["copy_to"], param, relativePath)
105 else:
106 setInputVariable(AnalyticalSolidSolution_parameters["copy_to"], param, str(value))
107 for param, data in AnalyticalSolidSolution_parameters["vectors"].items():
109 AnalyticalSolidSolution_parameters["copy_to"], param, data["value"], data["comment"]
110 )
111
112 # Process material file
113 print("\033[1;32mCreating materialFile...\033[0m")
114 # print(Material_parameters['variables'].items())
115 matParams = Material_parameters["variables"]
117 Material_parameters["copy_to"],
118 "enabledSlipSystems",
119 matParams["enabledSlipSystems"],
120 )
121
122 # for gPlaneNoise in matParams['glidePlaneNoise']:
123 # setInputVariable(Material_parameters['copy_to'],'glidePlaneNoise',gPlaneNoise)
125 Material_parameters["copy_to"], "glidePlaneNoise", matParams["glidePlaneNoise"]
126 )
127
129 Material_parameters["copy_to"],
130 "atomsPerUnitCell",
131 matParams["atomsPerUnitCell"],
132 )
134 Material_parameters["copy_to"],
135 "dislocationMobilityType",
136 matParams["dislocationMobilityType"],
137 )
138
139 # Process polycrystal
140 # pf = PolyCrystalFile('FeCrAl_Fe.txt')
141 pf = PolyCrystalFile(Material_parameters["copy_to"].split("/")[-1])
142 # pf.meshFile='unitCube24.msh'
143 pf.meshFile = f'{str(file_templates["mesh"]).split("/")[-1]}'
144 for param, value in Polycrystal_parameters["parameters"].items():
145 setattr(pf, param, value)
146 pf.write("inputFiles")
147
148
149def constructDotGrid(NX, NY, unitVec1, unitVec2):
150 # Construct non-orthogonal dot grid based on the non-minimized atom structure
151 firstNearNeighborDist = 2.8
152 dotGrid = np.zeros((NX * NY, 2)) # each row contains x and y position of the dot
153 vec1 = unitVec1 * firstNearNeighborDist
154 vec2 = unitVec2 * firstNearNeighborDist
155 for yIdx in range(NY):
156 for xIdx in range(NX):
157 dotGrid[yIdx * NX + xIdx] = vec1 * xIdx + vec2 * yIdx
158 return dotGrid
159
160
161def initUnitVectors(originalCorrVTK: str):
162 latVector1 = None
163 latVector2 = None
164 copyFlag1 = False
165 copyFlag2 = False
166 with open(originalCorrVTK) as o:
167 for line in o:
168 if copyFlag1:
169 latVector1 = np.array(line.strip().split(), dtype=float)
170 copyFlag1 = False
171 elif copyFlag2:
172 latVector2 = np.array(line.strip().split(), dtype=float)
173 copyFlag2 = False
174 elif "VECTORS lattice_basis1 double" in line:
175 copyFlag1 = True
176 elif "VECTORS lattice_basis2 double" in line:
177 copyFlag2 = True
178
179 unitVec1 = latVector1 / np.linalg.norm(latVector1)
180 unitVec2 = latVector2 / np.linalg.norm(latVector2)
181 unitVec1 = unitVec1[:2] # drop the z axis value
182 unitVec2 = unitVec2[:2]
183 return unitVec1, unitVec2
184
185
186def plotComparisonHistogram(realizationNumbers: list):
187 # Plotting on the first subplot
188 fig, axs = plt.subplots(1, 1, figsize=(8, 6), dpi=200) # Adjusted for two subplots
189
190 matFile = str(file_templates["material_file"]).split("/")[-1]
191 b_SI = getValueInFile(f"inputFiles/{matFile}", "b_SI")
192 mu0_SI = getValueInFile(f"inputFiles/{matFile}", "mu0_SI")
193
194 inputPath = "./inputFiles/"
195 for i, realizationNum in enumerate(realizationNumbers):
196 data = np.loadtxt(f"{inputPath}/noiseDistributionR{realizationNum}.txt")
197 data *= mu0_SI * b_SI
198 axs.hist(data, density=True, alpha=0.3, bins="auto", label=f"R{realizationNum}")
199
200 std = np.std(data)
201 # Annotate in the top right, offsetting each annotation
202 axs.text(
203 0.98,
204 0.95 - 0.05 * i,
205 f"R{realizationNum} = STD {std:.3g} J/m2",
206 transform=axs.transAxes,
207 ha="right",
208 va="top",
209 )
210
211 axs.grid(True)
212 axs.set_title(f"")
213 axs.set_xlabel(f"")
214 axs.set_ylabel(f"")
215 axs.legend()
216 fig.savefig(f"sampledNoiseDistribution.png")
217 plt.close()
218
219
220def circularShift(corrArray: np.ndarray, gridSize: np.ndarray) -> np.ndarray:
221 NX, NY = np.squeeze(gridSize[0]), np.squeeze(gridSize[1])
222 shiftY = NY / 2
223 shiftX = NX / 2
224 tempArr = np.zeros(NX * NY)
225 for y in np.arange(NY):
226 newY = int((y + shiftY) % NY)
227 for x in np.arange(NX):
228 newX = int((x + shiftX) % NX)
229 tempArr[newY * NX + newX] += corrArray[y * NX + x]
230 return tempArr
231
232
233def main() -> int:
234 # Preparing input files
235 folders = ["inputFiles"]
236 for x in folders:
237 # remove existing data
238 if os.path.exists(x):
239 shutil.rmtree(x)
240 # create necessary folder structure for the simulation
241 os.makedirs(x)
242
243 # set simulation parameters in inputFiles
245
246 simulationDir = os.path.abspath(".")
247 ddBase = pyMoDELib.DefectiveCrystalBase(simulationDir)
248
249 matFile = "inputFiles/AlMg5.txt"
250 absoluteTemp = 1
251 mat = pyMoDELib.PolycrystallineMaterialBase(matFile, absoluteTemp)
252 b_SI = getValueInFile(f"{matFile}", "b_SI")
253 mu0_SI = getValueInFile(f"{matFile}", "mu0_SI")
254 rho_SI = getValueInFile(f"{matFile}", "rho_SI")
255
256 tag = "1"
257 seed = 0
258 gridSize = np.array([256, 256, 64])
259 gridSpacing = np.array([1e-10, 1e-10, 1e-10])/b_SI
260 latticeBasis = np.array([[1, 0], [0, 1]]).reshape(2, 2)
261
262 msss_SI=0.9e18 /mu0_SI**2; #[Pa^2] Mean Square Shear Stress
263 a = 1e-10 /b_SI
264 a_cai_SI = 1e-09 /b_SI # in meter
265 #a_cai_SI =
266 anssNoise = pyMoDELib.AnalyticalSolidSolutionNoise(
267 tag,
268 seed,
269 gridSize.reshape(3, 1),
270 gridSpacing.reshape(3, 1),
271 latticeBasis,
272 a,
273 a_cai_SI,
274 msss_SI
275 )
276
277 realizationNum = 100
278 corr_xz, corr_yz = np.array(anssNoise.averageNoiseCorrelation(realizationNum)) * mu0_SI**2
279
280 corr_xz = circularShift(corr_xz, gridSize)
281 corr_yz = circularShift(corr_yz, gridSize)
282 corr_xz = corr_xz.reshape(gridSize[0], gridSize[1])
283 corr_yz = corr_yz.reshape(gridSize[0], gridSize[1])
284
285 fig, axes = plt.subplots(nrows=1, ncols=2, figsize=(12, 6), dpi=200)
286 # First plot with colorbar
287 axes[0].set_title("corr_xz")
288 im0 = axes[0].imshow(corr_xz, cmap="coolwarm", origin="lower")
289 fig.colorbar(im0, ax=axes[0], label="Noise Amplitude")
290 axes[0].set_xlabel("X (grid units)")
291 axes[0].set_ylabel("Y (grid units)")
292
293 # Second plot with colorbar
294 axes[1].set_title("corr_yz")
295 im1 = axes[1].imshow(corr_yz, cmap="coolwarm", origin="lower")
296 fig.colorbar(im1, ax=axes[1], label="Noise Amplitude")
297 axes[1].set_xlabel("X (grid units)")
298 axes[1].set_ylabel("Y (grid units)")
299 plt.tight_layout()
300 fig.savefig(f"ensemCorr_R{realizationNum}.png", transparent=True)
301
302 return 0
303
304
305if __name__ == "__main__":
306 main()
initUnitVectors(str originalCorrVTK)
plotComparisonHistogram(list realizationNumbers)
np.ndarray circularShift(np.ndarray corrArray, np.ndarray gridSize)
constructDotGrid(NX, NY, unitVec1, unitVec2)
setInputVector(fileName, variable, newVal, newCom)
setInputVariable(fileName, variable, newVal)
getValueInFile(fileName, variable)
REAL split