9#ifndef model_CrossSlipModels_cpp
10#define model_CrossSlipModels_cpp
26 throw std::runtime_error(
"crossSlipDeg must be 0.0<= crossSlipDeg <= 90.0");
34 if( !link.isBoundarySegment()
35 && !link.isGrainBoundarySegment()
36 && link.loopLinks().size()==1
37 && link.unitDirection().cross(link.burgers().normalized()).norm()<=
sinCrossSlip
38 && link.chordLength()>FLT_EPSILON
39 && (!enforceRemeshLength || link.chordLength()>2.0*link.network().networkRemesher.Lmin)
42 if((*link.loopLinks().begin())->loop->slipSystem())
46 for(
const auto* plane : link.glidePlanes())
48 if(grain && grain!=&plane->grain)
50 return std::make_pair(
false,-1);
56 return std::make_pair(
true,grain->
grainID);
60 return std::make_pair(
false,-1);
76 if(isBaseCSLink.first)
79 const auto loop((*link.loopLinks().begin())->loop);
80 const auto slipSystem(loop->slipSystem());
83 const auto& grain(*link.network().ddBase.poly.grain(isBaseCSLink.second));
84 const auto pki=link.pkIntegral();
85 const double pkGlide=std::fabs((pki-pki.dot(slipSystem->unitNormal)*slipSystem->unitNormal).norm());
87 std::optional<std::pair<double,int>> best;
88 for(
size_t s=0;s<grain.slipSystems().size();++s)
90 const auto& crossSlipSystem(grain.slipSystems().at(s));
91 if((loop->flow()-crossSlipSystem->s).squaredNorm()==0)
93 const double pkCross=std::fabs((pki-pki.dot(crossSlipSystem->unitNormal)*crossSlipSystem->unitNormal).norm());
95 if(!best || pkCross>best->first)
97 best=std::make_pair(pkCross,
static_cast<int>(s));
104 const auto& crossSlipSystem(grain.slipSystems().at(best->second));
105 if(slipSystem->unitNormal.cross(crossSlipSystem->unitNormal).squaredNorm()>FLT_EPSILON
106 && best->first>1.1*pkGlide)
108 return std::make_pair(
true,std::make_pair(grain.grainID,best->second));
113 return std::make_pair(
false,std::make_pair(-1,-1));
123 crossSlipDeq.emplace_back(link.source,
125 isCSLink.second.first,
126 isCSLink.second.second);
231 ,
csw(
TextFileParser(material.materialFile).readScalar<double>(
"csw_SI",true)*material.b_SI/material.cs_SI)
246 throw std::runtime_error(
"Thermal cross-slip requires positive physical nucleation lengths and nonnegative attempt frequency");
258 const double& Vec)
const
262 const double eg(link.slipSystem()->unitNormal.transpose()*link.quadraturePoint(
k).stress*link.slipSystem()->unitNormal.cross(link.slipSystem()->s.cartesian().normalized()));
265 const double dG(dE-std::fabs(
ss)*Vsc+eg*Veg-ec*Vec);
266 return w*std::exp(-dG/link.network().ddBase.poly.kB/link.network().ddBase.poly.T)*link.quadraturePoint(
k).j/L;
272 return link.slipSystem()->n.base()(0)==0 && link.slipSystem()->n.base()(1)==0?
csLb :
csLp;
280 return {candidate.first,{candidate.second,-1}};
286 std::map<int,double> rates;
287 if(!link.slipSystem() || !link.slipSystem()->mobility || link.network().ddBase.poly.T<=0.0)
291 const auto& grain=**link.grains().begin();
292 for(
size_t s=0;s<grain.slipSystems().size();++s)
294 const auto& slipSystem(grain.slipSystems().at(s));
295 if(((*link.loopLinks().begin())->loop->slipSystem()->s-slipSystem->s).squaredNorm()==0
296 && slipSystem->unitNormal.cross(link.glidePlaneNormal()).squaredNorm()>FLT_EPSILON)
299 if(link.slipSystem()->mobility && slipSystem->mobility)
303 if( (link.slipSystem()->n.base()(0)==0 && link.slipSystem()->n.base()(1)==0)
304 && slipSystem->n.base()(2)==0)
309 else if( link.slipSystem()->n.base()(2)==0
310 && (slipSystem->n.base()(0)==0 && slipSystem->n.base()(1)==0))
315 if(!std::isfinite(csRate) || csRate<0.0)
317 throw std::runtime_error(
"Nonfinite or negative thermal cross-slip rate");
321 rates.emplace(s,csRate);
336 std::vector<double> lengths;
337 std::vector<std::map<int,double>> rates;
338 std::map<int,double> nuclei;
339 for(
const auto* link : links)
341 lengths.push_back(link->chordLength());
343 for(
const auto& [target,rate] : rates.back())
348 const double occurrence=
dist(
gen);
350 const double position=
dist(
gen);
359 throw std::runtime_error(
"Thermal cross-slip requires branch-based sampling");
size_t InstanceCount< Derived >::count
std::optional< ThermalCrossSlipEvent > sampleThermalCrossSlip(const std::vector< double > &lengths, const std::vector< std::map< int, double > > &rates, const std::map< int, double > &nucleusLengths, const double dt, const double occurrence, const double targetDraw, const double positionDraw)
static std::string greenBoldColor
static std::string defaultColor
std::pair< bool, std::pair< int, int > > isCrossSlipLink(const NetworkLinkType &link) override
AthermalCrossSlipModel(const DefectiveCrystalTraitsIO &traitsIO)
std::deque< CrossSlipTupleType > CrossSlipContainerType
void addToCrossSlip(const NetworkLinkType &link, CrossSlipContainerType &crossSlipDeq) override
TraitsType::NetworkLinkType NetworkLinkType
const double sinCrossSlip
std::pair< bool, int > isBaseCrossSlipLink(const NetworkLinkType &link, const bool enforceRemeshLength=true) const
BaseCrossSlipModel(const DefectiveCrystalTraitsIO &traitsIO)
TraitsType::NetworkLinkType NetworkLinkType
const double crossSlipDeg
const bool enablePyramidalSlipSystems
std::pair< bool, std::pair< int, int > > isCrossSlipLink(const NetworkLinkType &link) override
double crossSlipRateKernel(const int &k, const NetworkLinkType &link, const SlipSystem &css, const double &w, const double &L, const double &dE, const double &Veg, const double &Vsc, const double &Vec) const
std::optional< ThermalCrossSlipEvent > sampleBranch(const std::vector< const NetworkLinkType * > &links, const double dt) override
std::map< int, double > targetRates(const NetworkLinkType &link) const
const bool enableBasalSlipSystems
std::deque< CrossSlipTupleType > CrossSlipContainerType
double nucleationLength(const NetworkLinkType &link) const
void addToCrossSlip(const NetworkLinkType &link, CrossSlipContainerType &crossSlipDeq) override
const bool enablePrismaticSlipSystems
TraitsType::NetworkLinkType NetworkLinkType
std::uniform_real_distribution dist
EscaigCrossSlipModelHEX(const PolycrystallineMaterialBase &material, const DefectiveCrystalTraitsIO &traitsIO)
virtual MatrixDim stress(const VectorDim &, const NodeType *const, const ElementType *const, const SimplexDim *const) const =0
VectorDimD cartesian() const
const RationalLatticeDirection< 3 > s
const VectorDim unitNormal