25 const std::filesystem::path root(
argv[1]);
26 const auto folder = std::filesystem::temp_directory_path() /
27 (
"periodic-fields-" + 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");
35 std::vector<int> seeds;
40 for(
const auto& face : region.second->faces())
42 const auto& pair = face.second->periodicFacePair;
43 if(pair.second && pair.first[
axis] > 0.9 &&
44 pair.first.normalized().cross(Eigen::Vector3d::Unit(
axis)).norm() < 1.e-8)
46 seeds.push_back(face.first);
51 require(seeds.size() == 3,
"Expected three cube periodic directions");
53 std::filesystem::copy_file(root /
"Library/DislocationDynamics/DD.txt", input /
"DD.txt");
54 const double length=200.0/std::sqrt(3.0);
55 for(
int activeAxis : {-1,2})
59 std::ofstream
f(input /
"DefectiveCrystal.txt");
60 f <<
"physics=DislocationDynamics;\nuseFEM=0;\nNsteps=0;\nmaxResolveSteps=0;\ndtMax=1;\n"
61 <<
"outputFrequency=1;\noutputBinary=0;\nstartAtTimeStep=0;\nperiodicImageSize=0;\nEwaldLengthFactor=0;\n";
62 std::ofstream
p(input /
"polycrystal.txt");
63 p << std::setprecision(17) <<
"materialFile=W.txt;\nmeshFile=mesh.msh;\nabsoluteTemperature=300;\n"
64 <<
"C2G1=1 0 0 0 1 0 0 0 1;\nF=" << length <<
" 0 0 0 " << length <<
" 0 0 0 " << length
65 <<
";\nX0=0 0 0;\nperiodicFaceIDs=";
68 p << seeds[activeAxis];
75 using V=Eigen::Vector3d;
77 const auto grain=base.poly.grain(1);
78 const auto plane=base.dislocationDynamics().glidePlaneFactory.getFromKey(
model::GlidePlaneKey<3>(V::Zero(),grain->reciprocalLatticeDirection(V::UnitZ())));
79 const V burgers=2.0/std::sqrt(3.0)*V::UnitX();
80 const std::array<V,4> positions{length*
V(-.8,-.8,0),length*
V(.8,-.8,0),length*
V(.8,.8,0),length*
V(-.8,.8,0)};
81 std::vector<std::shared_ptr<Network::NetworkNodeType>> owners;
82 for(
const auto&
p : positions)
86 std::vector<std::shared_ptr<Network::LoopType>> loops;
87 for(
size_t family=0;family<3;++family)
89 const auto loop=network.
loops().
create(burgers,plane);
90 loops.push_back(loop);
91 std::vector<std::shared_ptr<Network::LoopNodeType>> nodes;
92 for(
size_t k=0;
k<positions.size();++
k)
94 const size_t index=family==1 ? positions.size()-1-
k :
k;
96 nodes.push_back(network.
loopNodes().
create(loop,net,positions[
index],loop->periodicGlidePlane->getPatch(V::Zero()),
102 std::set<size_t> sharedIDs;
103 for(
const auto* link : loops[0]->linkSequence())
105 const auto segment=link->networkLink();
106 require(segment && segment->loopLinks().size()==2,
"Enclosure lost shared contour ownership");
107 require(segment->burgers().norm()<1.e-12,
"Opposite enclosed loops no longer cancel");
108 sharedIDs.insert(link->source->networkNode->sID);
110 require(sharedIDs.size()==4,
"Incorrect enclosed face contour");
111 for(
const auto* link : loops[2]->linkSequence())
113 require(!sharedIDs.count(link->source->networkNode->sID),
"Unrelated enclosing loop acquired junction sharing");
114 require(link->networkLink()->loopLinks().size()==1,
"Unrelated loop was merged");
118 const auto balanced=network.
loops().
create(burgers,plane);
119 std::vector<std::shared_ptr<Network::LoopNodeType>> balancedNodes;
120 const std::array<V,4> balancedPositions{length*
V(-.2,-.2,0),length*
V(.2,.2,0),length*
V(-.2,.2,0),length*
V(.2,-.2,0)};
121 for(
const V& position : balancedPositions)
124 balanced->periodicGlidePlane->getPatch(V::Zero()),
129 require(balanced->isLoop() && balanced->linkSequence().size()==4,
"Cancelling lobes were deleted during reconciliation");
132 require(network.
networkNodes().size()==nodeCount,
"Enclosed boundary update is not idempotent");
133 for(
const auto* link : loops[0]->linkSequence())
135 require(sharedIDs.count(link->source->networkNode->sID),
"Repeated update changed enclosed junction identity");
138 std::cout<<
"PASS: enclosure preserves shared ownership and separates unrelated loops\n";
140 catch(
const std::exception& error)
142 std::cerr<<error.what()<<std::endl;