47 std::deque<std::deque<std::pair<const LoopLinkType*,int>>> csBranches;
48 if(this->
network().crossSlipModel)
50 const auto atJunction=[
this](
const auto& node)
52 for(
const auto* occurrence : node->networkNode->loopNodes())
54 if(occurrence->loop().get()!=
this ||
55 (occurrence!=node.get() && !occurrence->isPeriodicSubdivision()))
62 std::deque<std::pair<const LoopLinkType*,int>> currentBranch;
67 const auto start=std::find_if(sequence.begin(),sequence.end(),[](
const auto* link)
69 return link->hasNetworkLink();
71 std::rotate(sequence.begin(),start,sequence.end());
72 for(
const auto& link : sequence)
74 if(link->hasNetworkLink())
76 if(this->
network().crossSlipModel->isThermal() && !currentBranch.empty())
78 if(atJunction(link->source))
80 csBranches.push_back(currentBranch);
81 currentBranch.clear();
84 const auto isCSLink(this->
network().crossSlipModel->isCrossSlipLink(*link->networkLink()));
88 if(currentBranch.empty())
90 currentBranch.emplace_back(link,isCSLink.second.second);
94 if(currentBranch.back().second==isCSLink.second.second)
96 currentBranch.emplace_back(link,isCSLink.second.second);
100 csBranches.push_back(currentBranch);
101 currentBranch.clear();
102 currentBranch.emplace_back(link,isCSLink.second.second);
108 if(!currentBranch.empty())
110 csBranches.push_back(currentBranch);
111 currentBranch.clear();
117 if(!currentBranch.empty())
119 currentBranch.emplace_back(link,currentBranch.back().second);
123 if(!currentBranch.empty())
125 csBranches.push_back(currentBranch);
126 currentBranch.clear();
129 if(csBranches.size()>1)
131 if( csBranches[0].front().
first->prev==csBranches.back().back().first
132 && csBranches[0].front().second==csBranches.back().back().second
133 && (!this->network().crossSlipModel->isThermal() ||
134 !atJunction(csBranches[0].front().
first->source)))
136 for(
typename std::deque<std::pair<const LoopLinkType*,int>>::reverse_iterator rIter = csBranches.back().rbegin();
137 rIter != csBranches.back().rend(); ++rIter)
139 csBranches[0].push_front(*rIter);
141 csBranches.pop_back();
145 for(
const auto& branch : csBranches)
149 std::optional<ThermalCrossSlipEvent>
event;
150 if(this->
network().crossSlipModel->isThermal())
152 std::vector<const NetworkLinkType*> links;
153 for(
const auto& pair : branch)
155 if(pair.first->hasNetworkLink())
157 links.push_back(pair.first->networkLink().get());
160 event=this->
network().crossSlipModel->sampleBranch(links,dt>=0.0? dt : this->
network().ddBase.simulationParameters.dt);
166 csNodes.emplace_back(std::deque<std::shared_ptr<LoopNodeType>>(),
event?
event->target : branch.back().second);
167 csNodes.back().thermal=
event;
168 for(
const auto& pair : branch)
170 if(!pair.first->source->isPeriodicSubdivision())
172 csNodes.back().first.emplace_back(pair.first->source);
176 if(csNodes.back().first.size())
178 if( branch.back().first->sink!=csNodes.back().first.back()
179 && !branch.back().first->sink->isPeriodicSubdivision())
181 csNodes.back().first.emplace_back(branch.back().first->sink);
338 if(_slippedArea>FLT_EPSILON)
346 assert(linkSeq.size()==4);
348 std::vector<std::pair<VectorDim,VectorDim>> triangle0;
349 triangle0.emplace_back(linkSeq[0]->source->get_P(),linkSeq[0]->sink->get_P());
350 triangle0.emplace_back(linkSeq[1]->source->get_P(),linkSeq[1]->sink->get_P());
351 triangle0.emplace_back(linkSeq[1]->sink->get_P(),linkSeq[0]->source->get_P());
354 for(
const auto& pair : triangle0)
356 rhN0+= 0.5*(pair.first-planePoint0).cross(pair.second-pair.first);
358 const double rhN0norm(rhN0.norm());
359 if(rhN0norm>FLT_EPSILON)
364 std::vector<std::pair<VectorDim,VectorDim>> triangle1;
365 triangle1.emplace_back(linkSeq[2]->source->get_P(),linkSeq[2]->sink->get_P());
366 triangle1.emplace_back(linkSeq[3]->source->get_P(),linkSeq[3]->sink->get_P());
367 triangle1.emplace_back(linkSeq[3]->sink->get_P(),linkSeq[2]->source->get_P());
370 for(
const auto& pair : triangle1)
372 rhN1+= 0.5*(pair.first-planePoint1).cross(pair.second-pair.first);
374 const double rhN1norm(rhN1.norm());
375 if(rhN1norm>FLT_EPSILON)
386 double freeLength=0.0;
387 double boundaryLength=0.0;
388 double junctionLength=0.0;
389 for(
const auto& link : this->
loopLinks())
391 if(link->networkLink())
393 if(link->networkLink()->isBoundarySegment())
395 boundaryLength+=(link->sink->get_P()-link->source->get_P()).norm();
399 if(link->networkLink()->loopLinks().size()==1)
401 freeLength+=(link->sink->get_P()-link->source->get_P()).norm();
405 junctionLength+=(link->sink->get_P()-link->source->get_P()).norm();
410 return std::make_tuple(freeLength,junctionLength,boundaryLength,
slippedArea());
447 VerboseDislocationLoop(3,
"DislocationLoop "<<this->
tag()<<std::endl;);
449 const SlipSystem*
const oldSlipSystem(_slipSystem.get());
472 if(_slipSystem.get()!=oldSlipSystem)
474 for(
const auto& link : this->
loopLinks())
476 if(link->networkLink())
478 link->networkLink()->updateSlipSystem();
484 VerboseDislocationLoop(3,
"_slipSystem.s= "<<_slipSystem->s.cartesian().transpose()<<std::endl;);
485 VerboseDislocationLoop(3,
"_slipSystem.unitNormal= "<<_slipSystem->unitNormal.transpose()<<std::endl;);
489 VerboseDislocationLoop(3,
"slipSystem NOT FOUND"<<std::endl;);
534 VerboseDislocationLoop(2,
"DislocationLoop "<<this->
sID<<
" updateGeometry"<<std::endl;);
535 _rightHandedUnitNormal_old=_rightHandedUnitNormal;
543 for(
const auto& loopLink : this->
loopLinks())
545 nA+= 0.5*(loopLink->source->get_P()-P0).cross(loopLink->sink->get_P()-loopLink->source->get_P());
548 _slippedArea=nA.norm();
549 _rightHandedUnitNormal= _slippedArea>FLT_EPSILON? (nA/_slippedArea).
eval() : VectorDim::Zero();
550 const double nnDot(_rightHandedUnitNormal.dot(
glidePlane->unitNormal));
554 VerboseDislocationLoop(3,
"_rightHandedUnitNormal= "<<_rightHandedUnitNormal.transpose()<<std::endl;);
561 for(
const auto& loopLink : this->
loopLinks())
563 nA+= 0.5*(loopLink->source->get_P()-P0).cross(loopLink->sink->get_P()-loopLink->source->get_P());
567 for(
const auto& loopLink : this->
loopLinks())
569 isPlanar= (isPlanar && tempPlane.
contains(loopLink->source->get_P()));
575 _slippedArea=nA.norm();
576 _rightHandedUnitNormal= _slippedArea>FLT_EPSILON? (nA/_slippedArea).
eval() : VectorDim::Zero();
579 VerboseDislocationLoop(3,
"non-glide _rightHandedUnitNormal= "<<_rightHandedUnitNormal.transpose()<<std::endl;);
586 std::vector<VectorDim> linkShifts;
587 std::vector<VectorDim> globalNodePos;
590 for(
const auto& link : linkSeq)
592 if(link->periodicPlanePatch())
594 linkShifts.push_back(link->periodicPlanePatch()->shift);
598 if(!link->source->isPeriodicSubdivision())
600 globalNodePos.push_back(link->source->get_P());
603 _patches.update(linkShifts,globalNodePos);
Scalar readScalar(const std::string &key, const bool &verbose=false)