50 example({{0,0},{2,0},{2,2},{0,2}},4);
51 example({{0,0},{2,2},{0,2},{2,0}},2);
52 example({{0,0},{2,0},{2,1},{1,1},{1,2},{0,2}},3);
53 example({{0,0},{1,0},{1,1},{0,1},{0,0},{2,0},{3,0},{3,1},{2,1},{2,0}},2);
54 example({{0,0},{3,0},{3,3},{0,3},{0,0},{1,1},{1,2},{2,2},{2,1},{1,1}},8);
55 example({{0,0},{1,0},{1,1},{0,1},{0,0},{1,0},{1,1},{0,1}},1);
56 example({{0,0},{1,0},{1,1},{0,1},{0,0},{0,1},{1,1},{1,0}},0);
57 example({{0,0},{0,0},{1,0},{1,1},{0,1},{0,0}},1);
60 const std::filesystem::path root(
argv[1]);
61 const auto folder = std::filesystem::temp_directory_path() /
62 (
"bicrystal-boundary-topology-" + std::to_string(std::chrono::steady_clock::now().time_since_epoch().count()));
63 const auto input = folder /
"inputFiles";
64 std::filesystem::create_directories(input);
65 std::filesystem::create_directories(folder /
"F");
66 std::filesystem::copy_file(root /
"Library/Materials/W.txt", input /
"W.txt");
68 std::filesystem::copy_file(root /
"Library/Meshes/bicrystal_48.msh", input /
"mesh.msh");
69 std::filesystem::copy_file(root /
"Library/DislocationDynamics/DD.txt", input /
"DD.txt");
70 std::filesystem::create_directories(folder /
"config");
71 const double length=3671.9477120460206;
73 std::ofstream
f(input /
"DefectiveCrystal.txt");
74 f <<
"physics=DislocationDynamics;\nuseFEM=0;\nNsteps=0;\nmaxResolveSteps=0;\ndtMax=1;\noutputFrequency=1;\noutputBinary=0;\nstartAtTimeStep=0;\nperiodicImageSize=0 0 0;\nEwaldLengthFactor=0;\n";
75 std::ofstream
p(input /
"polycrystal.txt");
76 p << std::setprecision(17) <<
"materialFile=W.txt;\nmeshFile=mesh.msh;\nabsoluteTemperature=300;\nC2G1=1 0 0 0 1 0 0 0 1;\n"
77 <<
"C2G2=0.8 0 0.6 0 1 0 -0.6 0 0.8;\nF=" << length <<
" 0 0 0 " << length <<
" 0 0 0 " << length
78 <<
";\nX0=0 0 0;\nperiodicFaceIDs=-1;\n";
82 const auto dd=input/
"DD.txt";
83 std::ifstream source(dd);
84 std::string contents((std::istreambuf_iterator<char>(source)),std::istreambuf_iterator<char>());
85 const auto location=contents.find(
"Lmax=100;");
86 require(location!=std::string::npos,
"Expected library remeshing default");
87 contents.replace(location,std::string(
"Lmax=100;").size(),
"Lmax=150;");
88 std::ofstream output(dd);
92 for(
int frame : {430,433,500})
98 std::ifstream stream(root/
"tests/data"/(
"bicrystalBoundary"+std::to_string(frame)+
".txt"));
99 require(
bool(stream),
"Missing bicrystal fixture");
103 for(
const auto& item : network.
loops())
105 const auto loop=item.second.lock();
106 Eigen::Vector3d fullArea=Eigen::Vector3d::Zero();
107 for(
const auto* link : loop->linkSequence())
109 fullArea+=0.5*link->source->get_P().cross(link->sink->get_P());
113 require((loop->patches().orientedArea()-fullArea).norm()<1.e-8*std::max(1.0,fullArea.norm()),
114 "Patch assembly discarded part of the original loop area");
115 for(
const auto& patch : loop->patches().localPatches())
117 const auto& polygon=patch.second;
118 const double original=
area(polygon);
119 auto reversed=polygon;
120 std::reverse(reversed.begin(),reversed.end());
121 require(std::abs(
area(reversed)-original)<1.e-8*std::max(1.0,original),
122 "Bicrystal fill depends on contour orientation");
128 V low=polygon.front(),high=low;
129 for(
const auto&
p : polygon)
132 high=high.cwiseMax(
p);
135 for(
int i=0;
i<19;++
i)
137 for(
int j=0;
j<19;++
j)
139 const V p=low+(high-low).cwiseProduct(
V((
i+0.371)/19,(
j+0.613)/19));
141 for(
const auto&
t : triangles)
146 "Bicrystal tessellation has missing or overlapping fill");
152 require(patches>0,
"No bicrystal patches tested");
153 std::cout<<
"Checked frame "<<frame<<
": "<<patches<<
" patches\n";
155 std::filesystem::remove_all(folder);
158 catch(
const std::exception&
e)
160 std::cerr<<
e.what()<<std::endl;