8#ifndef model_DislocationLoopNode_cpp_
9#define model_DislocationLoopNode_cpp_
27 ,_periodicPlanePatch(patch_in)
28 ,periodicPlaneEdge(edge_in)
30 VerboseDislocationLoopNode(1,
"Creating LoopNode "<<this->tag()<<std::endl;);
31 if (periodicPlaneEdge.second!=
nullptr)
33 if (periodicPlaneEdge.first ==
nullptr)
35 assert(
false &&
"Inconsisten definition of periodic plane edges for the dislocation loop node");
42 DislocationLoopNode<dim>::DislocationLoopNode(
typename DislocationLoopNode<dim>::LoopNetworkType*
const net,
43 const std::shared_ptr<
typename DislocationLoopNode<dim>::LoopType>& loop,
44 const std::shared_ptr<
typename DislocationLoopNode<dim>::NetworkNodeType>& networkNode,
45 const LoopLinkType*
const loopLink) :
47 ,SplineNodeType(loopLink->periodicPlanePatch()? networkNode->get_P()-loopLink->periodicPlanePatch()->
shift : networkNode->get_P())
48 ,_periodicPlanePatch(loopLink->periodicPlanePatch())
49 ,periodicPlaneEdge(std::make_pair(nullptr,nullptr))
51 VerboseDislocationLoopNode(1,
"Creating LoopNode without PeriodicPlaneEdge "<<this->tag()<<std::endl;);
82 auto currentPrev(this->
prev.first);
83 while (currentPrev->isPeriodicSubdivision())
85 if (currentPrev ==
this)
89 currentPrev = currentPrev->prev.first;
101 auto currentNext(this->
next.first);
102 while (currentNext->isPeriodicSubdivision())
104 if (currentNext ==
this)
108 currentNext = currentNext->next.first;
119 std::vector<DislocationLoopNode<dim>*>
temp;
120 if (this->
prev.first)
122 auto currentPrev(this->
prev.first);
123 while (currentPrev->isPeriodicSubdivision())
125 temp.push_back(currentPrev);
126 currentPrev = currentPrev->prev.first;
136 std::vector<DislocationLoopNode<dim>*>
temp;
137 if (this->
next.first)
139 auto currentNext(this->
next.first);
140 while (currentNext->isPeriodicSubdivision())
142 temp.push_back(currentNext);
143 currentNext = currentNext->next.first;
153 VerboseDislocationLoopNode(2,
"DislocationLoopNode "<<this->tag()<<
" set_P (lowerDim)"<<std::endl;);
154 assert(periodicPlaneEdge.first);
156 VectorDim globalPosition(this->loop()->periodicGlidePlane->referencePlane->globalPosition(newP));
157 VectorDim localPosition(VectorDim::Zero());
159 if (periodicPlaneEdge.second==
nullptr)
161 localPosition=periodicPlaneEdge.first->meshIntersection->snap(globalPosition + periodicPlaneEdge.first->patch->shift);
171 SegmentSegmentDistance<3> ssd(periodicPlaneEdge.first->meshIntersection->P0,periodicPlaneEdge.first->meshIntersection->P1,
172 periodicPlaneEdge.second->meshIntersection->P0,periodicPlaneEdge.second->meshIntersection->P1);
173 assert(ssd.dMin<FLT_EPSILON &&
"The two periodic plane edges must intersect");
174 assert((periodicPlaneEdge.first->patch->shift-periodicPlaneEdge.second->patch->shift).norm()<FLT_EPSILON &&
"Two patch shifts must match ");
175 localPosition=0.5 * (ssd.x0 + ssd.x1);
177 globalPosition = localPosition - periodicPlaneEdge.first->patch->shift;
181 SplineNodeType::set_P(globalPosition);
182 this->networkNode->set_P(localPosition);
209 for(
const auto* face : edge->meshIntersection->faces)
211 if(!face->periodicFacePair.second || face->regionIDs!=face->periodicFacePair.second->regionIDs)
230 if(!this->network().trialNodeMotion)
233 const VectorDim mapped=newP+(_periodicPlanePatch ? _periodicPlanePatch->shift : VectorDim::Zero());
234 this->networkNode->trySet_P(mapped);
237 if(!isPeriodicSubdivision())
241 SplineNodeType::set_P(this->loop()->glidePlane ? this->loop()->glidePlane->snapToPlane(newP) : newP);
248 return _periodicPlanePatch;
262 if((pNext->get_P()-pPrev->get_P()).norm()<0.95*Lmax)
264 const double deltaArea(0.5 * (this->get_P() - pPrev->get_P()).cross(pNext->get_P() - this->get_P()).norm());
277 const double loopArea(this->
loop()->currentAreaVector().norm());
278 const double loopAreaRate(this->
loop()->currentAreaRate());
280 if (loopArea > std::pow(Lmin, 2))
282 VerboseDislocationLoopNode(2,
" DislocationLoopNode " << this->
tag() <<
" loopArea= " << loopArea << std::endl;);
283 VerboseDislocationLoopNode(2,
" DislocationLoopNode " << this->
tag() <<
" deltaArea= " << deltaArea << std::endl;);
284 VerboseDislocationLoopNode(2,
" DislocationLoopNode " << this->
tag() <<
" relAreaTh= " << relAreaTh << std::endl;);
285 VerboseDislocationLoopNode(2,
" DislocationLoopNode " << this->
tag() <<
" removable? " << (deltaArea / loopArea < relAreaTh) << std::endl;);
287 return deltaArea / loopArea < relAreaTh;
289 else if (loopArea > FLT_EPSILON && loopAreaRate<-FLT_EPSILON)
291 VerboseDislocationLoopNode(2,
" DislocationLoopNode " << this->
tag() <<
" removable (small loop)" << std::endl;);
296 VerboseDislocationLoopNode(2,
" DislocationLoopNode " << this->
tag() <<
" NOT removable (zero area loop)" << std::endl;);
302 VerboseDislocationLoopNode(2,
" DislocationLoopNode " << this->
tag() <<
" NOT removable (short segment)" << std::endl;);
315 VerboseDislocationLoopNode(2,
" Checking if DislocationLoopNode " << this->
tag() <<
" is removable " << std::endl;);
318 VerboseDislocationLoopNode(2,
" DislocationLoopNode " << this->
tag() <<
" onPlaneEdge" << std::endl;);
323 VerboseDislocationLoopNode(2,
" DislocationLoopNode " << this->
tag() <<
" NOT removable (both periodicPrev and periodicNext exist)" << std::endl;);
324 return std::make_pair(
false,0);
328 const double loopArea(this->
loop()->currentAreaVector().norm());
329 if (loopArea < std::pow(Lmin, 2))
331 VerboseDislocationLoopNode(2,
" DislocationLoopNode " << this->
tag() <<
" removable (on Edge via Geometric condition)" << std::endl;);
332 return std::make_pair(
true,this->
sID);
336 VerboseDislocationLoopNode(2,
" DislocationLoopNode " << this->
tag() <<
" NOT removable (on Edge)" << std::endl;);
337 return std::make_pair(
false, 0);
345 VerboseDislocationLoopNode(2,
" Dislocation LoopNode Not on Boundary " << std::endl;);
353 VerboseDislocationLoopNode(2,
" Has pPrev and pNext" << std::endl;);
357 VerboseDislocationLoopNode(2,
" Has 1 loop nodes" << std::endl;);
358 if ((pPrev->get_P() - pNext->get_P()).norm() < this->network().networkRemesher.Lmax
362 return std::make_pair(
true,this->
sID);
364 else if (this->
networkNode->isOnExternalBoundary())
369 return std::make_pair(
true,this->
sID);
373 return std::make_pair(
false,0);
379 return std::make_pair(
false,0);
382 else if (this->
networkNode->loopNodes().size() >= 2)
384 VerboseDislocationLoopNode(2,
" Has 2 loop nodes" << std::endl;);
385 const auto prevTwin(this->
prev.second->twinnedLink());
386 const auto nextTwin(this->
next.second->twinnedLink());
388 if (prevTwin && nextTwin)
390 VerboseDislocationLoopNode(2,
" Has prevTwin and nextTwin" << std::endl;);
392 if (prevTwin->loop == nextTwin->loop && (prevTwin->periodicPlanePatch() == nextTwin->periodicPlanePatch()))
394 VerboseDislocationLoopNode(2,
" Same patches" << std::endl;);
397 size_t prevtwinID((prevTwin->source->networkNode==this->networkNode)? prevTwin->source->sID : prevTwin->sink->sID);
398 size_t nexttwinID((nextTwin->source->networkNode==this->networkNode)? nextTwin->source->sID : nextTwin->sink->sID);
401 if (prevtwinID==nexttwinID)
403 VerboseDislocationLoopNode(2,
" Same IDs" << std::endl;);
404 return std::make_pair(
true,prevtwinID);
410 return std::make_pair(
false,0);
416 VerboseDislocationLoopNode(2,
" Different patches" << std::endl;);
417 return std::make_pair(
false, 0);
422 VerboseDislocationLoopNode(2,
" No prevTwin or nextTwin" << std::endl;);
423 return std::make_pair(
false,0);
428 VerboseDislocationLoopNode(2,
"this->networkNode->loopNodes().size()="<<this->
networkNode->loopNodes().size()<< std::endl;);
429 return std::make_pair(
false,0);
434 VerboseDislocationLoopNode(2,
" No pPrev or pNext" << std::endl;);
435 return std::make_pair(
false,0);
445 VerboseDislocationLoopNode(4,
"checking if DislocationLoopNode "<<this->
sID<<
" isMovable:"<<std::endl;);
451 isMovable=(isMovable && ((X-this->get_P()).squaredNorm()<FLT_EPSILON));
454 if(isMovable && this->
loop()->glidePlane)
456 isMovable=(isMovable && this->
loop()->glidePlane->contains(X));
static void initFromFile(const std::string &)
TraitsType::LoopType LoopType
DislocationLoopNode(LoopNetworkType *const, const std::shared_ptr< LoopType > &, const std::shared_ptr< NetworkNodeType > &, const VectorDim &, const std::shared_ptr< PeriodicPlanePatch< dim > > &, const std::pair< const std::shared_ptr< PeriodicPlaneEdge< dim > >, const std::shared_ptr< PeriodicPlaneEdge< dim > > > &)
TraitsType::VectorDim VectorDim
std::pair< bool, size_t > isRemovable(const double &Lmin, const double &Lmax, const double &relAreaTh)
const DislocationLoopNodeType * periodicPrev() const
bool isGeometricallyRemovable(const double &Lmin, const double &Lmax, const double &relAreaTh)
TraitsType::LoopNetworkType LoopNetworkType
std::vector< DislocationLoopNodeType * > boundaryNext() const
std::shared_ptr< PeriodicPlanePatch< dim > > periodicPlanePatch() const
TraitsType::NetworkNodeType NetworkNodeType
bool periodicContourVertex
bool isMovableTo(const VectorDim &) const
bool isPeriodicSubdivision() const
std::shared_ptr< DislocationLoopNode > clone(const std::shared_ptr< LoopType > &, const std::shared_ptr< NetworkNodeType > &) const
TraitsType::VectorLowerDim VectorLowerDim
std::vector< DislocationLoopNodeType * > boundaryPrev() const
const std::pair< const std::shared_ptr< PeriodicPlaneEdge< dim > >, const std::shared_ptr< PeriodicPlaneEdge< dim > > > periodicPlaneEdge
void set_P(const VectorDim &)
const DislocationLoopNodeType * periodicNext() const
bool isPhysicalBoundaryNode() const
TraitsType::LoopNodeType LoopNodeType
bool isContractableTo(const LoopNodeType *const other) const
static int verboseDislocationLoopNode
std::shared_ptr< NetworkNodeType > networkNode
const std::shared_ptr< LoopType > & loop() const
std::pair< LoopNodeType *, LoopLinkType * > prev
bool isContractableTo(const Derived *const other) const
std::pair< LoopNodeType *, LoopLinkType * > next
LoopNetworkType * p_network() const
Scalar readScalar(const std::string &key, const bool &verbose=false)