27 const std::filesystem::path root(
argv[1]);
28 const auto folder = std::filesystem::temp_directory_path() /
29 (
"bicrystal-collapse-4244-" + std::to_string(std::chrono::steady_clock::now().time_since_epoch().count()));
30 const auto input = folder /
"inputFiles";
31 std::filesystem::create_directories(input);
32 std::filesystem::create_directories(folder /
"F");
33 std::filesystem::copy_file(root /
"Library/Materials/W.txt", input /
"W.txt");
35 std::filesystem::copy_file(root /
"Library/Meshes/bicrystal_48.msh", input /
"mesh.msh");
36 std::filesystem::copy_file(root /
"Library/DislocationDynamics/DD.txt", input /
"DD.txt");
37 std::filesystem::create_directories(folder /
"config");
38 const double length=3671.9477120460206;
40 std::ofstream
f(input /
"DefectiveCrystal.txt");
41 f <<
"physics=DislocationDynamics;\nuseFEM=0;\nNsteps=0;\nmaxResolveSteps=0;\ndtMax=1;\noutputFrequency=1;\noutputBinary=0;\nstartAtTimeStep=0;\nperiodicImageSize=0 0 0;\nEwaldLengthFactor=0;\n";
42 std::ofstream
p(input /
"polycrystal.txt");
43 p << std::setprecision(17) <<
"materialFile=W.txt;\nmeshFile=mesh.msh;\nabsoluteTemperature=300;\nC2G1=1 0 0 0 1 0 0 0 1;\n"
44 <<
"C2G2=0.8 0 0.6 0 1 0 -0.6 0 0.8;\nF=" << length <<
" 0 0 0 " << length <<
" 0 0 0 " << length
45 <<
";\nX0=0 0 0;\nperiodicFaceIDs=-1;\n";
49 const auto dd=input/
"DD.txt";
50 std::ifstream source(dd);
51 std::string contents((std::istreambuf_iterator<char>(source)),std::istreambuf_iterator<char>());
52 const auto location=contents.find(
"Lmax=100;");
53 require(location!=std::string::npos,
"Expected library remeshing default");
54 contents.replace(location,std::string(
"Lmax=100;").size(),
"Lmax=150;");
55 std::ofstream output(dd);
63 std::ifstream stream(root/
"tests/data/bicrystalCollapse4244.txt");
64 require(
bool(stream),
"Missing frame 4244 fixture");
67 require(network.
loops().size()==6,
"Incomplete junction neighborhood");
68 require(network.
loops().at(5860).lock()->currentAreaVector().norm()>1.0,
"Initial loop has no slipped area");
70 const auto loop=network.
loops().at(5860).lock();
71 const auto plane=loop->periodicGlidePlane;
72 const Eigen::Vector3d originalApex=network.
loopNodes().
get(6036331)->get_P();
73 const std::array<Eigen::Vector3d,3> trial{
74 Eigen::Vector3d(3672.8571855755372,480.38042416509757,-1119.2670014528765),
75 Eigen::Vector3d(3671.947712046021,458.39269828388035,-1146.0695536572607),
76 Eigen::Vector3d(3671.947712046021,489.69414114074192,-1106.9427500861839)};
77 for(
bool outside : {
false,
true})
79 for(
size_t start=0;start<3;++start)
81 for(
bool reverse : {
false,
true})
83 std::vector<std::pair<Eigen::Vector2d,const int* const>> polygon;
84 for(
size_t k=0;
k<3;++
k)
86 const size_t i=(start+(reverse ? 3-
k :
k))%3;
87 polygon.emplace_back(plane->referencePlane->localPosition(
i==0 && !outside ? originalApex : trial[
i]),
nullptr);
89 const auto contour=plane->polygonPatchIntersection(polygon,
false);
92 require(contour.empty(),
"Clipped line returned a degenerate contour");
96 require(contour.size()>=3,
"Valid nearby slipped area was discarded");
98 for(
size_t k=0;
k<contour.size();++
k)
100 const auto a=std::get<0>(contour[
k])-std::get<0>(contour.front());
101 const auto b=std::get<0>(contour[(
k+1)%contour.size()])-std::get<0>(contour.front());
104 require(std::abs(
area)>1.0,
"Nearby contour lost its nonzero area");
111 require(network.
loops().count(5860)==0,
"Collapsed retained line survived as a loop");
115 const std::set<size_t> survivingLoops{5852,5892,5893};
116 require(network.
loops().size()==survivingLoops.size(),
"Unexpected surviving loop count");
117 for(
const auto& entry : network.
loops())
119 require(survivingLoops.count(entry.first) && entry.second.lock()->currentAreaVector().norm()>1.0,
120 "Lost a nonzero-area neighbor");
125 const auto link=entry.second.lock();
126 std::set<size_t> memberships;
127 Eigen::Vector3d sum=Eigen::Vector3d::Zero();
128 for(
const auto* ll : link->loopLinks())
130 memberships.insert(ll->loop->sID);
131 sum+=(ll->source->networkNode==link->source ? 1.0 : -1.0)*ll->flow().cartesian();
133 require(memberships==survivingLoops,
"Clipping damaged the three-loop junction sharing");
134 require((sum-link->burgers()).norm()<1.e-12,
"Shared Burgers sum is inconsistent");
136 const auto loopCount=network.
loops().size();
138 std::map<std::pair<size_t,size_t>,Eigen::Vector3d> burgers;
141 burgers.emplace(entry.first,entry.second.lock()->burgers());
145 network.
networkLinks().size()==burgers.size(),
"Boundary update is not idempotent");
148 require((entry.second.lock()->burgers().array()==burgers.at(entry.first).array()).all(),
"Shared Burgers vector changed");
150 for(
const auto& entry : network.
loopNodes())
152 const auto node=entry.second.lock();
153 require((node->get_P()+node->periodicPlanePatch()->shift-node->networkNode->get_P()).norm()<1.e-7,
154 "Periodic loop/network mapping changed");
156 std::filesystem::remove_all(folder);
157 std::cout<<
"PASS: frame 4244 collapsed clipping result and shared boundary junctions\n";
160 catch(
const std::exception& error)
162 std::cerr<<error.what()<<
'\n';