25 const std::filesystem::path root(
argv[1]);
26 const auto folder = std::filesystem::temp_directory_path() /
27 (
"bicrystal-open-boundary-" + 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";
47 const auto dd=input/
"DD.txt";
48 std::ifstream source(dd);
49 std::string contents((std::istreambuf_iterator<char>(source)),std::istreambuf_iterator<char>());
50 const auto location=contents.find(
"Lmax=100;");
51 require(location!=std::string::npos,
"Expected library remeshing default");
52 contents.replace(location,std::string(
"Lmax=100;").size(),
"Lmax=150;");
53 std::ofstream output(dd);
61 std::ifstream stream(root/
"tests/data/bicrystalBoundary621.txt");
62 require(
bool(stream),
"Missing bicrystal junction regression fixture");
65 using V=Eigen::Vector3d;
66 const double dt=147.3858585805344;
70 const auto node=entry.second.lock();
71 node->trySet_P(node->get_P()+dt*node->get_V());
73 const auto target=network.
loops().at(162).lock();
74 std::vector<V> polygon;
75 for(
const auto* link : target->linkSequence())
77 if(!link->source->isPeriodicSubdivision())
79 polygon.push_back(link->source->get_P());
85 for(
bool left : {
true,
false})
87 std::vector<V> clipped;
88 for(
size_t i=0;
i<polygon.size(); ++
i)
90 const V&
a=polygon[
i];
91 const V&
b=polygon[(
i+1)%polygon.size()];
92 const double da=
left ?
a.x()+length : -
a.x();
93 const double db=
left ?
b.x()+length : -
b.x();
100 clipped.push_back(
a+da/(da-db)*(
b-
a));
103 polygon=std::move(clipped);
105 const auto area=[](
const std::vector<V>& points)->
V
110 for(
size_t i=0;
i<points.size(); ++
i)
112 result+=0.5*(points[
i]-points.front()).cross(points[(
i+1)%points.size()]-points.front());
117 const V expected=
area(polygon);
118 require(expected.norm()>1,
"Regression target has no resolved slipped area");
121 const auto check=[&]()
123 std::vector<V> actual;
124 for(
const auto* link : target->linkSequence())
126 actual.push_back(link->source->get_P());
127 require(link->sink->next.second->source==link->sink,
"Broken loop connectivity");
129 require((
area(actual)-expected).norm()<1.e-8*expected.norm(),
130 "Boundary walk lost or changed a lobe of the retained contour");
131 for(
const auto& entry : network.
loopNodes())
133 const auto node=entry.second.lock();
134 require((node->get_P()+node->periodicPlanePatch()->shift-node->networkNode->get_P()).norm()<1.e-7,
135 "Loop/network periodic mapping is inconsistent");
139 const size_t nodes=network.
loopNodes().size();
142 require(network.
loopNodes().size()==nodes,
"Repeated reconciliation changed contour topology");
145 std::filesystem::remove_all(folder);
146 std::cout<<
"PASS: frame 621 open-boundary walk, area and periodic mapping\n";
149 catch(
const std::exception& error)
151 std::cerr<<error.what()<<
'\n';