Mechanics of Defect Evolution Library
Loading...
Searching...
No Matches
testBoundaryJunctionFormation.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
14void require(bool condition, const char* message)
15{
16 if(!condition)
17 {
18 throw std::runtime_error(message);
19 }
20}
21
22int main(int argc, char** argv)
23{
24 try
25 {
26 require(argc == 2, "Expected repository root");
27 const std::filesystem::path root(argv[1]);
28 const auto folder = std::filesystem::temp_directory_path() /
29 ("boundary-junction-" + 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");
34
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 model::SimplicialMesh<3> mesh((input/"mesh.msh").string(),Eigen::Matrix3d::Identity(),Eigen::Vector3d::Zero(),{-1});
39 std::array<int,3> seeds{-1,-1,-1};
40 for(const auto& region : mesh.regions())
41 {
42 for(const auto& face : region.second->faces())
43 {
44 const auto& pair=face.second->periodicFacePair;
45 if(pair.second)
46 {
47 for(int axis=0;axis<3;++axis)
48 {
49 if(pair.first.normalized().cross(Eigen::Vector3d::Unit(axis)).norm()<1.e-8)
50 {
51 seeds[axis]=face.first;
52 }
53 }
54 }
55 }
56 }
57 require(seeds[0]>=0 && seeds[1]>=0,"Missing periodic seeds");
58 model::StaticID<model::Polyhedron<3,3-1>>::force_count(0);
59 const double length=3671.9477120460206;
60 for(int scenario=0;scenario<6;++scenario)
61 {
62 const bool full=scenario==1 || scenario==2;
63 {
64 std::ofstream f(input/"DefectiveCrystal.txt");
65 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";
66 std::ofstream p(input/"polycrystal.txt");
67 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="<<(full ? -1 : seeds[scenario==0 || scenario==5 ? 1 : 0])<<";\n";
68 }
69 model::DefectiveCrystalBase<3> base(folder.string());
70 require(base.periodicLatticeBasis.cols()==(full ? 3 : 1),"Incorrect active periodic rank");
73 using V=Eigen::Vector3d;
74 Network network(container);
75 const auto grain=base.poly.grain(1);
76 const auto plane=base.dislocationDynamics().glidePlaneFactory.getFromKey(model::GlidePlaneKey<3>(V::Zero(),grain->reciprocalLatticeDirection(V::UnitZ())));
77 const V burgers=2.0/std::sqrt(3.0)*V::UnitX();
78 const bool yFace=scenario>=4;
79 const double xFace=scenario>=2 ? -1.0 : 0.0;
80 const V p0=length*(yFace ? V(-0.7,0.5,0) : V(xFace,-0.2,0));
81 const V p1=length*(yFace ? V(-0.3,0.5,0) : V(xFace,0.2,0));
82 std::vector<std::shared_ptr<Network::LoopType>> loops;
83 for(int k=0;k<2;++k)
84 {
85 const auto loop=network.loops().create(burgers,plane);
86 loops.push_back(loop);
87 const V apex=length*(yFace ? V(-0.5,0.1+0.1*k,0) : V(-0.4-0.1*k,0,0));
88 std::vector<std::shared_ptr<Network::LoopNodeType>> ring;
89 for(const auto& pos : {p0,p1,apex})
90 {
91 const auto node=network.networkNodes().create(pos);
92 ring.push_back(network.loopNodes().create(loop,node,pos,loop->periodicGlidePlane->getPatch(V::Zero()),
93 std::make_pair(std::shared_ptr<model::PeriodicPlaneEdge<3>>(),std::shared_ptr<model::PeriodicPlaneEdge<3>>())));
94 }
95 network.insertLoop(loop,ring);
96 }
97 network.updateBoundaryNodes();
98 network.updateGeometry();
99 const auto sharedLength=[&]()
100 {
101 double result=0;
102 for(const auto& entry : network.networkLinks())
103 {
104 const auto link=entry.second.lock();
105 if(link->loopLinks().size()==2)
106 {
107 result+=link->chord().norm();
108 require(std::abs(link->burgers().norm()-2*burgers.norm())<1.e-8,"Junction Burgers sum changed");
109 }
110 }
111 return result;
112 };
113 require(sharedLength()==0,"Fixture already contains shared segments");
114 // Each pass can join one endpoint of initially disconnected overlaps.
115 network.junctionsMaker.formJunctions(0.0);
116 network.junctionsMaker.formJunctions(0.0);
117 network.updateGeometry();
118 const double joined=sharedLength();
119 if(scenario==5)
120 {
121 require(joined<1.e-8,"Same-grain periodic seam received physical-boundary junction rule");
122 }
123 else
124 {
125 require(std::abs(joined-(p1-p0).norm())<1.e-7,"Physical/GB overlap did not become a shared junction");
126 }
127 for(const auto& loop : loops)
128 {
129 require(loop->isLoop(),"Junction formation broke loop closure");
130 for(const auto* link : loop->linkSequence())
131 {
132 const auto node=link->source;
133 require((node->get_P()+node->periodicPlanePatch()->shift-node->networkNode->get_P()).norm()<1.e-7,
134 "Junction formation broke periodic mapping");
135 }
136 }
137 }
138 std::filesystem::remove_all(folder);
139 std::cout<<"PASS: internal, periodic GB, physical-face and same-grain seam junctions\n";
140 return 0;
141 }
142 catch(const std::exception& error)
143 {
144 std::cerr<<error.what()<<'\n';
145 return 1;
146 }
147}
Eigen::Vector3d V
void updateBoundaryNodes(const std::function< void()> &checkpoint={})
DislocationJunctionFormation< dim > junctionsMaker
const LoopContainerType & loops() const
Definition LoopNetwork.h:98
const NetworkNodeContainerType & networkNodes() const
const LoopNodeContainerType & loopNodes() const
NetworkLinkContainerType & networkLinks()
void insertLoop(const std::shared_ptr< LoopType > &loop, const std::vector< std::shared_ptr< LoopNodeType > > nodes)
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
LatticePlaneKey< dim > GlidePlaneKey
int regions
Definition triangle.cpp:696
SharedPtrType create(const Args &...args)
void require(bool condition, const char *message)
model::DislocationNetwork< 3 > Network
void argv
vertex p1
int axis
void b int argc
vertex p[3]
int k
result
apex(top, farvertex)