Mechanics of Defect Evolution Library
Loading...
Searching...
No Matches
testBicrystalPrismaticGlide.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
33 std::filesystem::copy_file(root / "Library/Meshes/bicrystal_48.msh", input / "mesh.msh");
34 std::filesystem::copy_file(root / "Library/DislocationDynamics/DD.txt", input / "DD.txt");
35 std::filesystem::create_directories(folder / "config");
36 const double length=3671.9477120460206;
37 {
38 std::ofstream f(input / "DefectiveCrystal.txt");
39 f << "physics=DislocationDynamics;\nuseFEM=0;\nNsteps=0;\nmaxResolveSteps=0;\ndtMax=1;\noutputFrequency=1;\noutputBinary=0;\nstartAtTimeStep=0;\nperiodicImageSize=0 0 0;\nEwaldLengthFactor=0;\n";
40 std::ofstream p(input / "polycrystal.txt");
41 p << std::setprecision(17) << "materialFile=W.txt;\nmeshFile=mesh.msh;\nabsoluteTemperature=300;\nC2G1=1 0 0 0 1 0 0 0 1;\n"
42 << "C2G2=0.8 0 0.6 0 1 0 -0.6 0 0.8;\nF=" << length << " 0 0 0 " << length << " 0 0 0 " << length
43 << ";\nX0=0 0 0;\nperiodicFaceIDs=-1;\n";
44 }
45 model::DefectiveCrystalBase<3> base(folder.string());
46 model::MicrostructureGenerator generator(base);
48 spec.slipSystemIDs={0};
49 spec.loopRadii={1.e-7};
50 spec.glideSteps={50};
51 spec.loopCenters.resize(1,3);
52 spec.loopCenters << -0.5*length,0,0;
53 generator.addPrismaticLoopIndividual(spec);
54 require(generator.config().loops().size()==7,"Expected complete prismatic construction");
56 model::DislocationNetwork<3> network(container);
57 network.initializeConfiguration(generator.config(),std::ofstream(),std::ofstream());
58 network.alphaLineTension=1.0;
59 require(!network.stochasticForceGenerator,"Regression requires deterministic mobility");
60 using V=Eigen::Vector3d;
61 size_t checked=0;
62 double maxRawTangential=0;
63 for(const auto& entry : network.networkLinks())
64 {
65 const auto segment=entry.second.lock();
66 segment->createQuadraturePoints(false);
67 segment->updateQuadraturePoints(false);
68 if(!segment->slipSystem())
69 {
70 continue;
71 }
72 const V normal=segment->slipSystem()->unitNormal;
73 for(auto& point : segment->quadraturePoints())
74 {
75 ++checked;
76 const V glide=normal.cross(point.rl).normalized();
77 const V raw=point.lineTensionForce;
78 maxRawTangential=std::max(maxRawTangential,std::abs(raw.dot(point.rl)));
79 require(std::abs(point.pkForce.dot(glide))<1.e-9,"Initial prism has unexpected PK glide force");
80 require(std::abs(raw.dot(glide))<1.e-9,"Initial prism has unexpected LT glide force");
81 require(point.velocity.norm()<1.e-12,"Unloaded bicrystal prism has spurious glide velocity");
82 // Confirm raw line tension still equals energy times spline curvature.
83 V expected=V::Zero();
84 for(const auto* link : segment->loopLinks())
85 {
86 const double u=link->source->networkNode==segment->source ? point.abscissa : 1-point.abscissa;
87 const V curvature=link->spline().get_rll(u);
88 if(!std::isnan(curvature.squaredNorm()))
89 {
90 expected+=point.coreEnergyPerLength*curvature;
91 }
92 }
93 require((raw-expected).norm()<1.e-12,"Raw line tension was altered");
94 const auto initialStress=point.internalStress;
95 // Apply an actual shear stress producing a specified PK glide force.
96 const auto drive=point.forceToStress(1.e-3*glide,point.rl,*segment);
97 point.internalStress=initialStress+drive;
98 point.updateForcesAndVelocities(*segment,false);
99 const V positive=point.velocity;
100 require(positive.norm()>1.e-8 && positive.dot(glide)>0,"Positive glide force gives no forward response");
101 require(std::abs(positive.dot(point.rl))<1.e-12 && std::abs(positive.dot(normal))<1.e-12,
102 "Driven velocity is not along the permitted glide direction");
103 require((point.lineTensionForce-raw).norm()<1.e-12,"Velocity update modified raw line tension");
104 // Unresolved line tension must change neither speed nor direction.
105 point.lineTensionForce.setZero();
106 point.updateForcesAndVelocities(*segment,false);
107 require((point.velocity-positive).norm()<1.e-9,"Climb/tangential LT changes driven mobility");
108 point.lineTensionForce=raw;
109 point.internalStress=initialStress-drive;
110 point.updateForcesAndVelocities(*segment,false);
111 require(point.velocity.norm()>1.e-8 && point.velocity.dot(glide)<0,"Negative glide force gives no reverse response");
112 require(std::abs(point.velocity.dot(point.rl))<1.e-12,"Reverse velocity is tangential");
113 point.internalStress=initialStress;
114 point.updateForcesAndVelocities(*segment,false);
115 }
116 }
117 require(checked>0,"No quadrature velocities tested");
118 require(maxRawTangential>1.e-6,"Test did not reproduce a finite tangential LT component");
119 std::filesystem::remove_all(folder);
120 std::cout << "PASS: " << checked << " bicrystal prism quadrature points, unloaded and driven, raw LT unchanged\n";
121 return 0;
122 }
123 catch(const std::exception& error)
124 {
125 std::cerr << error.what() << '\n';
126 return 1;
127 }
128}
Eigen::Vector3d V
std::shared_ptr< StochasticForceGenerator > stochasticForceGenerator
void initializeConfiguration(const DefectiveCrystalConfigIO< dim > &configIO, const std::ofstream &f_file, const std::ofstream &F_labels) override
NetworkLinkContainerType & networkLinks()
function int_R syms a b c u real f
Definition int_R.m:4
void require(bool condition, const char *message)
void argv
REAL u[4]
void b int argc
vertex p[3]