19 check(
argc == 2,
"Expected repository root");
20 const std::filesystem::path root(
argv[1]);
22 std::filesystem::temp_directory_path() /
23 (
"model-surface-" + std::to_string(std::chrono::steady_clock::now().time_since_epoch().count()));
24 for(
const auto *name : {
"inputFiles",
"config",
"F"})
26 std::filesystem::create_directories(dir / name);
28 const auto input = dir /
"inputFiles";
29 std::filesystem::copy_file(root /
"Library/Materials/W.txt", input /
"W.txt");
30 std::filesystem::copy_file(root /
"Library/Meshes/bicrystal_48.msh", input /
"mesh.msh");
32 std::ofstream
f(input /
"DefectiveCrystal.txt");
33 f <<
"physics=ElasticDeformation;\nuseFEM=0;\nNsteps=1;\nmaxResolveSteps=0;\ndtMax=1;\n"
34 <<
"outputFrequency=1;\noutputBinary=0;\nstartAtTimeStep=0;\n";
35 std::ofstream
p(input /
"polycrystal.txt");
36 p <<
"materialFile=W.txt;\nmeshFile=mesh.msh;\nabsoluteTemperature=300;\n"
37 <<
"C2G1=1 0 0 0 1 0 0 0 1;\nC2G2=0.8 0 0.6 0 1 0 -0.6 0 0.8;\nF=100 0 0 0 100 0 0 0 100;\nX0=0 0 0;\nperiodicFaceIDs=;\n";
38 std::ofstream
e(input /
"ElasticDeformation.txt");
39 e <<
"useElasticDeformationFEM=0;\ninertiaReliefPenaltyFactor=1e-3;\n"
40 <<
"ExternalStress0=0 0 .01 0 0 0;\nExternalStressRate=0 0 .01 0 0 0;\n"
41 <<
"ExternalStrain0=0 0 0 0 0 0;\nExternalStrainRate=0 0 0 0 0 0;\n"
42 <<
"stiffnessRatio=0 0 0 0 0 0;\n";
47 std::set<size_t> externalIDs,internalIDs;
48 std::set<const model::Simplex<3,2>*> internalTriangles;
49 for(
const auto& region : base.mesh.regions())
51 for(
const auto& entry : region.second->faces())
53 const auto& face=*entry.second;
56 externalIDs.insert(face.sID);
60 internalIDs.insert(face.sID);
61 internalTriangles.insert(face.simplices().begin(),face.simplices().end());
65 check(!internalIDs.empty(),
"Bicrystal has no internal faces");
68 for(
size_t i=0;
i<inside.triangles.size();++
i)
70 const auto&
t=inside.triangles[
i];
71 const Eigen::Vector3d cross=(inside.referencePoints[
t[1]]-inside.referencePoints[
t[0]])
72 .cross(inside.referencePoints[
t[2]]-inside.referencePoints[
t[0]]);
73 const auto* face=inside.boundaryFaces[
i];
74 check(internalTriangles.count(face),
"Internal selection included external face");
76 area+=0.5*cross.norm();
79 for(
const auto* face : internalTriangles)
83 check(std::abs(
area-expected)<1.e-8,
"Internal faces duplicated or lost during refinement");
85 const auto cut=inside.split({trace});
86 check(!cut.walls.empty(),
"Internal interface did not acquire slip-step walls");
87 std::set<size_t> all=externalIDs;
88 all.insert(internalIDs.begin(),internalIDs.end());
91 check(both.triangles.size()==outside.triangles.size()+internalTriangles.size(),
"Combined faces duplicated interfaces");
96 auto window=vtkSmartPointer<vtkGenericOpenGLRenderWindow>::New();
97 window->SetReadyForRendering(
false);
98 auto renderer=vtkSmartPointer<vtkRenderer>::New();
99 window->AddRenderer(renderer);
102 for(
const auto id : externalIDs)
104 auto* item=surface.findChild<QCheckBox*>(QString(
"surfaceExternalFace_%1").arg(
id));
105 check(item && !item->isChecked(),
"External face selected by default");
107 for(
const auto id : internalIDs)
109 auto* item=surface.findChild<QCheckBox*>(QString(
"surfaceInternalFace_%1").arg(
id));
110 check(item && !item->isChecked(),
"Internal face selected by default");
112 check(surface.findChildren<QCheckBox*>(QRegularExpression(
"surfaceInternalFace_.*")).size()==
static_cast<int>(internalIDs.size()),
113 "Internal face appears twice in UI");
118 check(surface.
polyData->GetNumberOfCells()==0,
"Disabled groups rendered selected faces");
120 check(surface.
polyData->GetNumberOfCells()==
static_cast<vtkIdType
>(internalTriangles.size()),
"Internal face selection did not render");
121 for(
const auto id : internalIDs)
123 auto* item=surface.findChild<QCheckBox*>(QString(
"surfaceInternalFace_%1").arg(
id));
124 check(item->isChecked(),
"Enabling internal group did not select all faces");
125 item->setChecked(
false);
127 check(surface.
polyData->GetNumberOfCells()==0,
"Individual deselection did not hide internal faces");
130 check(surface.
polyData->GetNumberOfCells()==0,
"Re-enabling internal group lost the empty selection");
131 for(
const auto id : internalIDs)
133 auto* item=surface.findChild<QCheckBox*>(QString(
"surfaceInternalFace_%1").arg(
id));
134 check(!item->isChecked(),
"Internal checkbox selection was reset");
135 item->setChecked(
true);
138 surface.
polyData->GetPoint(0,oldPoint);
139 base.simulationParameters.totalTime+=1.0;
142 surface.
polyData->GetPoint(0,newPoint);
143 check((Eigen::Map<Eigen::Vector3d>(oldPoint)-Eigen::Map<Eigen::Vector3d>(newPoint)).norm()>1.e-10,
144 "Internal displacement did not update with frame physics");
146 check(surface.
polyData->GetNumberOfCells()==0,
"Hidden internal faces left stale geometry");
148 check(surface.
polyData->GetNumberOfCells()==
static_cast<vtkIdType
>(internalTriangles.size()),
"Internal group did not restore selected faces");
150 std::filesystem::remove_all(dir);
153 catch(
const std::exception&
e)
155 std::cerr<<
e.what()<<std::endl;