Mechanics of Defect Evolution Library
Loading...
Searching...
No Matches
testSurfaceInternalFaces.cpp
Go to the documentation of this file.
1#include <SurfaceMeshActor.h>
2#include <QApplication>
3#include <filesystem>
4#include <fstream>
5#include <chrono>
6#include <iostream>
7void check(bool condition,const char* message)
8{
9 if(!condition)
10 {
11 throw std::runtime_error(message);
12 }
13}
14int main(int argc,char** argv)
15{
16 QApplication app(argc,argv);
17 try
18 {
19 check(argc == 2, "Expected repository root");
20 const std::filesystem::path root(argv[1]);
21 const auto dir =
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"})
25 {
26 std::filesystem::create_directories(dir / name);
27 }
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");
31 {
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";
43 }
44
45 {
46 model::DefectiveCrystalBase<3> base(dir.string());
47 std::set<size_t> externalIDs,internalIDs;
48 std::set<const model::Simplex<3,2>*> internalTriangles;
49 for(const auto& region : base.mesh.regions())
50 {
51 for(const auto& entry : region.second->faces())
52 {
53 const auto& face=*entry.second;
54 if(face.isExternal())
55 {
56 externalIDs.insert(face.sID);
57 }
58 else
59 {
60 internalIDs.insert(face.sID);
61 internalTriangles.insert(face.simplices().begin(),face.simplices().end());
62 }
63 }
64 }
65 check(!internalIDs.empty(),"Bicrystal has no internal faces");
66 const auto inside=model::SurfaceMeshGeometry::build(base.mesh,625,internalIDs);
67 double area=0;
68 for(size_t i=0;i<inside.triangles.size();++i)
69 {
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");
75 check(cross.dot(face->outNormal(model::SurfaceMeshGeometry::samplingParent(face)->region->regionID))>0,"Internal orientation invalid");
76 area+=0.5*cross.norm();
77 }
78 double expected=0;
79 for(const auto* face : internalTriangles)
80 {
81 expected+=face->vol0;
82 }
83 check(std::abs(area-expected)<1.e-8,"Internal faces duplicated or lost during refinement");
84 model::SurfaceMeshGeometry::Trace trace{Eigen::Vector3d::Zero(),Eigen::Vector3d::UnitY(),internalTriangles};
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());
89 const auto both=model::SurfaceMeshGeometry::build(base.mesh,1.e20,all);
90 const auto outside=model::SurfaceMeshGeometry::build(base.mesh,1.e20,externalIDs);
91 check(both.triangles.size()==outside.triangles.size()+internalTriangles.size(),"Combined faces duplicated interfaces");
92 check(model::SurfaceMeshGeometry::build(base.mesh,625,{}).triangles.empty(),"Empty selection rendered faces");
93 model::DefectiveCrystal<3> crystal(base);
94 model::DefectiveCrystalConfigIO<3> config((dir/"config").string());
95 crystal.initializeConfiguration(config);
96 auto window=vtkSmartPointer<vtkGenericOpenGLRenderWindow>::New();
97 window->SetReadyForRendering(false);
98 auto renderer=vtkSmartPointer<vtkRenderer>::New();
99 window->AddRenderer(renderer);
100 model::SurfaceMeshActor surface(window,renderer,crystal);
101 check(!surface.externalFaces->isChecked() && !surface.internalFaces->isChecked(),"Incorrect group defaults");
102 for(const auto id : externalIDs)
103 {
104 auto* item=surface.findChild<QCheckBox*>(QString("surfaceExternalFace_%1").arg(id));
105 check(item && !item->isChecked(),"External face selected by default");
106 }
107 for(const auto id : internalIDs)
108 {
109 auto* item=surface.findChild<QCheckBox*>(QString("surfaceInternalFace_%1").arg(id));
110 check(item && !item->isChecked(),"Internal face selected by default");
111 }
112 check(surface.findChildren<QCheckBox*>(QRegularExpression("surfaceInternalFace_.*")).size()==static_cast<int>(internalIDs.size()),
113 "Internal face appears twice in UI");
114 surface.meshSizeEdit->setText("1e20");
115 surface.externalFaces->setChecked(false);
116 surface.updateConfiguration();
117 surface.showSurface->setChecked(true);
118 check(surface.polyData->GetNumberOfCells()==0,"Disabled groups rendered selected faces");
119 surface.internalFaces->setChecked(true);
120 check(surface.polyData->GetNumberOfCells()==static_cast<vtkIdType>(internalTriangles.size()),"Internal face selection did not render");
121 for(const auto id : internalIDs)
122 {
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);
126 }
127 check(surface.polyData->GetNumberOfCells()==0,"Individual deselection did not hide internal faces");
128 surface.internalFaces->setChecked(false);
129 surface.internalFaces->setChecked(true);
130 check(surface.polyData->GetNumberOfCells()==0,"Re-enabling internal group lost the empty selection");
131 for(const auto id : internalIDs)
132 {
133 auto* item=surface.findChild<QCheckBox*>(QString("surfaceInternalFace_%1").arg(id));
134 check(!item->isChecked(),"Internal checkbox selection was reset");
135 item->setChecked(true);
136 }
137 double oldPoint[3];
138 surface.polyData->GetPoint(0,oldPoint);
139 base.simulationParameters.totalTime+=1.0;
140 surface.updateConfiguration();
141 double newPoint[3];
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");
145 surface.internalFaces->setChecked(false);
146 check(surface.polyData->GetNumberOfCells()==0,"Hidden internal faces left stale geometry");
147 surface.internalFaces->setChecked(true);
148 check(surface.polyData->GetNumberOfCells()==static_cast<vtkIdType>(internalTriangles.size()),"Internal group did not restore selected faces");
149 }
150 std::filesystem::remove_all(dir);
151 return 0;
152 }
153 catch(const std::exception& e)
154 {
155 std::cerr<<e.what()<<std::endl;
156 return 1;
157 }
158}
void initializeConfiguration(const DefectiveCrystalConfigIO< dim > &configIO)
const vtkSmartPointer< vtkPolyData > polyData
QGroupBox *const externalFaces
QGroupBox *const internalFaces
QCheckBox *const showSurface
QLineEdit *const meshSizeEdit
final point of the source segment t
function int_R syms a b c u real f
Definition int_R.m:4
static SurfaceMeshGeometry build(const SimplicialMesh< 3 > &mesh, double maxArea)
static const Simplex< 3, 3 > * samplingParent(const Simplex< 3, 2 > *face)
void check(bool condition, const char *message)
void argv
void b int argc
vertex p[3]
int i
int e
REAL area