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");
33 std::filesystem::copy_file(root /
"Library/Meshes/bicrystal_48.msh", input /
"mesh.msh");
34 std::filesystem::copy_file(root /
"Library/DislocationDynamics/DD.txt", input /
"DD.txt");
35 std::filesystem::create_directories(folder /
"config");
36 const double length=3671.9477120460206;
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 0 0;\nEwaldLengthFactor=0;\n";
40 std::ofstream
p(input /
"polycrystal.txt");
41 p << std::setprecision(17) <<
"materialFile=W.txt;\nmeshFile=mesh.msh;\nabsoluteTemperature=300;\nC2G1=1 0 0 0 1 0 0 0 1;\n"
42 <<
"C2G2=0.8 0 0.6 0 1 0 -0.6 0 0.8;\nF=" << length <<
" 0 0 0 " << length <<
" 0 0 0 " << length
43 <<
";\nX0=0 0 0;\nperiodicFaceIDs=-1;\n";
48 spec.slipSystemIDs={0};
49 spec.loopRadii={1.e-7};
51 spec.loopCenters.resize(1,3);
52 spec.loopCenters << -0.5*length,0,0;
53 generator.addPrismaticLoopIndividual(spec);
54 require(generator.config().loops().size()==7,
"Expected complete prismatic construction");
60 using V=Eigen::Vector3d;
62 double maxRawTangential=0;
65 const auto segment=entry.second.lock();
66 segment->createQuadraturePoints(
false);
67 segment->updateQuadraturePoints(
false);
68 if(!segment->slipSystem())
72 const V normal=segment->slipSystem()->unitNormal;
73 for(
auto& point : segment->quadraturePoints())
76 const V glide=normal.cross(point.rl).normalized();
77 const V raw=point.lineTensionForce;
78 maxRawTangential=std::max(maxRawTangential,std::abs(raw.dot(point.rl)));
79 require(std::abs(point.pkForce.dot(glide))<1.e-9,
"Initial prism has unexpected PK glide force");
80 require(std::abs(raw.dot(glide))<1.e-9,
"Initial prism has unexpected LT glide force");
81 require(point.velocity.norm()<1.e-12,
"Unloaded bicrystal prism has spurious glide velocity");
84 for(
const auto* link : segment->loopLinks())
86 const double u=link->source->networkNode==segment->source ? point.abscissa : 1-point.abscissa;
87 const V curvature=link->spline().get_rll(
u);
88 if(!std::isnan(curvature.squaredNorm()))
90 expected+=point.coreEnergyPerLength*curvature;
93 require((raw-expected).norm()<1.e-12,
"Raw line tension was altered");
94 const auto initialStress=point.internalStress;
96 const auto drive=point.forceToStress(1.e-3*glide,point.rl,*segment);
97 point.internalStress=initialStress+drive;
98 point.updateForcesAndVelocities(*segment,
false);
99 const V positive=point.velocity;
100 require(positive.norm()>1.e-8 && positive.dot(glide)>0,
"Positive glide force gives no forward response");
101 require(std::abs(positive.dot(point.rl))<1.e-12 && std::abs(positive.dot(normal))<1.e-12,
102 "Driven velocity is not along the permitted glide direction");
103 require((point.lineTensionForce-raw).norm()<1.e-12,
"Velocity update modified raw line tension");
105 point.lineTensionForce.setZero();
106 point.updateForcesAndVelocities(*segment,
false);
107 require((point.velocity-positive).norm()<1.e-9,
"Climb/tangential LT changes driven mobility");
108 point.lineTensionForce=raw;
109 point.internalStress=initialStress-drive;
110 point.updateForcesAndVelocities(*segment,
false);
111 require(point.velocity.norm()>1.e-8 && point.velocity.dot(glide)<0,
"Negative glide force gives no reverse response");
112 require(std::abs(point.velocity.dot(point.rl))<1.e-12,
"Reverse velocity is tangential");
113 point.internalStress=initialStress;
114 point.updateForcesAndVelocities(*segment,
false);
117 require(checked>0,
"No quadrature velocities tested");
118 require(maxRawTangential>1.e-6,
"Test did not reproduce a finite tangential LT component");
119 std::filesystem::remove_all(folder);
120 std::cout <<
"PASS: " << checked <<
" bicrystal prism quadrature points, unloaded and driven, raw LT unchanged\n";
123 catch(
const std::exception& error)
125 std::cerr << error.what() <<
'\n';