8#ifndef model_DislocationJunctionFormation_cpp_
9#define model_DislocationJunctionFormation_cpp_
24#define VerboseJunctions(N,x) if(verboseJunctions>=N){std::cout<<x;}
26#define VerboseJunctions(N,x)
36 void DislocationJunctionFormation<dim>::insertIntersection(std::deque<IntersectionTypeContainerType> &intersectionContainer,
40 const double ¤tcCollisionTOL,
41 const bool &bndJunction,
const bool &gbndJunction,
const int event)
43 VerboseJunctions(2,
"insertIntersection " << linkA->tag() <<
" [ " << linkA->source->get_P().transpose() <<
", " << linkA->sink->get_P().transpose()
45 <<
"," << linkB->tag() <<
" [ " << linkB->source->get_P().transpose() <<
", " << linkB->sink->get_P().transpose()
46 <<
" ]" << std::endl;);
47 VerboseJunctions(2,
"insertIntersection "
48 <<
"ssd.dMin=" << ssd.dMin << std::endl;);
49 VerboseJunctions(2,
"insertIntersection "
50 <<
"currentcCollisionTOL=" << currentcCollisionTOL << std::endl;);
52 if (ssd.dMin < currentcCollisionTOL)
54 bool isValidJunction(bndJunction || gbndJunction);
55 if (!isValidJunction && !linkA->isBoundarySegment() && !linkB->isBoundarySegment() && !linkA->isGrainBoundarySegment() && !linkB->isGrainBoundarySegment())
58 const VectorDim chordA(linkA->sink->get_P() - linkA->source->get_P());
59 const double LA(chordA.norm());
60 const VectorDim chordB(linkB->sink->get_P() - linkB->source->get_P());
61 const double LB(chordB.norm());
63 if (LA > FLT_EPSILON && LB > FLT_EPSILON)
65 if (ssd.dMin > FLT_EPSILON)
68 ssd.x0 + infiniteLineLength / LA * chordA,
69 linkA->burgers(),
DN.ddBase.dislocationDynamics().EwaldLength);
72 ssd.x1 + infiniteLineLength / LB * chordB,
73 linkB->burgers(),
DN.ddBase.dislocationDynamics().EwaldLength);
75 VerboseJunctions(3,
"Non-intersecting pair" << std::endl;);
76 const VectorDim forceOnA = (stressB.stress(ssd.x0) * linkA->burgers()).cross(chordA);
77 const VectorDim forceOnB = (stressA.stress(ssd.x1) * linkB->burgers()).cross(chordB);
79 if (forceOnA.dot(dxShift) > FLT_EPSILON && forceOnB.dot(dxShift) < -FLT_EPSILON)
81 VerboseJunctions(3,
"attractive pair 1" << std::endl;);
82 isValidJunction =
true;
86 VerboseJunctions(3,
"non-attractive pair" << std::endl;);
91 VerboseJunctions(3,
"Intersecting pair .. Determining via frank rule" << std::endl;);
92 isValidJunction=(linkA->burgers().dot(linkB->burgers())*linkA->chord().dot(linkB->chord())<=0.0);
100 intersectionContainer[omp_get_thread_num()].emplace_back(linkA->key,
104 intersectionContainer[0].emplace_back(linkA->key,
112 VerboseJunctions(3,
"dMin=" << ssd.dMin <<
", collisionTol=" << currentcCollisionTOL << std::endl;);
117 void DislocationJunctionFormation<dim>::findIntersections(std::deque<IntersectionTypeContainerType>& intersectionContainer,
118 const size_t& nThreads)
124 const auto t0= std::chrono::system_clock::now();
125 std::cout<<
" Finding collisions "<<std::flush;
129 for(
const auto& link :
DN.networkLinks())
131 const auto sharedLink(link.second.lock());
133 if( (!sharedLink->hasZeroBurgers() )
134 || sharedLink->isBoundarySegment() || sharedLink->isGrainBoundarySegment() )
137 const double x0=sharedLink->source->get_P()(0);
138 const double x1=sharedLink->sink->get_P()(0);
144 std::cout<<
"("<<swp.potentialIntersectionPairs().size()<<
" sweep-line pairs) "<<
defaultColor<<std::flush;
147 std::deque<std::pair<const NetworkLinkType*,const NetworkLinkType*>> reducedIntersectionPairs;
148 for(
size_t k=0;
k<swp.potentialIntersectionPairs().size();++
k)
150 const auto& linkA(swp.potentialIntersectionPair(
k).first);
151 const auto& linkB(swp.potentialIntersectionPair(
k).second);
152 const VectorDim& sourceA(linkA->source->get_P());
153 const VectorDim& sinkA(linkA->sink->get_P());
154 const VectorDim& sourceB(linkB->source->get_P());
155 const VectorDim& sinkB(linkB->sink->get_P());
158 bool yDontOverlap((std::min(sourceA(1),sinkA(1))>std::max(sourceB(1),sinkB(1))+
collisionTol) || (std::max(sourceA(1),sinkA(1))<std::min(sourceB(1),sinkB(1))-
collisionTol));
159 bool zDontOverlap((std::min(sourceA(2),sinkA(2))>std::max(sourceB(2),sinkB(2))+
collisionTol) || (std::max(sourceA(2),sinkA(2))<std::min(sourceB(2),sinkB(2))-
collisionTol));
161 if(!yDontOverlap && !zDontOverlap)
163 reducedIntersectionPairs.emplace_back(linkA,linkB);
167 std::cout<<
" ("<<reducedIntersectionPairs.size()<<
" reduced pairs) "<<
magentaColor<<
" ["<<(std::chrono::duration<double>(std::chrono::system_clock::now()-
t0)).
count()<<
" sec]"<<
defaultColor<<std::endl;
169 const auto t1= std::chrono::system_clock::now();
170 std::cout<<
" Selecting junctions ("<<nThreads<<
" threads): "<<std::flush;
176 for(
size_t k=0;
k<reducedIntersectionPairs.size();++
k)
179 const auto& linkA(reducedIntersectionPairs[
k].
first);
180 const auto& linkB(reducedIntersectionPairs[
k].second);
182 findPairIntersections(intersectionContainer,linkA,linkB);
185 int nIntersections=0;
186 for (
const auto& intersectionByThreadContainer : intersectionContainer)
188 nIntersections+=intersectionByThreadContainer.size();
190 std::cout<<nIntersections<<
" physical junctions "<<std::flush;
196 void DislocationJunctionFormation<dim>::findPairIntersections(
197 std::deque<IntersectionTypeContainerType>& intersectionContainer,
200 VerboseJunctions(2,
"checking intersection "<<linkA->tag()<<
","<<linkB->tag()<<std::endl;);
203 const bool linkAisBnd(linkA->isBoundarySegment());
204 const bool linkBisBnd(linkB->isBoundarySegment());
205 const bool linkAisGBnd(linkA->isGrainBoundarySegment());
206 const bool linkBisGBnd(linkB->isGrainBoundarySegment());
209 bool bndJunction=
false;
210 bool gbndJunction=
false;
211 const auto facesB=linkB->meshFaces();
214 if(linkA->chord().norm()>FLT_EPSILON && linkB->chord().norm()>FLT_EPSILON &&
215 linkA->chord().normalized().cross(linkB->chord().normalized()).norm()<FLT_EPSILON &&
216 linkA->glidePlaneNormal().cross(linkB->glidePlaneNormal()).norm()<FLT_EPSILON)
218 for(
const auto* face : linkA->meshFaces())
220 if(facesB.count(face))
222 const bool grainBoundary=face->regionIDs.first!=face->regionIDs.second ||
223 (face->periodicFacePair.second && face->regionIDs!=face->periodicFacePair.second->regionIDs);
224 gbndJunction=gbndJunction || grainBoundary;
225 bndJunction=bndJunction || (face->isExternal() && !face->periodicFacePair.second);
230 VerboseJunctions(2,
"links are bnd: "<<linkAisBnd<<
" "<<linkBisBnd<<std::endl;);
231 VerboseJunctions(2,
"links are grainBnd: "<<linkAisGBnd<<
" "<<linkBisGBnd<<std::endl;);
232 VerboseJunctions(2,
"bndJunction: "<<bndJunction<<std::endl;);
233 VerboseJunctions(2,
"gbndJunction: "<<gbndJunction<<std::endl;);
235 const bool intersectionIsSourceSource(linkA->source->sID==linkB->source->sID);
236 const bool intersectionIsSourceSink( linkA->source->sID==linkB-> sink->sID);
237 const bool intersectionIsSinkSource( linkA-> sink->sID==linkB->source->sID);
238 const bool intersectionIsSinkSink( linkA-> sink->sID==linkB-> sink->sID);
242 const auto pcPlanes(linkA->parallelAndCoincidentGlidePlanes(linkB->glidePlanes()));
243 VerboseJunctions(2,
"pcPlanes.size()= "<<pcPlanes.size()<<std::endl;);
244 for(
const auto& pair : pcPlanes)
246 if(pair.first==pair.second)
248 const double cosTheta=(intersectionIsSourceSource||intersectionIsSinkSink)? linkA->chord().normalized().dot(linkB->chord().normalized()) : ((intersectionIsSourceSink ||intersectionIsSinkSource)? -linkA->chord().normalized().dot(linkB->chord().normalized()) : -1.0);
251 currentcCollisionTOL=FLT_EPSILON;
257 currentcCollisionTOL=FLT_EPSILON;
261 if(intersectionIsSourceSource)
265 linkA->sink->get_P(),
266 linkB->source->get_P(),
267 linkB->sink->get_P(),
269 insertIntersection(intersectionContainer,linkA,linkB,ssdA,currentcCollisionTOL,bndJunction,gbndJunction,1);
273 linkA->sink->get_P(),
274 linkB->sink->get_P(),
275 linkB->sink->get_P(),
277 insertIntersection(intersectionContainer,linkA,linkB,ssdB,currentcCollisionTOL,bndJunction,gbndJunction,2);
280 else if(intersectionIsSourceSink)
284 linkA->sink->get_P(),
285 linkB->source->get_P(),
286 linkB->sink->get_P(),
288 insertIntersection(intersectionContainer,linkA,linkB,ssdA,currentcCollisionTOL,bndJunction,gbndJunction,1);
292 linkA->sink->get_P(),
293 linkB->source->get_P(),
294 linkB->source->get_P(),
296 insertIntersection(intersectionContainer,linkA,linkB,ssdB,currentcCollisionTOL,bndJunction,gbndJunction,2);
298 else if(intersectionIsSinkSource)
303 linkA->source->get_P(),
304 linkB->source->get_P(),
305 linkB->sink->get_P(),
307 insertIntersection(intersectionContainer,linkA,linkB,ssdA,currentcCollisionTOL,bndJunction,gbndJunction,1);
312 linkA->sink->get_P(),
313 linkB->sink->get_P(),
314 linkB->sink->get_P(),
316 insertIntersection(intersectionContainer,linkA,linkB,ssdB,currentcCollisionTOL,bndJunction,gbndJunction,2);
318 else if(intersectionIsSinkSink)
322 linkA->source->get_P(),
323 linkB->source->get_P(),
324 linkB->sink->get_P(),
326 insertIntersection(intersectionContainer,linkA,linkB,ssdA,currentcCollisionTOL,bndJunction,gbndJunction,1);
331 linkA->sink->get_P(),
332 linkB->source->get_P(),
333 linkB->source->get_P(),
335 insertIntersection(intersectionContainer,linkA,linkB,ssdB,currentcCollisionTOL,bndJunction,gbndJunction,2);
342 linkA->sink->get_P(),
343 linkB->source->get_P(),
346 insertIntersection(intersectionContainer,linkA,linkB,ssd,currentcCollisionTOL,bndJunction,gbndJunction);
352 std::pair<std::shared_ptr<typename DislocationJunctionFormation<dim>::NetworkNodeType>,
bool> DislocationJunctionFormation<dim>::junctionNode(
const double &
t,
354 const std::shared_ptr<NetworkLinkType> &L)
358 auto Nclose =
t < 0.5 ? L->source : L->sink;
359 auto Nfar =
t >= 0.5 ? L->source : L->sink;
360 VerboseJunctions(4,
"Nclose=" << Nclose->sID <<
" (GP Size)=> " << Nclose->glidePlanes().size() << std::endl;);
361 VerboseJunctions(4,
"Nfar=" << Nfar->sID <<
" (GP Size)=> " << Nfar->glidePlanes().size() << std::endl;);
363 if (
t > FLT_EPSILON &&
t < 1.0 - FLT_EPSILON)
365 if ((Nclose->get_P() -
x).norm() >
DN.networkRemesher.Lmin)
367 VerboseJunctions(4,
"JunctionNode case a" << std::endl;);
369 const VectorDim snappedPosition(L->glidePlanes().size() > 0 ? L->snapToGlidePlanes(
x) :
x);
370 const auto newNetNode(
DN.networkNodes().create(snappedPosition, L->source->get_V() * (1.0 -
t) + L->sink->get_V() *
t,L->source->climbVelocityScalar*(1.0-
t)+L->sink->climbVelocityScalar*
t,L->source->velocityReduction() * (1.0 -
t) + L->sink->velocityReduction() *
t));
371 DN.expandNetworkLink(L, newNetNode);
372 return std::make_pair(newNetNode,
true);
376 if (Nclose->isMovableTo(
x) && !Nclose->isBoundaryNode())
378 VerboseJunctions(4,
"JunctionNode case b" << std::endl;);
379 return std::make_pair(Nclose,
false);
383 if ((Nfar->get_P() -
x).norm() >
DN.networkRemesher.Lmin)
385 VerboseJunctions(4,
"JunctionNode case c" << std::endl;);
387 const VectorDim snappedPosition(L->glidePlanes().size() > 0 ? L->snapToGlidePlanes(
x) :
x);
389 const auto newNetNode(
DN.networkNodes().create(snappedPosition, L->source->get_V() * (1.0 -
t) + L->sink->get_V() *
t, L->source->climbVelocityScalar*(1.0-
t)+L->sink->climbVelocityScalar*
t,L->source->velocityReduction() * (1.0 -
t) + L->sink->velocityReduction() *
t));
396 DN.expandNetworkLink(L, newNetNode);
399 return std::make_pair(newNetNode,
true);
403 if (Nfar->isMovableTo(
x) && !Nfar->isBoundaryNode())
405 VerboseJunctions(4,
"JunctionNode case d" << std::endl;);
406 return std::make_pair(Nfar,
false);
410 VerboseJunctions(4,
"JunctionNode case e" << std::endl;);
416 const VectorDim snappedPosition(L->glidePlanes().size() > 0 ? L->snapToGlidePlanes(
x) :
x);
418 const auto newNetNode(
DN.networkNodes().create(snappedPosition, L->source->get_V() * (1.0 -
t) + L->sink->get_V() *
t, L->source->climbVelocityScalar*(1.0-
t)+L->sink->climbVelocityScalar*
t,L->source->velocityReduction() * (1.0 -
t) + L->sink->velocityReduction() *
t));
419 DN.expandNetworkLink(L, newNetNode);
420 return std::make_pair(newNetNode,
true);
428 bool physicalEndpoint=
false;
429 for(
const auto* ln : Nclose->loopNodes())
431 physicalEndpoint=physicalEndpoint || ln->isPhysicalBoundaryNode();
433 if (!Nclose->isBoundaryNode() ||
434 (physicalEndpoint && (Nclose->get_P()-
x).norm()<=FLT_EPSILON))
436 VerboseJunctions(4,
"JunctionNode case f" << std::endl;);
437 return std::make_pair(Nclose,
false);
441 VerboseJunctions(4,
"JunctionNode case g (returning nullptr)" << std::endl;);
442 return std::make_pair(
nullptr,
false);
449 size_t DislocationJunctionFormation<dim>::contractJunctions(
const std::deque<IntersectionTypeContainerType>& intersectionContainer)
451 const auto t0= std::chrono::system_clock::now();
452 std::cout<<
" : "<<std::flush;
454 DN.danglingBoundaryLoopNodes.clear();
455 size_t nContracted=0;
457 std::set<size_t> changedNodes;
459 for (
const auto& intersectionByThreadContainer : intersectionContainer)
461 for (
const auto& intersection : intersectionByThreadContainer)
463 const KeyType& key1(std::get<0>(intersection));
464 const KeyType& key2(std::get<1>(intersection));
466 const auto L1(
DN.networkLinks().get(key1));
467 const auto L2(
DN.networkLinks().get(key2));
474 std::set<size_t> footprint;
475 std::set<size_t> visitedLoops;
476 for(
const auto& node : {L1->source,L1->sink,L2->source,L2->sink})
478 for(
const auto* occurrence : node->loopNodes())
480 if(visitedLoops.insert(occurrence->loop()->sID).second)
482 for(
const auto* link : occurrence->loop()->linkSequence())
484 footprint.insert(link->source->networkNode->sID);
489 const bool dependent=std::any_of(footprint.begin(),footprint.end(),[&](
const size_t id)
491 return changedNodes.count(id)!=0;
501 std::deque<IntersectionTypeContainerType> refreshed(1);
502 findPairIntersections(refreshed,L1.get(),L2.get());
503 if(refreshed.front().empty())
509 auto refreshedEvent=refreshed.front().begin();
510 for(
auto it=refreshed.front().begin();it!=refreshed.front().end();++it)
512 if(std::get<3>(*it)==std::get<3>(intersection))
518 const auto ssd=std::get<2>(*refreshedEvent);
519 const double t=ssd.t;
520 const double u=ssd.u;
521 VerboseJunctions(1,
"forming junction "<<key1.first<<
"->"<<key1.second<<
", "
522 <<key2.first<<
"->"<<key2.second<<
", "
523 <<
"dMin="<<ssd.dMin<<
", "
524 <<
"@ ("<<
t<<
","<<
u<<
"), "<<std::flush);
525 VerboseJunctions(4,
"JunctionNode for segment: " << key1.first <<
"->" << key1.second <<
" @ " <<
t << std::endl;);
526 std::pair<std::shared_ptr<NetworkNodeType>,
bool> Ni(junctionNode(
t,ssd.x0,L1));
527 VerboseJunctions(4,
"JunctionNode for segment: " << key2.first <<
"->" << key2.second <<
" @ " <<
u << std::endl;);
528 std::pair<std::shared_ptr<NetworkNodeType>,
bool> Nj(junctionNode(
u,ssd.x1,L2));
530 if (Ni.first && Nj.first)
533 VerboseJunctions(1,
"contracting " << Ni.first->sID <<
" " << Nj.first->sID << std::endl;);
535 if (Ni.first->sID != Nj.first->sID)
537 const bool success =
DN.nodeContractor.contract(Ni.first,Nj.first,
false);
538 VerboseJunctions(1,
"success= " <<
success << std::endl;);
545 DN.removeNetworkNode(Ni.first->sID);
549 DN.removeNetworkNode(Nj.first->sID);
554 changedNodes.insert(footprint.begin(),footprint.end());
555 changedNodes.insert(Ni.first->sID);
556 changedNodes.insert(Nj.first->sID);
568 DN.removeNetworkNode(Ni.first->sID);
576 DN.removeNetworkNode(Nj.first->sID);
586 if(nContracted || !
DN.danglingBoundaryLoopNodes.empty())
588 DN.updateBoundaryNodes();
590 std::cout<<
" ("<<nContracted<<
" contracted, "<<nDeferred<<
" deferred)"<<
magentaColor
591 <<
" ["<<(std::chrono::duration<double>(std::chrono::system_clock::now()-
t0)).
count()
599 void DislocationJunctionFormation<dim>::glissileJunctions(
const double &
dx)
601 const auto t0 = std::chrono::system_clock::now();
602 std::cout <<
" Forming Glissile Junctions: " << std::flush;
604 std::deque<std::tuple<std::shared_ptr<NetworkNodeType>, std::shared_ptr<NetworkNodeType>, size_t,
size_t>> glissDeq;
606 for (
const auto &linkIter :
DN.networkLinks())
608 const auto link(linkIter.second.lock());
611 if ( link->loopLinks().size() > 1
612 && link->chordLength() >
dx
617 const VectorDim unitChord(link->chord() / link->chordLength());
619 if (!link->isGrainBoundarySegment() && !link->isBoundarySegment())
622 VerboseJunctions(2,
"glissele junction, segment " << link->tag() << std::endl;);
624 for (
const auto &gr : link->grains())
626 for (
size_t s = 0;
s < gr->slipSystems().size(); ++
s)
628 const auto &slipSystem(gr->slipSystems().at(s));
629 if ((slipSystem->s.cartesian() - link->burgers()).norm() < FLT_EPSILON && fabs(slipSystem->n.cartesian().normalized().dot(unitChord)) < FLT_EPSILON)
631 VerboseJunctions(3,
"glissDeq, emplacing" << std::endl;);
633 glissDeq.emplace_back(link->source, link->sink, gr->grainID, s);
641 size_t formedJunctions=0;
642 for(
const auto& [source,sink,grainID,slipID] : glissDeq)
644 const auto link=
DN.networkLinks().get(std::make_pair(
source->sID,sink->sID));
645 const auto& slip=
DN.ddBase.poly.grain(grainID)->slipSystems().at(slipID);
647 if(!link || link->hasZeroBurgers() || !link->isSessile() ||
648 link->isBoundarySegment() || link->isGrainBoundarySegment() ||
649 (link->burgers()-slip->s.cartesian()).norm()>FLT_EPSILON)
657 std::deque<const LoopNodeType*>
path;
660 for(
const auto* occurrence : link->loopLinks())
662 const bool forward=occurrence->source->networkNode==
source;
663 const auto*
a=(forward? occurrence->source : occurrence->sink).get();
664 const auto*
b=(forward? occurrence->sink : occurrence->source).get();
665 std::deque<const LoopNodeType*> candidate{
a,
b};
666 std::set<const LoopNodeType*> visited{
a,
b};
667 for(
const bool left : {
true,
false})
669 const auto*
current=
left? candidate.front() : candidate.back();
670 while(
current->isPeriodicSubdivision())
672 const bool next=
left? !forward : forward;
673 const auto* adjacent=next?
current->next.first :
current->prev.first;
674 if(!adjacent || !visited.insert(adjacent).second)
681 candidate.push_front(adjacent);
685 candidate.push_back(adjacent);
709 if(
path.size()!=candidate.size())
714 for(
size_t k=0;
k<
path.size();++
k)
716 if(path[
k]->networkNode!=candidate[
k]->networkNode ||
717 (path[
k]->periodicPlanePatch()->shift-originShift-
718 candidate[
k]->periodicPlanePatch()->shift+shift).norm()>FLT_EPSILON)
730 if(!valid ||
path.size()<2)
736 const auto glidePlane=
DN.ddBase.dislocationDynamics().glidePlaneFactory.getFromKey(
GlidePlaneKey<dim>(midpoint,slip->n));
737 const auto periodicPlane=
DN.ddBase.dislocationDynamics().periodicGlidePlaneFactory.get(glidePlane->key);
738 using EdgePair=std::pair<std::shared_ptr<PeriodicPlaneEdge<dim>>,std::shared_ptr<PeriodicPlaneEdge<dim>>>;
741 std::shared_ptr<NetworkNodeType> node;
743 std::shared_ptr<PeriodicPlanePatch<dim>> patch;
746 std::vector<SeedPoint> prepared;
747 std::set<const NetworkLinkType*> physicalLinks;
748 size_t midpointAfter=
path.size();
749 for(
size_t k=0;
k<
path.size();++
k)
751 const auto* node=
path[
k];
752 const VectorDim shift=node->periodicPlanePatch()->shift-originShift;
754 if(std::abs((position-glidePlane->P).dot(glidePlane->unitNormal))>FLT_EPSILON)
759 const auto patch=periodicPlane->getPatch(shift);
761 for(
const auto& edge : patch->edges())
765 if(edge->meshIntersection->contains(node->networkNode->get_P()))
771 else if(!
edges.second)
781 if(node->isPeriodicSubdivision() && !
edges.first)
785 prepared.push_back({node->networkNode,position,patch,
edges});
788 const auto* next=
path[
k+1];
789 const auto* loopLink=node->next.first==next? node->next.second : node->prev.second;
790 const auto segment=loopLink->networkLink();
793 const VectorDim orientedB=(segment->source==node->networkNode? 1.0 : -1.0)*segment->burgers();
794 if(segment->isBoundarySegment() || segment->isGrainBoundarySegment() ||
795 (orientedB-link->burgers()).norm()>FLT_EPSILON ||
796 !physicalLinks.insert(segment.get()).second)
811 if(!valid || midpointAfter==
path.size())
819 const auto seed=
DN.loops().create(slip->s.cartesian(),glidePlane);
820 std::vector<std::shared_ptr<LoopNodeType>> nodes;
821 for(
auto iter=prepared.rbegin();iter!=prepared.rend();++iter)
823 nodes.push_back(
DN.loopNodes().create(seed,iter->node,iter->position,iter->patch,iter->edges));
825 for(
size_t k=0;
k+1<prepared.size();++
k)
827 const auto& point=prepared[
k];
830 const auto freeNode=
DN.networkNodes().clone(point.node->sID);
831 nodes.push_back(
DN.loopNodes().create(seed,freeNode,point.position,point.patch,point.edges));
835 const auto freeNode=
DN.networkNodes().create(midpoint);
836 nodes.push_back(
DN.loopNodes().create(seed,freeNode,midpoint,periodicPlane->getPatch(VectorDim::Zero()),EdgePair()));
839 DN.insertLoop(seed,nodes);
842 std::cout <<
"(" << formedJunctions <<
" junctions)" <<
magentaColor <<
" [" << (std::chrono::duration<double>(std::chrono::system_clock::now() -
t0)).
count() <<
" sec]" <<
defaultColor << std::endl;
866 const size_t nThreads = 1;
868 const size_t nThreads = 1;
873 size_t nContracted=1;
877 std::deque<IntersectionTypeContainerType> intersectionContainer;
878 intersectionContainer.resize(nThreads);
879 findIntersections(intersectionContainer,nThreads);
881 nContracted=contractJunctions(intersectionContainer);
882 glissileJunctions(
dx);
891 void DislocationJunctionFormation<dim>::breakJunctions()
893 for (
const auto &nodeIter : DN.networkNodes())
895 const auto netNode(nodeIter.second.lock());
898 if ( netNode->loopNodes().size()==2
899 && netNode->neighbors().size()==4
902 std::cout<<
"Detected 4-point junction at node "<<netNode->sID<<std::endl;
Scalar readScalar(const std::string &key, const bool &verbose=false)
final point of the source segment t
size_t InstanceCount< Derived >::count
double DislocationJunctionFormation< dim >::collisionTol
static std::string magentaColor
static std::string defaultColor
LatticePlaneKey< dim > GlidePlaneKey
Eigen::Matrix< double, 3, 1 > VectorDim
void computeIntersectionPairs()
enum insertvertexresult success