34 auto window=vtkSmartPointer<vtkGenericOpenGLRenderWindow>::New();
35 window->SetReadyForRendering(
false);
36 auto renderer=vtkSmartPointer<vtkRenderer>::New();
37 window->AddRenderer(renderer);
39 const int loopStart=renderer->GetActors()->GetNumberOfItems();
43 const auto nodeCount=network->networkNodes().size();
44 const auto loopNodeCount=network->loopNodes().size();
45 std::map<std::pair<size_t,size_t>,std::set<size_t>> sharing;
46 auto points=vtkSmartPointer<vtkPoints>::New();
47 for(
const auto& entry : network->networkNodes())
49 points->InsertNextPoint(entry.second.lock()->get_P().data());
51 auto input=vtkSmartPointer<vtkPolyData>::New();
52 input->SetPoints(points);
53 for(
const auto& entry : network->networkLinks())
55 for(
const auto* ll : entry.second.lock()->loopLinks())
57 sharing[entry.first].insert(ll->loop->sID);
63 vtkIdType counts[3]={0,0,0};
64 for(
int group=0;group<3;++group)
66 auto* actor=vtkActor::SafeDownCast(renderer->GetActors()->GetItemAsObject(group));
67 auto* tube=vtkTubeFilter::SafeDownCast(actor->GetMapper()->GetInputAlgorithm());
68 require(tube,
"Missing segment tube filter");
69 data[group]=vtkPolyData::SafeDownCast(tube->GetInputDataObject(0,0));
70 require(data[group] && data[group]->GetPoints()==points,
"Segment points changed");
71 data[group]->GetLines()->InitTraversal();
73 for(
const auto& entry : network->networkLinks())
75 const auto link=entry.second.lock();
76 const int group=link->hasZeroBurgers()?2:((link->isBoundarySegment() || link->isGrainBoundarySegment())?1:0);
77 checkLine(data[group],counts[group],link->source->networkID(),link->sink->networkID());
80 const auto expected=links.
computeColor(link->burgers(),link->chord(),link->slipSystem(),{});
81 auto* colors=group==0?data[group]->GetCellData()->GetArray(
"Colors"):data[group]->GetCellData()->GetScalars();
82 require(colors,
"Missing segment colors");
85 require(colors->GetComponent(counts[group],
k)==
static_cast<unsigned char>(expected(
k)),
"Segment color changed");
88 std::set<size_t> memberships;
89 for(
const auto* ll : link->loopLinks())
91 memberships.insert(ll->loop->sID);
93 require(memberships==sharing.at(entry.first),
"Actor update changed junction sharing");
96 for(
int group=0;group<3;++group)
98 require(counts[group]==data[group]->GetNumberOfLines(),
"Segment count changed");
100 auto* loopActor=vtkActor::SafeDownCast(renderer->GetActors()->GetItemAsObject(loopStart+1));
101 auto* loopData=vtkPolyData::SafeDownCast(loopActor->GetMapper()->GetInputDataObject(0,0));
102 require(loopData && loopData->GetNumberOfPoints()==
static_cast<vtkIdType
>(loopNodeCount),
"Loop occurrences were merged");
103 require(loopData->GetNumberOfLines()==
static_cast<vtkIdType
>(network->loopLinks().size()),
"Loop line count changed");
104 loopData->GetLines()->InitTraversal();
106 for(
const auto& entry : network->loopLinks())
108 checkLine(loopData,
i++,entry.second.source->networkID(),entry.second.sink->networkID());
110 for(
const auto& entry : network->loopNodes())
112 const auto node=entry.second.lock();
114 loopData->GetPoint(node->networkID(),xyz);
117 require(xyz[
k]==
static_cast<float>(node->get_P()(
k)),
"Loop point position changed");
120 require(network->networkNodes().size()==nodeCount && network->loopNodes().size()==loopNodeCount,
121 "Actor update changed topology");
126 std::shared_ptr<model::DislocationNetwork<3>::NetworkLinkType> shared;
127 for(
const auto& entry : network->networkLinks())
129 const auto link=entry.second.lock();
130 if(link->loopLinks().size()>1 && link->chordLength()>1 && !link->isBoundarySegment())
136 require(
bool(shared),
"Fixture has no shared junction");
137 const auto memberships=shared->loopLinks().size();
138 auto inserted=network->networkNodes().create(shared->get_r(0.5));
139 network->expandNetworkLink(shared,inserted);
141 require(inserted->loopNodes().size()==memberships,
"Expansion lost junction sharing");
142 network->updateGeometry();
144 network->removeNetworkNode(inserted->sID);
146 network->updateGeometry();
157 const std::filesystem::path root(
argv[1]);
158 const auto folder = std::filesystem::temp_directory_path() /
159 (
"actor-index-caches-" + std::to_string(std::chrono::steady_clock::now().time_since_epoch().count()));
160 const auto input = folder /
"inputFiles";
161 std::filesystem::create_directories(input);
162 std::filesystem::create_directories(folder /
"F");
163 std::filesystem::copy_file(root /
"Library/Materials/W.txt", input /
"W.txt");
165 std::filesystem::copy_file(root /
"Library/Meshes/bicrystal_48.msh", input /
"mesh.msh");
166 std::filesystem::copy_file(root /
"Library/DislocationDynamics/DD.txt", input /
"DD.txt");
167 std::filesystem::create_directories(folder /
"config");
168 const double length=3671.9477120460206;
170 std::ofstream
f(input /
"DefectiveCrystal.txt");
171 f <<
"physics=DislocationDynamics;\nuseFEM=0;\nNsteps=0;\nmaxResolveSteps=0;\ndtMax=1;\noutputFrequency=1;\noutputBinary=0;\nstartAtTimeStep=0;\nperiodicImageSize=0 0 0;\nEwaldLengthFactor=0;\n";
172 std::ofstream
p(input /
"polycrystal.txt");
173 p << std::setprecision(17) <<
"materialFile=W.txt;\nmeshFile=mesh.msh;\nabsoluteTemperature=300;\nC2G1=1 0 0 0 1 0 0 0 1;\n"
174 <<
"C2G2=0.8 0 0.6 0 1 0 -0.6 0 0.8;\nF=" << length <<
" 0 0 0 " << length <<
" 0 0 0 " << length
175 <<
";\nX0=0 0 0;\nperiodicFaceIDs=-1;\n";
179 const auto dd=input/
"DD.txt";
180 std::ifstream source(dd);
181 std::string contents((std::istreambuf_iterator<char>(source)),std::istreambuf_iterator<char>());
182 const auto location=contents.find(
"Lmax=100;");
183 require(location!=std::string::npos,
"Expected library remeshing default");
184 contents.replace(location,std::string(
"Lmax=100;").size(),
"Lmax=150;");
185 std::ofstream output(dd);
189 for(
const std::string
fixture : {
"bicrystalBoundary430.txt",
"bicrystalBoundary500.txt",
"bicrystalSharedConstraints1915.txt"})
195 std::ifstream stream(root/
"tests/data"/
fixture);
196 require(
bool(stream),
"Missing bicrystal fixture");
197 saved.readTxtStream(stream);
201 std::filesystem::remove_all(folder);
202 std::cout<<
"PASS: actor points, connectivity, colors and junction sharing match legacy indexing\n";
205 catch(
const std::exception& error)
207 std::cerr<<error.what()<<std::endl;