Mechanics of Defect Evolution Library
Loading...
Searching...
No Matches
testJunctionLoopInsertion.cpp
Go to the documentation of this file.
6#include <filesystem>
7#include <fstream>
8#include <iomanip>
9#include <chrono>
10#include <iostream>
11#include <set>
12#include <array>
13#include <sstream>
14
15void require(bool condition, const char* message)
16{
17 if(!condition)
18 {
19 throw std::runtime_error(message);
20 }
21}
22
23int main(int argc, char** argv)
24{
25 try
26 {
27 require(argc == 2, "Expected repository root");
28 const std::filesystem::path root(argv[1]);
29 const auto folder = std::filesystem::temp_directory_path() /
30 ("junction-insertion-" + std::to_string(std::chrono::steady_clock::now().time_since_epoch().count()));
31 const auto input = folder / "inputFiles";
32 std::filesystem::create_directories(input);
33 std::filesystem::create_directories(folder / "F");
34 std::filesystem::copy_file(root / "Library/Materials/W.txt", input / "W.txt");
35
36 std::filesystem::copy_file(root / "Library/Meshes/bicrystal_48.msh", input / "mesh.msh");
37 std::filesystem::copy_file(root / "Library/DislocationDynamics/DD.txt", input / "DD.txt");
38 std::filesystem::create_directories(folder / "config");
39 model::SimplicialMesh<3> mesh((input/"mesh.msh").string(),Eigen::Matrix3d::Identity(),Eigen::Vector3d::Zero(),{-1});
40 std::array<int,3> seeds{-1,-1,-1};
41 for(const auto& region : mesh.regions())
42 {
43 for(const auto& face : region.second->faces())
44 {
45 const auto& pair=face.second->periodicFacePair;
46 if(pair.second)
47 {
48 for(int axis=0;axis<3;++axis)
49 {
50 if(pair.first.normalized().cross(Eigen::Vector3d::Unit(axis)).norm()<1.e-8)
51 {
52 seeds[axis]=face.first;
53 }
54 }
55 }
56 }
57 }
58 require(seeds[0]>=0 && seeds[1]>=0,"Missing periodic seeds");
59 model::StaticID<model::Polyhedron<3,3-1>>::force_count(0);
60 const double length=3671.9477120460206;
61 for(int scenario=0;scenario<3;++scenario)
62 {
63 const bool full=scenario==1;
64 const bool periodic=scenario<2;
65 {
66 std::ofstream f(input/"DefectiveCrystal.txt");
67 f<<"physics=DislocationDynamics;\nuseFEM=0;\nNsteps=0;\nmaxResolveSteps=0;\ndtMax=1;\noutputFrequency=1;\noutputBinary=0;\nstartAtTimeStep=0;\nperiodicImageSize="<<(full ? "0 0 0" : "0")<<";\nEwaldLengthFactor=0;\n";
68 std::ofstream p(input/"polycrystal.txt");
69 p<<std::setprecision(17)<<"materialFile=W.txt;\nmeshFile=mesh.msh;\nabsoluteTemperature=300;\nC2G1=1 0 0 0 1 0 0 0 1;\nC2G2=0.8 0 0.6 0 1 0 -0.6 0 0.8;\nF="<<length<<" 0 0 0 "<<length<<" 0 0 0 "<<length<<";\nX0=0 0 0;\nperiodicFaceIDs=";
70 if(periodic)
71 {
72 p<<(full ? -1 : seeds[1]);
73 }
74 p<<";\n";
75 }
76 model::DefectiveCrystalBase<3> base(folder.string());
79 using V=Eigen::Vector3d;
80 Network network(container);
81 const auto grain=base.poly.grain(1);
82 model::MicrostructureGenerator generator(base);
83 const V a=length*V(-0.5,0,0);
84 const V b=length*V(-0.5,periodic ? 0.7 : 0.3,0);
85 const V burgers=2.0/std::sqrt(3.0)*V::UnitY();
86 const auto insert=[&](const std::vector<V>& polygon,const V& normal)
87 {
88 const auto plane=base.dislocationDynamics().periodicGlidePlaneFactory.get(model::GlidePlaneKey<3>(polygon.front(),grain->reciprocalLatticeDirection(normal)));
89 return generator.insertJunctionLoop(polygon,plane,burgers,normal,polygon.front(),1,model::DislocationLoopIO<3>::GLISSILELOOP);
90 };
91 const auto snapshot=[&]()
92 {
93 std::ostringstream out;
94 out<<std::setprecision(17);
95 for(const auto& node : generator.config().nodes())
96 {
97 out<<node;
98 }
99 for(const auto& loop : generator.config().loops())
100 {
101 out<<loop;
102 }
103 for(const auto& node : generator.config().loopNodes())
104 {
105 out<<node;
106 }
107 for(const auto& link : generator.config().loopLinks())
108 {
109 out<<link;
110 }
111 for(const auto& entry : generator.uniqueNetworkNodeMap)
112 {
113 out<<entry.first.transpose()<<entry.second;
114 }
115 return out.str();
116 };
117 require(insert({a,b,length*V(-0.7,0.1,0)},V::UnitZ()),"Valid first loop rejected");
118 require(insert({a,b,length*V(-0.5,0.1,0.2)},V::UnitX()),"Shared junction loop rejected");
119 const auto before=snapshot();
120 // Internal GB, cross-grain periodic/physical back face, and a
121 // nonperiodic face (Z is inactive except in the full scenario).
122 require(!insert({a,length*V(0.1,0.1,0),length*V(-0.7,0.2,0)},V::UnitZ()),"Internal GB crossing accepted");
123 require(!insert({a,length*V(-1.1,0.1,0),length*V(-0.7,0.2,0)},V::UnitZ()),"Back-face crossing accepted");
124 if(!full)
125 {
126 require(!insert({a,length*V(-0.5,0.1,0.7),length*V(-0.5,0.2,0)},V::UnitX()),"Physical face crossing accepted");
127 }
128 require(before==snapshot(),"Rejected insertion changed configuration or sharing map");
129 network.initializeConfiguration(generator.config(),std::ofstream(),std::ofstream());
130 size_t shared=0;
131 size_t shifted=0;
132 for(const auto& entry : network.networkLinks())
133 {
134 const auto segment=entry.second.lock();
135 if(segment->loopLinks().size()==2)
136 {
137 ++shared;
138 require(segment->glidePlanes().size()==2,"Junction lost a contributing glide plane");
139 require((segment->burgers().norm()-2.0*burgers.norm())<1.e-8 && segment->burgers().norm()>burgers.norm(),"Junction Burgers sum changed");
140 }
141 for(const auto* plane : segment->glidePlanes())
142 {
143 require(segment->source->glidePlanes().count(plane) && segment->sink->glidePlanes().count(plane),"Endpoint missing junction plane");
144 }
145 }
146 for(const auto& node : generator.config().loopNodes())
147 {
148 shifted+=node.periodicShift.norm()>1.e-8;
149 }
150 require(shared>0,"No shared junction tested");
151 require((shifted>0)==periodic,"Same-grain periodic crossing not exercised");
152 }
153 std::filesystem::remove_all(folder);
154 std::cout<<"PASS: topology-based insertion and multi-plane junction sharing\n";
155 return 0;
156 }
157 catch(const std::exception& error)
158 {
159 std::cerr<<error.what()<<'\n';
160 return 1;
161 }
162}
Eigen::Vector3d V
void initializeConfiguration(const DefectiveCrystalConfigIO< dim > &configIO, const std::ofstream &f_file, const std::ofstream &F_labels) override
NetworkLinkContainerType & networkLinks()
A class template that implements a counter of the number of instances of Derived type that are create...
Definition StaticID.h:29
function int_R syms a b c u real f
Definition int_R.m:4
a
Definition int_R.m:14
b
Definition int_R.m:16
LatticePlaneKey< dim > GlidePlaneKey
int regions
Definition triangle.cpp:696
void periodic(const Trial &field, double relative=1.e-10)
model::DislocationNetwork< 3 > Network
void require(bool condition, const char *message)
void out
void argv
int axis
void b int argc
vertex p[3]