1"""Generate a polycrystal with random prismatic loops and 33-direction strain loading."""
4from pathlib
import Path
7repository = Path(__file__).resolve().parents[2]
8parser = argparse.ArgumentParser(description=__doc__)
9parser.add_argument(
"--output-dir", type=Path, default=Path(__file__).resolve().parent,
10 help=
"Simulation folder (defaults to this tutorial folder).")
11args = parser.parse_args()
12args.output_dir.mkdir(parents=
True, exist_ok=
True)
13os.chdir(args.output_dir.resolve())
14sys.path.insert(0, str(repository /
"python"))
15from modlibUtils
import *
19folders=[
'config',
'F',
'inputFiles']
21 if not os.path.exists(x):
25DCfile=
'DefectiveCrystal.txt'
26DCfileTemplate=str(repository)+
'/Library/DefectiveCrystal/'+DCfile
27print(
"\033[1;32mCreating DDfile\033[0m")
28shutil.copy2(DCfileTemplate,
'inputFiles/'+DCfile)
29setInputVariable(
'inputFiles/'+DCfile,
'physics',
'DislocationDynamics ElasticDeformation')
30setInputVariable(
'inputFiles/'+DCfile,
'useFEM',
'0')
31setInputVariable(
'inputFiles/'+DCfile,
'Nsteps',
'10000')
32setInputVariable(
'inputFiles/'+DCfile,
'maxResolveSteps',
'0')
33setInputVariable(
'inputFiles/'+DCfile,
'dtMax',
'1e25')
34setInputVariable(
'inputFiles/'+DCfile,
'outputFrequency',
'1')
36setInputVariable(
'inputFiles/'+DCfile,
'startAtTimeStep',
'-1')
37setInputVector(
'inputFiles/'+DCfile,
'periodicImageSize',np.array([0,0,0]),
'image counts for the active periodic directions')
41DDfileTemplate=str(repository)+
'/Library/DislocationDynamics/'+DDfile
42print(
"\033[1;32mCreating DDfile\033[0m")
43shutil.copy2(DDfileTemplate,
'inputFiles/'+DDfile)
44setInputVariable(
'inputFiles/'+DDfile,
'timeSteppingMethod',
'adaptive')
45setInputVariable(
'inputFiles/'+DDfile,
'dxMax',
'10')
46setInputVariable(
'inputFiles/'+DDfile,
'use_velocityFilter',
'1')
47setInputVariable(
'inputFiles/'+DDfile,
'alphaLineTension',
'1.0')
48setInputVariable(
'inputFiles/'+DDfile,
'Lmin',
'25')
49setInputVariable(
'inputFiles/'+DDfile,
'Lmax',
'150')
50setInputVariable(
'inputFiles/'+DDfile,
'outputQuadraturePoints',
'1')
51setInputVariable(
'inputFiles/'+DDfile,
'glideSolverType',
'Galerkin')
52setInputVariable(
'inputFiles/'+DDfile,
'climbSolverType',
'none')
53setInputVariable(
'inputFiles/'+DDfile,
'crossSlipModel',
'0')
57materialFileTemplate=str(repository)+
'/Library/Materials/'+materialFile;
58print(
"\033[1;32mCreating materialFile\033[0m")
59shutil.copy2(materialFileTemplate,
'inputFiles/'+materialFile)
61b_SI=getValueInFile(
'inputFiles/'+materialFile,
'b_SI')
64elasticDeformatinoFile=
'ElasticDeformation.txt';
65elasticDeformatinoFileTemplate=str(repository)+
'/Library/ElasticDeformation/'+elasticDeformatinoFile;
66print(
"\033[1;32mCreating elasticDeformatinoFile\033[0m")
67shutil.copy2(elasticDeformatinoFileTemplate,
'inputFiles/'+elasticDeformatinoFile)
68setInputVector(
'inputFiles/'+elasticDeformatinoFile,
'ExternalStress0',np.zeros(6),
'applied stress')
71setInputVector(
'inputFiles/'+elasticDeformatinoFile,
'ExternalStrainRate',
72 np.array([0.0, 0.0, strainRate33, 0.0, 0.0, 0.0]),
'applied strain rate in the global 33 direction')
73setInputVector(
'inputFiles/'+elasticDeformatinoFile,
'stiffnessRatio',
74 np.array([0.0, 0.0, 1e20, 0.0, 0.0, 0.0]),
'strain control in 33; zero-stress control in the other components')
78meshFile=
'poly30_periodicXYZ.msh';
79meshFileTemplate=str(repository)+
'/Library/Meshes/'+meshFile;
80print(
"\033[1;32mCreating polycrystalFile\033[0m")
81shutil.copy2(meshFileTemplate,
'inputFiles/'+meshFile)
82pf=PolyCrystalFile(materialFile);
83pf.absoluteTemperature=300;
86pf.grain1globalX1 = np.array([1.0, 0.0, 0.0])
87pf.grain1globalX3 = np.array([0.0, 0.0, 1.0])
88pf.boxScaling=np.array([1e-6,1e-6,1e-6])/b_SI
89pf.X0=np.array([0,0,0])
90pf.periodicFaceIDs=np.array([-1])
94rx = np.array([[1., 0., 0.], [0., 0.8, -0.6], [0., 0.6, 0.8]])
95ry = np.array([[0.8, 0., 0.6], [0., 1., 0.], [-0.6, 0., 0.8]])
96rz = np.array([[0.8, -0.6, 0.], [0.6, 0.8, 0.], [0., 0., 1.]])
97grainOrientations = [np.eye(3), rx, rx.T, ry, ry.T, rz, rz.T,
98 rx @ ry, ry @ rz, rz @ rx]
101elementaryRotations = [rx, rx.T, ry, ry.T, rz, rz.T]
102for first
in elementaryRotations:
103 for second
in elementaryRotations:
104 orientation = first @ second
105 if len(grainOrientations)<30
and not any(
106 np.allclose(orientation, existing, rtol=0, atol=1e-12)
107 for existing
in grainOrientations):
108 grainOrientations.append(orientation)
109if len(grainOrientations)!=30:
110 raise ValueError(
'Expected 30 distinct grain orientations')
114repeatCounts = 25 * np.maximum(1, np.round(pf.boxScaling / (25 * pf.boxEdgesLatticeLengths)))
116pf.boxScaling = meshScale * repeatCounts * pf.boxEdgesLatticeLengths
117pf.write(
'inputFiles')
118with open(
'inputFiles/polycrystal.txt',
'a')
as polycrystalFile:
119 for grainID, orientation
in enumerate(grainOrientations[1:], start=2):
120 rows = [
' '.join(f
'{value:.17g}' for value
in row)
for row
in orientation]
121 polycrystalFile.write(f
'C2G{grainID}=' +
'\n '.join(rows)
122 +
'; # crystal-to-global rotation\n')
126microstructureName =
'prismaticLoopsDensity.txt'
127microstructureFile =
'inputFiles/' + microstructureName
128shutil.copy2(repository /
'Library/Microstructures/prismaticLoopsDensity.txt',
133setInputVector(microstructureFile,
'allowedGrainIDs', np.array([-1]),
'random placement throughout all grains')
135with open(
'inputFiles/initialMicrostructure.txt',
'w')
as initialMicrostructureFile:
136 initialMicrostructureFile.write(
'microstructureFile=' + microstructureName +
';\n')
139print(
'Inputs ready: ' + str(Path.cwd()))
140print(
'Run microstructureGenerator, then DDomp, using this simulation folder.')
setInputVector(fileName, variable, newVal, newCom)
setInputVariable(fileName, variable, newVal)