25 const std::filesystem::path root(
argv[1]);
26 const auto folder = std::filesystem::temp_directory_path() /
27 (
"node-motion-" + std::to_string(std::chrono::steady_clock::now().time_since_epoch().count()));
28 const auto input = folder /
"inputFiles";
29 std::filesystem::create_directories(input);
30 std::filesystem::create_directories(folder /
"F");
31 std::filesystem::copy_file(root /
"Library/Materials/W.txt", input /
"W.txt");
32 const auto meshFile = root /
"Library/Meshes/unitCube24.msh";
33 std::filesystem::copy_file(meshFile, input /
"mesh.msh");
35 std::vector<int> seeds;
40 for(
const auto& face : region.second->faces())
42 const auto& pair = face.second->periodicFacePair;
43 if(pair.second && pair.first[
axis] > 0.9 &&
44 pair.first.normalized().cross(Eigen::Vector3d::Unit(
axis)).norm() < 1.e-8)
46 seeds.push_back(face.first);
51 require(seeds.size() == 3,
"Expected three cube periodic directions");
54 std::filesystem::copy_file(root /
"Library/DislocationDynamics/DD.txt", input /
"DD.txt");
55 const double length=200.0/std::sqrt(3.0);
56 for(
int scenario=0;scenario<5;++scenario)
59 std::ofstream
f(input /
"DefectiveCrystal.txt");
60 f <<
"physics=DislocationDynamics;\nuseFEM=0;\nNsteps=0;\nmaxResolveSteps=0;\ndtMax=1;\noutputFrequency=1;\noutputBinary=0;\nstartAtTimeStep=0;\nperiodicImageSize=0;\nEwaldLengthFactor=0;\n";
61 std::ofstream
p(input /
"polycrystal.txt");
62 p <<
"materialFile=W.txt;\nmeshFile=mesh.msh;\nabsoluteTemperature=300;\nC2G1=1 0 0 0 1 0 0 0 1;\nF=" << std::setprecision(17) << length <<
" 0 0 0 " << length <<
" 0 0 0 " << length <<
";\nX0=0 0 0;\nperiodicFaceIDs=";
72 using V=Eigen::Vector3d;
74 const auto grain=base.poly.grain(1);
75 const auto plane=base.dislocationDynamics().glidePlaneFactory.getFromKey(
model::GlidePlaneKey<3>(V::Zero(),grain->reciprocalLatticeDirection(V::UnitZ())));
76 const V burgers=2.0/std::sqrt(3.0)*V::UnitX();
78 const auto second=network.
loops().
create(scenario==1 ?
V(-burgers) : scenario==2 ?
V(2*burgers) : burgers,plane);
84 const auto makeNode=[&](
const auto& loop,
const auto& net)
86 const V offset=(scenario==3 && loop==second) ?
V(length,0,0) : V::Zero();
87 return network.
loopNodes().
create(loop,net,
V(net->get_P()+offset),loop->periodicGlidePlane->getPatch(-offset),
92 network.
insertLoop(
first,std::vector<std::shared_ptr<Network::LoopNodeType>>{
104 network.
insertLoop(second,std::vector<std::shared_ptr<Network::LoopNodeType>>{
105 makeNode(second,
c),makeNode(second,
a),makeNode(second,d),makeNode(second,
e),makeNode(second,
b)});
109 network.
insertLoop(second,std::vector<std::shared_ptr<Network::LoopNodeType>>{
110 makeNode(second,
a),makeNode(second,
c),makeNode(second,
b),makeNode(second,
e),makeNode(second,d)});
113 for(
const auto* candidate :
first->linkSequence())
115 if(candidate->source->networkNode==
a && candidate->sink->networkNode==
b)
120 require(link!=
nullptr,
"Missing tested segment");
121 const auto actual=link->
spline();
127 require(oldSpline.
get_rll(0.5).norm()>1.e-3,
"Regression geometry does not expose the old curvature error");
130 scenario==2 ?
c->get_P() : d->get_P(),
a->get_P(),
b->get_P(),scenario==2 ?
c->get_P() :
e->get_P());
131 for(
double u : {0.1,0.5,0.9})
133 require((actual.get_rl(
u)-expected.
get_rl(
u)).norm()<1.e-10,
"Wrong junction spline tangent");
134 require((actual.get_rll(
u)-expected.
get_rll(
u)).norm()<1.e-10,
"Wrong junction spline curvature");
137 require(actual.get_rll(
u).norm()<1.e-10,
"Artificial loop closure produces line tension on a straight segment");
141 std::filesystem::remove_all(folder);
142 std::cout <<
"PASS: cancelling junction continuation, reversed Burgers and genuine junction preservation\n";
145 catch(
const std::exception& error)
147 std::cerr << error.what() <<
'\n';