Mechanics of Defect Evolution Library
Loading...
Searching...
No Matches
testJunctionSpline.cpp
Go to the documentation of this file.
5#include <filesystem>
6#include <fstream>
7#include <iomanip>
8#include <chrono>
9#include <iostream>
10#include <set>
11
12void require(bool condition, const char* message)
13{
14 if(!condition)
15 {
16 throw std::runtime_error(message);
17 }
18}
19
20int main(int argc, char** argv)
21{
22 try
23 {
24 require(argc == 2, "Expected repository root");
25 const std::filesystem::path root(argv[1]);
26 const auto folder = std::filesystem::temp_directory_path() /
27 ("node-motion-" + 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");
34 model::SimplicialMesh<3> mesh(meshFile.string(), Eigen::Matrix3d::Identity(), Eigen::Vector3d::Zero(), {-1});
35 std::vector<int> seeds;
36 for(int axis = 0; axis < 3; ++axis)
37 {
38 for(const auto& region : mesh.regions())
39 {
40 for(const auto& face : region.second->faces())
41 {
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)
45 {
46 seeds.push_back(face.first);
47 }
48 }
49 }
50 }
51 require(seeds.size() == 3, "Expected three cube periodic directions");
52 model::StaticID<model::Polyhedron<3,3-1>>::force_count(0);
53
54 std::filesystem::copy_file(root / "Library/DislocationDynamics/DD.txt", input / "DD.txt");
55 const double length=200.0/std::sqrt(3.0);
56 for(int scenario=0;scenario<5;++scenario)
57 {
58 {
59 std::ofstream f(input / "DefectiveCrystal.txt");
60 f << "physics=DislocationDynamics;\nuseFEM=0;\nNsteps=0;\nmaxResolveSteps=0;\ndtMax=1;\noutputFrequency=1;\noutputBinary=0;\nstartAtTimeStep=0;\nperiodicImageSize=0;\nEwaldLengthFactor=0;\n";
61 std::ofstream p(input / "polycrystal.txt");
62 p << "materialFile=W.txt;\nmeshFile=mesh.msh;\nabsoluteTemperature=300;\nC2G1=1 0 0 0 1 0 0 0 1;\nF=" << std::setprecision(17) << length << " 0 0 0 " << length << " 0 0 0 " << length << ";\nX0=0 0 0;\nperiodicFaceIDs=";
63 if(scenario==3)
64 {
65 p << seeds[0];
66 }
67 p << ";\n";
68 }
69 model::DefectiveCrystalBase<3> base(folder.string());
72 using V=Eigen::Vector3d;
73 Network network(container);
74 const auto grain=base.poly.grain(1);
75 const auto plane=base.dislocationDynamics().glidePlaneFactory.getFromKey(model::GlidePlaneKey<3>(V::Zero(),grain->reciprocalLatticeDirection(V::UnitZ())));
76 const V burgers=2.0/std::sqrt(3.0)*V::UnitX();
77 const auto first=network.loops().create(burgers,plane);
78 const auto second=network.loops().create(scenario==1 ? V(-burgers) : scenario==2 ? V(2*burgers) : burgers,plane);
79 const auto a=network.networkNodes().create(V(0,0,0));
80 const auto b=network.networkNodes().create(V(20,0,0));
81 const auto c=network.networkNodes().create(V(0,20,0));
82 const auto d=network.networkNodes().create(V(-20,0,0));
83 const auto e=network.networkNodes().create(V(40,0,0));
84 const auto makeNode=[&](const auto& loop,const auto& net)
85 {
86 const V offset=(scenario==3 && loop==second) ? V(length,0,0) : V::Zero();
87 return network.loopNodes().create(loop,net,V(net->get_P()+offset),loop->periodicGlidePlane->getPatch(-offset),
88 std::make_pair(std::shared_ptr<model::PeriodicPlaneEdge<3>>(),std::shared_ptr<model::PeriodicPlaneEdge<3>>()));
89 };
90 if(scenario==4)
91 {
92 network.insertLoop(first,std::vector<std::shared_ptr<Network::LoopNodeType>>{
93 makeNode(first,c),makeNode(first,a),makeNode(first,b),makeNode(first,c),
94 makeNode(first,b),makeNode(first,e),makeNode(first,d),makeNode(first,a)});
95 }
96 else
97 {
98 network.insertLoop(first,std::vector<std::shared_ptr<Network::LoopNodeType>>{makeNode(first,c),makeNode(first,a),makeNode(first,b)});
99 }
100 // Opposite orientation with equal Burgers, or equal orientation
101 // with opposite Burgers, both cancel the artificial CA and BC links.
102 if(scenario==1)
103 {
104 network.insertLoop(second,std::vector<std::shared_ptr<Network::LoopNodeType>>{
105 makeNode(second,c),makeNode(second,a),makeNode(second,d),makeNode(second,e),makeNode(second,b)});
106 }
107 else if(scenario!=4)
108 {
109 network.insertLoop(second,std::vector<std::shared_ptr<Network::LoopNodeType>>{
110 makeNode(second,a),makeNode(second,c),makeNode(second,b),makeNode(second,e),makeNode(second,d)});
111 }
112 const Network::LoopLinkType* link=nullptr;
113 for(const auto* candidate : first->linkSequence())
114 {
115 if(candidate->source->networkNode==a && candidate->sink->networkNode==b)
116 {
117 link=candidate;
118 }
119 }
120 require(link!=nullptr,"Missing tested segment");
121 const auto actual=link->spline();
122 if(scenario==0)
123 {
124 // Reproduce the old loop-local choice: it bends a physically
125 // straight segment toward the cancelling construction edges.
126 const model::CatmullRomSplineSegment<3> oldSpline(c->get_P(),a->get_P(),b->get_P(),c->get_P());
127 require(oldSpline.get_rll(0.5).norm()>1.e-3,"Regression geometry does not expose the old curvature error");
128 }
130 scenario==2 ? c->get_P() : d->get_P(),a->get_P(),b->get_P(),scenario==2 ? c->get_P() : e->get_P());
131 for(double u : {0.1,0.5,0.9})
132 {
133 require((actual.get_rl(u)-expected.get_rl(u)).norm()<1.e-10,"Wrong junction spline tangent");
134 require((actual.get_rll(u)-expected.get_rll(u)).norm()<1.e-10,"Wrong junction spline curvature");
135 if(scenario!=2)
136 {
137 require(actual.get_rll(u).norm()<1.e-10,"Artificial loop closure produces line tension on a straight segment");
138 }
139 }
140 }
141 std::filesystem::remove_all(folder);
142 std::cout << "PASS: cancelling junction continuation, reversed Burgers and genuine junction preservation\n";
143 return 0;
144 }
145 catch(const std::exception& error)
146 {
147 std::cerr << error.what() << '\n';
148 return 1;
149 }
150}
Eigen::Vector3d V
TraitsType::LoopLinkType LoopLinkType
const LoopContainerType & loops() const
Definition LoopNetwork.h:98
const NetworkNodeContainerType & networkNodes() const
const LoopNodeContainerType & loopNodes() const
void insertLoop(const std::shared_ptr< LoopType > &loop, const std::vector< std::shared_ptr< LoopNodeType > > nodes)
VectorDim get_rl(const double &u) const
VectorDim get_rll(const double &u) const
A class template that implements a counter of the number of instances of Derived type that are create...
Definition StaticID.h:29
c
Definition int_R.m:15
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
SharedPtrType create(const Args &...args)
model::DislocationNetwork< 3 > Network
void require(bool condition, const char *message)
void argv
REAL u[4]
int axis
void b int argc
vertex p[3]
int e
vertex first