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");
34 std::filesystem::copy_file(root /
"Library/DislocationDynamics/DD.txt", input /
"DD.txt");
35 const double length=200.0/std::sqrt(3.0);
38 std::ofstream
f(input /
"DefectiveCrystal.txt");
39 f <<
"physics=DislocationDynamics;\nuseFEM=0;\nNsteps=0;\nmaxResolveSteps=0;\ndtMax=1;\noutputFrequency=1;\noutputBinary=0;\nstartAtTimeStep=0;\nperiodicImageSize=0;\nEwaldLengthFactor=0;\n";
40 std::ofstream
p(input /
"polycrystal.txt");
41 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=";
47 using V=Eigen::Vector3d;
49 const auto grain=base.poly.grain(1);
51 const auto ss=grain->slipSystems().at(0);
52 const V burgers=
ss->s.cartesian();
53 const V normal=
ss->unitNormal;
54 const V tangent=normal.cross(burgers).normalized();
55 const V glide=normal.cross(tangent).normalized();
57 const auto loop=network.
loops().
create(burgers,plane);
58 const auto makeNode=[&](
const V&
p)
63 const auto a=makeNode(-10*tangent);
64 const auto b=makeNode(10*tangent);
65 network.
insertLoop(loop,std::vector<std::shared_ptr<Network::LoopNodeType>>{
a,
b,makeNode(10*glide)});
67 const auto segment=
a->next.second->networkLink();
68 require(
bool(segment->slipSystem()),
"Test segment has no mobility slip system");
71 const Eigen::Matrix3d stress=0.1*(burgers.normalized()*normal.transpose()+normal*burgers.normalized().transpose());
72 const auto velocity=[&](
const V& force)
74 return Q::getGlideVelocity(*segment,V::Zero(),force,stress,tangent,1.0,-1);
76 require(velocity(tangent).norm()<1.e-12,
"Purely tangential force drives quadrature motion");
77 require(velocity(normal).norm()<1.e-12,
"Climb force drives glide motion");
78 const V reference=velocity(glide);
79 require(reference.norm()>1.e-12,
"Mobility test is vacuous: no glide response");
80 const V mixed=velocity(glide+100*tangent+20*normal);
81 require((mixed-reference).norm()<1.e-10,
"Tangential force changes glide velocity");
82 require(std::abs(mixed.dot(tangent))<1.e-12,
"Velocity is not orthogonal to the segment");
83 require(std::abs(mixed.dot(normal))<1.e-12,
"Velocity leaves the glide plane");
84 require((velocity(-glide)+reference).norm()<1.e-10,
"Glide force sign is lost");
85 require(point.forceToStress(tangent,tangent,*segment).norm()<1.e-12,
"Tangential force produces mobility stress");
86 const auto resolved=point.forceToStress(glide,tangent,*segment);
87 require((point.forceToStress(glide+100*tangent+20*normal,tangent,*segment)-resolved).norm()<1.e-10,
88 "Unresolved force changes mobility stress");
89 const V recovered=(resolved*segment->burgers()).cross(tangent);
90 require((recovered-glide).norm()<1.e-10,
"Equivalent stress does not recover resolved force");
92 std::filesystem::remove_all(folder);
93 std::cout <<
"PASS: quadrature glide direction and consistent resolved-force stress\n";
96 catch(
const std::exception& error)
98 std::cerr << error.what() <<
'\n';