8#ifndef model_DislocationSegment_cpp_
9#define model_DislocationSegment_cpp_
19 const std::shared_ptr<NetworkNodeType>& nI,
20 const std::shared_ptr<NetworkNodeType>& nJ) :
29 VerboseDislocationSegment(1,
"Constructing DislocationSegment "<<this->
tag()<<std::endl);
38 return VectorDim::Zero();
43 const double tempNorm(
temp.norm());
44 return tempNorm<FLT_EPSILON? VectorDim::Zero() : (
temp/tempNorm).
eval();
55 const auto grs(this->
grains());
58 std::set<std::shared_ptr<SlipSystem>> ssSet;
60 for (
const auto &loopLink : this->
loopLinks())
62 if (loopLink->loop->slipSystem())
64 ssSet.insert(loopLink->loop->slipSystem());
89 for(
const auto& gpss : (*gps.begin())->slipSystems())
91 if((gpss->s.cartesian()-
burgers()).norm()<FLT_EPSILON)
130 VerboseDislocationSegment(3,
"_slipSystem.s= " <<
_slipSystem->s.cartesian().transpose() << std::endl;);
134 VerboseDislocationSegment(3,
"_slipSystem.s= " <<
_slipSystem->s.cartesian().transpose() << std::endl;);
135 VerboseDislocationSegment(3,
"_slipSystem.n= " <<
_slipSystem->unitNormal.transpose() << std::endl;);
146 VerboseDislocationSegment(2,
"DislocationSegment "<<this->
tag()<<
", adding LoopLink "<<pL->tag()<<std::endl;);
148 if(pL->source->networkNode==this->source)
150 Burgers+=pL->flow().cartesian();
154 Burgers-=pL->flow().cartesian();
161 const auto sourcePlanes(this->
source->glidePlanes());
162 const auto sinkPlanes(this->
sink->glidePlanes());
165 if(sourcePlanes.count(plane)==0 || sinkPlanes.count(plane)==0)
167 throw std::runtime_error(
"Segment glide plane missing from an endpoint");
180 VerboseDislocationSegment(2,
"DislocationSegment "<<this->
tag()<<
", removing LoopLink "<<pL->tag()<<std::endl;);
183 if(pL->source->networkNode==this->source)
185 Burgers-=pL->flow().cartesian();
189 Burgers+=pL->flow().cartesian();
201 VerboseDislocationSegment(2,
"DislocationSegment "<<this->
tag()<<
", updateGeometry "<<std::endl;);
205 VerboseDislocationSegment(2,
"DislocationSegment "<<this->
tag()<<
", updateGeometry DONE"<<std::endl;);
218 for(
const auto& loopLink : this->
loopLinks())
253 return MeshLocation::onRegionBoundary;
257 return MeshLocation::onMeshBoundary;
265 return MeshLocation::insideMesh;
309 if(face->regionIDs.first!=face->regionIDs.second ||
310 (face->periodicFacePair.second && face->regionIDs!=face->periodicFacePair.second->regionIDs))
326 Eigen::VectorXd& FQ)
const
336 Eigen::VectorXd& FQ,
const size_t sourceIndex,
const size_t sinkIndex)
const
344 std::pair<VectorNcoeff,VectorDim>,
347 h2posMap.emplace(sourceIndex,std::make_pair((
VectorNcoeff()<<1.0,0.0).finished(),this->
source->get_P()));
348 h2posMap.emplace(sinkIndex,std::make_pair((
VectorNcoeff()<<0.0,1.0).finished(),this->
sink->get_P()));
351 Eigen::Matrix<double, Ndof, Eigen::Dynamic> Mseg(Eigen::Matrix<double, Ndof, Eigen::Dynamic>::Zero(
Ncoeff*
dim,h2posMap.size()*
dim));
354 for(
const auto& pair : h2posMap)
358 Mseg.template block<dim,dim>(r*
dim,
c*
dim)=pair.second.first(r)*MatrixDim::Identity();
364 const Eigen::MatrixXd tempKqq(Mseg.transpose()*this->nodalVelocityMatrix(*
this)*Mseg);
366 for(
const auto& pairI : h2posMap)
368 for(
int dI=0;dI<
dim;++dI)
370 const size_t globalI=pairI.first*
dim+dI;
372 for(
const auto& pairJ : h2posMap)
374 for(
int dJ=0;dJ<
dim;++dJ)
376 const size_t globalJ=pairJ.first*
dim+dJ;
378 if (std::fabs(tempKqq(localI,localJ))>FLT_EPSILON)
380 kqqT.emplace_back(globalI,globalJ,tempKqq(localI,localJ));
391 const Eigen::VectorXd tempFq(Mseg.transpose()*this->nodalVelocityVector(*
this));
393 for(
const auto& pairI : h2posMap)
395 for(
int dI=0;dI<
dim;++dI)
397 const size_t globalI=pairI.first*
dim+dI;
399 FQ(globalI)+=tempFq(localI);
417 this->
update(*
this,isClimbStep);
426 return *subcyclingBins.begin();
430 if (maxVelocity > FLT_EPSILON)
432 const double avgV((0.5 * (this->
source->get_V() + this->sink->get_V())).norm());
434 if (avgV >= FLT_EPSILON)
436 const double velRat(maxVelocity / avgV);
437 std::map<double, int>
temp;
438 for (
const auto &sbin : subcyclingBins)
440 temp.emplace(fabs(velRat - sbin), sbin);
442 return temp.begin()->second;
446 return *subcyclingBins.rbegin();
452 return *subcyclingBins.begin();
471 if (ln->periodicPlanePatch())
473 temp.emplace(ln->periodicPlanePatch()->glidePlane.get());
486 for (
const auto &sourceMeshFace : sourceMeshFaces)
488 if (sinkMeshFaces.find(sourceMeshFace) != sinkMeshFaces.end())
490 temp.emplace(sourceMeshFace);
499 bool _isOnExternalBoundary(
false);
502 if (face->regionIDs.first == face->regionIDs.second)
504 _isOnExternalBoundary =
true;
508 return _isOnExternalBoundary;
514 bool _isOnInternalBoundary(
false);
517 if (face->regionIDs.first != face->regionIDs.second)
519 _isOnInternalBoundary =
true;
522 return _isOnInternalBoundary;
536 temp.insert(&glidePlane->grain);
547 _outNormal += face->outNormal();
549 const double _outNormalNorm(_outNormal.norm());
550 if (_outNormalNorm > FLT_EPSILON)
552 _outNormal /= _outNormalNorm;
556 _outNormal.setZero();
564 std::vector<std::pair<const GlidePlane<dim> *
const,
const GlidePlane<dim> *
const>> pp;
568 for (
const auto &otherPlane : other)
572 const bool parallel=&plane->n.lattice==&otherPlane->n.lattice?
573 plane->n.cross(otherPlane->n).base().squaredNorm()==0 :
574 plane->unitNormal.cross(otherPlane->unitNormal).norm()<FLT_EPSILON;
577 pp.emplace_back(plane, otherPlane);
590 Eigen::Matrix<double,Eigen::Dynamic,Eigen::Dynamic>
N(Eigen::Matrix<double,dim,Eigen::Dynamic>::Zero(
dim,gps.size()));
591 Eigen::Matrix<double,Eigen::Dynamic,Eigen::Dynamic> P(Eigen::Matrix<double,dim,Eigen::Dynamic>::Zero(
dim,gps.size()));
594 for(
const auto& plane : gps)
596 N.col(
k)=plane->unitNormal;
602 const std::pair<bool,VectorDim> snapped(pInt.
snap(
x));
605 return snapped.second;
609 std::cout<<
"glidePlanes.size()="<<gps.size()<<std::endl;
610 std::cout<<
"N="<<
N<<std::endl;
611 std::cout<<
"P="<<P<<std::endl;
612 throw std::runtime_error(
"DislocationSegment: cannot snap, glidePlanes dont intersect.");
613 return snapped.second;
628 const auto& Dinv(icp.
invD.at((*this->grains().begin())->grainID));
629 const auto& Ddet(icp.
detD.at((*this->grains().begin())->grainID));
631 Eigen::Array<double,mSize,1>
a(Eigen::Array<double,mSize,1>::Zero());
632 Eigen::Array<double,mSize,1>
b(Eigen::Array<double,mSize,1>::Zero());
633 Eigen::Array<double,mSize,1>
c(Eigen::Array<double,mSize,1>::Zero());
634 const double bxtSource(bCt.dot(this->source->climbDirection()));
635 const double bxtSink (bCt.dot(this->sink->climbDirection()));
637 Eigen::Array<double,mSize,1> bias(Eigen::Array<double,mSize,1>::Ones());
640 const auto loop((*this->
loopLinks().begin())->loop);
641 if(loop->burgers().dot(loop->rightHandedUnitNormal())>FLT_EPSILON)
645 else if(loop->burgers().dot(loop->rightHandedUnitNormal())<-FLT_EPSILON)
651 for(
const auto& shift : this->
network().ddBase.periodicShifts)
656 b(
k) =-2.0*(
x+shift-this->
source->get_P()).dot( Dinv[
k]*this->
chord() );
659 const Eigen::Array<double,mSize,1> ba(
b/
a);
660 const Eigen::Array<double,mSize,1>
ca(
c/
a);
661 const Eigen::Array<double,mSize,1> sqbca(sqrt(1.0+ba+
ca));
662 const Eigen::Array<double,mSize,1> sqca(sqrt(
ca));
663 const Eigen::Array<double,mSize,1> logTerm(log((2.0*sqbca+2.0+ba)/(2.0*sqca+ba)));
664 const Eigen::Array<double,mSize,1> I0((1.0+0.5*ba)*logTerm-sqbca+sqca);
665 const Eigen::Array<double,mSize,1> I1( -0.5*ba*logTerm+sqbca-sqca);
666 M.col(0)+=bxtSource*this->
chordLength()/(4.0*M_PI)*(I0/bias/sqrt(
a*Ddet)).matrix();
667 M.col(1)+=bxtSink* this->
chordLength()/(4.0*M_PI)*(I1/bias/sqrt(
a*Ddet)).matrix();
680 temp(
k)=cM.row(
k)*(Eigen::Matrix<double,2,1>()<<this->
source->climbVelocityScalar(
k),this->
sink->climbVelocityScalar(
k)).finished();
void create(const LinkType &parentSegment, const double &quadPerLength, const bool &isClimbStep)
void update(const LinkType &parentSegment, const bool &isClimbStep)
const DislocationQuadraturePointContainerType & quadraturePoints() const
ConcentrationMatrixType concentrationMatrices(const VectorDim &x, const ClusterDynamicsParameters< dim > &icp) const
std::set< const GlidePlaneType * > GlidePlaneContainerType
MeshLocation meshLocation() const
static int verboseDislocationSegment
bool isGrainBoundarySegment() const
std::set< const PlanarMeshFaceType * > PlanarMeshFaceContainerType
Eigen::Matrix< double, mSize, 1 > ConcentrationVectorType
TraitsType::VectorDim VectorDim
PlanarMeshFaceContainerType meshFaces() const
bool isOnInternalBoundary() const
Eigen::Matrix< double, mSize, 2 > ConcentrationMatrixType
GlidePlaneContainerType glidePlanes() const
StraightDislocationSegment< dim > straight
static constexpr int mSize
void addToGlobalAssembly(std::deque< Eigen::Triplet< double > > &kqqT, Eigen::VectorXd &FQ) const
bool isBoundarySegment() const
DislocationSegment(LoopNetworkType *const net, const std::shared_ptr< NetworkNodeType > &, const std::shared_ptr< NetworkNodeType > &)
void updateQuadraturePoints(const bool &isClimbStep)
VectorDim snapToGlidePlanes(const VectorDim &P) const
const VectorDim & glidePlaneNormal() const
static constexpr int Ncoeff
std::set< const GrainType * > GrainContainerType
static void initFromFile(const std::string &)
static const VectorDim zeroVector
VectorDim climbDirection() const
std::vector< std::pair< const GlidePlane< dim > *const, const GlidePlane< dim > *const > > parallelAndCoincidentGlidePlanes(const GlidePlaneContainerType &other) const
void createQuadraturePoints(const bool &isClimbStep)
const VectorDim & burgers() const
double BurgersNorm
The Burgers vector.
bool isOnBoundary() const
void removeLoopLink(LoopLinkType *const pL)
bool hasZeroBurgers() const
void addLoopLink(LoopLinkType *const pL)
SplineSegment< dim, 0 > SplineSegmentType
GrainContainerType grains() const
static double quadPerLength
const std::shared_ptr< SlipSystem > & slipSystem() const
std::shared_ptr< SlipSystem > _slipSystem
int velocityGroup(const double &maxVelocity, const std::set< int > &subcyclingBins) const
VectorDim bndNormal() const
TraitsType::LoopNetworkType LoopNetworkType
bool isOnExternalBoundary() const
TraitsType::LoopLinkType LoopLinkType
ConcentrationVectorType clusterConcentration(const VectorDim &x, const ClusterDynamicsParameters< dim > &icp) const
SplineSegmentType::VectorNcoeff VectorNcoeff
TraitsType::MeshLocation MeshLocation
const LoopNetworkType & network() const
void removeLoopLink(LoopLinkType *const pL)
const std::shared_ptr< NetworkNodeType > source
NetworkLink(LoopNetworkType *const loopNetwork, const std::shared_ptr< NetworkNodeType > &nI, const std::shared_ptr< NetworkNodeType > &nJ)
const std::shared_ptr< NetworkNodeType > sink
LoopLinkContainerType & loopLinks()
void addLoopLink(LoopLinkType *const pL)
const VectorDim & unitDirection() const
const VectorDim & chord() const
const double & chordLength() const
Scalar readScalar(const std::string &key, const bool &verbose=false)
auto eval(const std::shared_ptr< T > &t)
const Eigen::Array< double, 2, mSize > discreteDislocationBias
const std::map< size_t, std::vector< Eigen::Matrix< double, dim, dim > > > invD
const std::map< size_t, Eigen::Array< double, mSize, 1 > > detD
static double a2
Dislocation core size squared.
std::pair< bool, VectorDim > snap(const VectorDim &x) const