Mechanics of Defect Evolution Library
Loading...
Searching...
No Matches
testPhysicsBases.cpp
Go to the documentation of this file.
7#include <filesystem>
8#include <fstream>
9#include <iomanip>
10#include <chrono>
11
12void require(bool value,const char* message)
13{
14 if(!value)
15 {
16 throw std::runtime_error(message);
17 }
18}
19
20template<class Function>
21void mustFail(Function operation,const std::string& message)
22{
23 bool failed=false;
24 try
25 {
26 operation();
27 }
28 catch(const std::runtime_error& error)
29 {
30 failed=std::string(error.what()).find(message)!=std::string::npos;
31 }
32 require(failed,"Expected operation to fail with the specified diagnostic");
33}
34
35int main(int argc,char** argv)
36{
37 try
38 {
39 require(argc==2,"Expected repository root");
40 const std::filesystem::path root(argv[1]);
41 const auto folder=std::filesystem::temp_directory_path()/
42 ("physics-bases-"+std::to_string(std::chrono::steady_clock::now().time_since_epoch().count()));
43 const auto input=folder/"inputFiles";
44 std::filesystem::create_directories(input);
45 std::filesystem::create_directories(folder/"F");
46 std::filesystem::copy_file(root/"Library/Materials/W.txt",input/"W.txt");
47 std::filesystem::copy_file(root/"Library/Meshes/unitCube24.msh",input/"mesh.msh");
48 auto configure=[&](const std::string& physics,double length,const std::string& faces)
49 {
50 std::ofstream(input/"DefectiveCrystal.txt")
51 <<"physics="<<physics<<";\nuseFEM=0;\nNsteps=0;\nmaxResolveSteps=0;\ndtMax=1;\n"
52 <<"outputFrequency=1;\noutputBinary=0;\nstartAtTimeStep=0;\nperiodicImageSize=0 0 0;\nEwaldLengthFactor=0;\n";
53 std::ofstream(input/"polycrystal.txt")<<std::setprecision(17)
54 <<"materialFile=W.txt;\nmeshFile=mesh.msh;\nabsoluteTemperature=300;\nC2G1=1 0 0 0 1 0 0 0 1;\nF="
55 <<length<<" 0 0 0 "<<length<<" 0 0 0 "<<length<<";\nX0=0 0 0;\nperiodicFaceIDs="<<faces<<";\n";
56 };
57 configure("ElasticDeformation",123.456,"-1");
58 {
59 model::DefectiveCrystalBase<3> base(folder.string());
60 require(base.periodicLatticeBasis.cols()==3,"Expected periodic mesh");
61 require(!base.dislocationDynamicsBase && !base.clusterDynamicsBase && base.elasticDeformationBase,
62 "Active physics did not determine contexts");
63 require(base.hasPhysics("ELASTICDEFORMATION"),"Case-insensitive lookup failed");
64 require(&base.elasticDeformation()==base.elasticDeformationBase.get(),"Contexts are not shared");
65 mustFail([&](){base.dislocationDynamics();},"not enabled");
66 model::MicrostructureGenerator generator(base);
67 mustFail([&](){generator.addPrismaticLoopDensity(model::PrismaticLoopDensitySpecification());},"not enabled");
68 mustFail([&](){generator.insertNetworkNode(Eigen::Vector3d::Zero());},"not enabled");
69 require(generator.configIO.nodes().empty() && generator.configIO.loops().empty(),"Disabled DD mutated configuration");
71 mustFail([&](){model::DislocationNetwork<3> network(container);},"not enabled");
72 }
73 configure("DislocationDynamics",123.456,"-1");
74 mustFail([&](){model::DefectiveCrystalBase<3> base(folder.string());},"not a lattice vector");
75 configure("DislocationDynamics ElasticDeformation dislocationdynamics",200/std::sqrt(3.0),"-1");
76 std::shared_ptr<model::DislocationDynamicsBase<3>> context;
77 {
78 model::DefectiveCrystalBase<3> base(folder.string());
79 require(base.activePhysics.size()==2,"Duplicate physics activation");
80 require(base.dislocationDynamicsBase && base.elasticDeformationBase && !base.clusterDynamicsBase,"Incorrect mixed contexts");
81 model::MicrostructureGenerator generator(base);
83 require(&generator.ddBase.dislocationDynamics()==&container.ddBase.dislocationDynamics(),"Generator and physics use different contexts");
84 context=base.dislocationDynamicsBase;
85 }
86 // A retained context owns its mesh/material even after its common base dies.
87 const auto grain=context->polyOwner->grain(1);
88 const auto plane=context->glidePlaneFactory.getFromKey(model::GlidePlaneKey<3>(Eigen::Vector3d::Zero(),grain->reciprocalLatticeDirection(Eigen::Vector3d::UnitZ())));
89 require(bool(plane),"Context dependencies did not survive common-base destruction");
90 configure("none",123.456,"");
91 {
92 model::DefectiveCrystalBase<3> base(folder.string());
93 require(base.activePhysics.empty() && !base.dislocationDynamicsBase && !base.clusterDynamicsBase && !base.elasticDeformationBase,"Disabled contexts were constructed");
94 }
95 configure("typo",123.456,"");
96 mustFail([&](){model::DefectiveCrystalBase<3> base(folder.string());},"Unknown physics");
97 std::filesystem::remove_all(folder);
98 std::cout<<"PASS: active physics contexts, DD validation, generator guards, and context lifetime\n";
99 return 0;
100 }
101 catch(const std::exception& error)
102 {
103 std::cerr<<error.what()<<'\n';
104 return 1;
105 }
106}
LatticePlaneKey< dim > GlidePlaneKey
DislocationDynamicsBase< dim > & dislocationDynamics() const
DefectiveCrystalBase< dim > & ddBase
void require(bool value, const char *message)
void mustFail(Function operation, const std::string &message)
void argv
void b int argc