28 const std::filesystem::path root(
argv[1]);
29 const auto folder = std::filesystem::temp_directory_path() /
30 (
"junction-insertion-" + std::to_string(std::chrono::steady_clock::now().time_since_epoch().count()));
31 const auto input = folder /
"inputFiles";
32 std::filesystem::create_directories(input);
33 std::filesystem::create_directories(folder /
"F");
34 std::filesystem::copy_file(root /
"Library/Materials/W.txt", input /
"W.txt");
36 std::filesystem::copy_file(root /
"Library/Meshes/bicrystal_48.msh", input /
"mesh.msh");
37 std::filesystem::copy_file(root /
"Library/DislocationDynamics/DD.txt", input /
"DD.txt");
38 std::filesystem::create_directories(folder /
"config");
40 std::array<int,3> seeds{-1,-1,-1};
43 for(
const auto& face : region.second->faces())
45 const auto& pair=face.second->periodicFacePair;
50 if(pair.first.normalized().cross(Eigen::Vector3d::Unit(
axis)).norm()<1.e-8)
52 seeds[
axis]=face.first;
58 require(seeds[0]>=0 && seeds[1]>=0,
"Missing periodic seeds");
60 const double length=3671.9477120460206;
61 for(
int scenario=0;scenario<3;++scenario)
63 const bool full=scenario==1;
66 std::ofstream
f(input/
"DefectiveCrystal.txt");
67 f<<
"physics=DislocationDynamics;\nuseFEM=0;\nNsteps=0;\nmaxResolveSteps=0;\ndtMax=1;\noutputFrequency=1;\noutputBinary=0;\nstartAtTimeStep=0;\nperiodicImageSize="<<(full ?
"0 0 0" :
"0")<<
";\nEwaldLengthFactor=0;\n";
68 std::ofstream
p(input/
"polycrystal.txt");
69 p<<std::setprecision(17)<<
"materialFile=W.txt;\nmeshFile=mesh.msh;\nabsoluteTemperature=300;\nC2G1=1 0 0 0 1 0 0 0 1;\nC2G2=0.8 0 0.6 0 1 0 -0.6 0 0.8;\nF="<<length<<
" 0 0 0 "<<length<<
" 0 0 0 "<<length<<
";\nX0=0 0 0;\nperiodicFaceIDs=";
72 p<<(full ? -1 : seeds[1]);
79 using V=Eigen::Vector3d;
81 const auto grain=base.poly.grain(1);
83 const V a=length*
V(-0.5,0,0);
85 const V burgers=2.0/std::sqrt(3.0)*V::UnitY();
86 const auto insert=[&](
const std::vector<V>& polygon,
const V& normal)
88 const auto plane=base.dislocationDynamics().periodicGlidePlaneFactory.get(
model::GlidePlaneKey<3>(polygon.front(),grain->reciprocalLatticeDirection(normal)));
91 const auto snapshot=[&]()
93 std::ostringstream
out;
94 out<<std::setprecision(17);
95 for(
const auto& node : generator.config().nodes())
99 for(
const auto& loop : generator.config().loops())
103 for(
const auto& node : generator.config().loopNodes())
107 for(
const auto& link : generator.config().loopLinks())
111 for(
const auto& entry : generator.uniqueNetworkNodeMap)
113 out<<entry.first.transpose()<<entry.second;
117 require(insert({
a,
b,length*
V(-0.7,0.1,0)},V::UnitZ()),
"Valid first loop rejected");
118 require(insert({
a,
b,length*
V(-0.5,0.1,0.2)},V::UnitX()),
"Shared junction loop rejected");
119 const auto before=snapshot();
122 require(!insert({
a,length*
V(0.1,0.1,0),length*
V(-0.7,0.2,0)},V::UnitZ()),
"Internal GB crossing accepted");
123 require(!insert({
a,length*
V(-1.1,0.1,0),length*
V(-0.7,0.2,0)},V::UnitZ()),
"Back-face crossing accepted");
126 require(!insert({
a,length*
V(-0.5,0.1,0.7),length*
V(-0.5,0.2,0)},V::UnitX()),
"Physical face crossing accepted");
128 require(before==snapshot(),
"Rejected insertion changed configuration or sharing map");
134 const auto segment=entry.second.lock();
135 if(segment->loopLinks().size()==2)
138 require(segment->glidePlanes().size()==2,
"Junction lost a contributing glide plane");
139 require((segment->burgers().norm()-2.0*burgers.norm())<1.e-8 && segment->burgers().norm()>burgers.norm(),
"Junction Burgers sum changed");
141 for(
const auto* plane : segment->glidePlanes())
143 require(segment->source->glidePlanes().count(plane) && segment->sink->glidePlanes().count(plane),
"Endpoint missing junction plane");
146 for(
const auto& node : generator.config().loopNodes())
148 shifted+=node.periodicShift.norm()>1.e-8;
150 require(shared>0,
"No shared junction tested");
151 require((shifted>0)==
periodic,
"Same-grain periodic crossing not exercised");
153 std::filesystem::remove_all(folder);
154 std::cout<<
"PASS: topology-based insertion and multi-plane junction sharing\n";
157 catch(
const std::exception& error)
159 std::cerr<<error.what()<<
'\n';