Mechanics of Defect Evolution Library
Loading...
Searching...
No Matches
CrossSlipModels.cpp
Go to the documentation of this file.
1/* This file is part of MoDELib, the Mechanics Of Defects Evolution Library.
2 *
3 *
4 * MoDELib is distributed without any warranty under the
5 * GNU General Public License (GPL) v2 <http://www.gnu.org/licenses/>.
6 */
7
8
9#ifndef model_CrossSlipModels_cpp
10#define model_CrossSlipModels_cpp
11
12#include <DislocationNetwork.h>
13#include <CrossSlipModels.h>
14
15namespace model
16{
17
18 template <int dim>
20 /* init */ crossSlipDeg(TextFileParser(traitsIO.inputFilesFolder+"/DD.txt").readScalar<double>("crossSlipAngle_deg",true))
21 /* init */,sinCrossSlip(std::sin(crossSlipDeg*std::numbers::pi/180.0))
22 {
23
25 {
26 throw std::runtime_error("crossSlipDeg must be 0.0<= crossSlipDeg <= 90.0");
27 }
28
29 }
30
31 template <int dim>
32 std::pair<bool,int> BaseCrossSlipModel<dim>::isBaseCrossSlipLink(const NetworkLinkType& link,const bool enforceRemeshLength) const
33 {
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)
40 )
41 {
42 if((*link.loopLinks().begin())->loop->slipSystem())
43 {
44 // Check for one distinct grain without allocating a set.
45 const Grain<dim>* grain=nullptr;
46 for(const auto* plane : link.glidePlanes())
47 {
48 if(grain && grain!=&plane->grain)
49 {
50 return std::make_pair(false,-1);
51 }
52 grain=&plane->grain;
53 }
54 if(grain)
55 {
56 return std::make_pair(true,grain->grainID);
57 }
58 }
59 }
60 return std::make_pair(false,-1);
61 }
62
63 template <int dim>
65 /* init */ BaseCrossSlipModel<dim>(traitsIO)
66 {
67 std::cout<<greenBoldColor<<"Creating AthermalCrossSlipModel"<<defaultColor<<std::endl;
68 }
69
70 template <int dim>
71 std::pair<bool,std::pair<int,int>> AthermalCrossSlipModel<dim>::isCrossSlipLink(const NetworkLinkType& link)
72 {
73
74 const auto isBaseCSLink(this->isBaseCrossSlipLink(link));
75
76 if(isBaseCSLink.first)
77 {
78 // Find slip system on which screw segment has highest glide force
79 const auto loop((*link.loopLinks().begin())->loop);
80 const auto slipSystem(loop->slipSystem());
81 if(slipSystem)
82 {
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());
86
87 std::optional<std::pair<double,int>> best;
88 for(size_t s=0;s<grain.slipSystems().size();++s)
89 {
90 const auto& crossSlipSystem(grain.slipSystems().at(s));
91 if((loop->flow()-crossSlipSystem->s).squaredNorm()==0)
92 {
93 const double pkCross=std::fabs((pki-pki.dot(crossSlipSystem->unitNormal)*crossSlipSystem->unitNormal).norm());
94 // std::map::emplace kept the first slip system on ties.
95 if(!best || pkCross>best->first)
96 {
97 best=std::make_pair(pkCross,static_cast<int>(s));
98 }
99 }
100 }
101
102 if(best)
103 {
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)
107 {// highest glide PK-force is not on current slip system
108 return std::make_pair(true,std::make_pair(grain.grainID,best->second));
109 }
110 }
111 }
112 }
113 return std::make_pair(false,std::make_pair(-1,-1));
114 }
115
116 template <int dim>
118 CrossSlipContainerType& crossSlipDeq)
119 {
120 const auto isCSLink(isCrossSlipLink(link));
121 if(isCSLink.first)
122 {
123 crossSlipDeq.emplace_back(link.source,
124 link.sink,
125 isCSLink.second.first,
126 isCSLink.second.second);
127 }
128 }
129
131//template <int dim>
132//EscaigCrossSlipModelFCC<dim>::EscaigCrossSlipModelFCC(const PolycrystallineMaterialBase& material,const DefectiveCrystalTraitsIO& traitsIO) :
143//{
144// std::cout<<greenBoldColor<<"Creating EscaigCrossSlipModelFCC"<<defaultColor<<std::endl;
145//}
146//
148//template <int dim>
149//double EscaigCrossSlipModelFCC<dim>::crossSlipRateKernel(const int& k,const NetworkLinkType& link,const SlipSystem& css,
150// const double& w,
151// const double& L,
152// const double& dE,
153// const double& Veff
154// ) const
155//{ /*!@param[in] k the current quadrature point
156// *
157// */
158// const double eg(link.slipSystem()->unitNormal.transpose()*link.quadraturePoint(k).stress*link.slipSystem()->unitNormal.cross(link.slipSystem()->s.cartesian().normalized()));
159// const double ss(css.unitNormal.transpose()*link.quadraturePoint(k).stress*css.s.cartesian().normalized());
160// const double ec(css.unitNormal.transpose()*link.quadraturePoint(k).stress*css.unitNormal.cross(css.s.cartesian().normalized()));
161// // const double dG(dE-Veff*(-eg + ec)); // deltaSigma
162// const double dG(dE-std::fabs(ss)*Veff+eg*Veff-ec*Veff);
163//
164// return w*std::exp(-dG/link.network().poly.kB/link.network().poly.T)*link.quadraturePoint(k).j/L;
165//}
166//
168//template <int dim>
169//std::pair<bool,std::pair<int,int>> EscaigCrossSlipModelFCC<dim>::isCrossSlipLink(const NetworkLinkType& link)
170//{
171//
172// const auto isBaseCSLink(this->isBaseCrossSlipLink(link));
173// if(isBaseCSLink.first)
174// {
175// const auto& grain(**link.grains().begin());
176// std::map<double,int> ssMap;
177// for(size_t s=0;s<grain.singleCrystal->slipSystems().size();++s)
178// {
179// const auto& slipSystem(grain.singleCrystal->slipSystems()[s]);
180// if(((*link.loopLinks().begin())->loop->slipSystem()->s-slipSystem->s).squaredNorm()==0
181// && slipSystem->unitNormal.cross(link.glidePlaneNormal()).squaredNorm()>FLT_EPSILON) // not current slip system
182// {
183// if(link.slipSystem()->mobility && slipSystem->mobility)
184// {
185//
186// double csRate(0.0);
187// NetworkLinkType::QuadratureDynamicType::integrate(link.quadraturePoints().size(),this,csRate,&EscaigCrossSlipModelFCC<dim>::crossSlipRateKernel,link,*slipSystem,
188// omegaA,lengthC,Ea,activeVol);
189//
190// const double csProb(1.0-std::exp(-csRate*link.network().simulationParameters.dt));
191// ssMap.emplace(csProb,s);
192// }
193// }
194// }
195//
196// if(ssMap.size())
197// {
198// const double r(dist(gen));
199// if(ssMap.rbegin()->first > r)
200// {
201// return std::make_pair(true,std::make_pair(grain.grainID,ssMap.rbegin()->second));
202// }
203// }
204// }
205// return std::make_pair(false,std::make_pair(-1,-1));
206//}
207//
208//
209//template <int dim>
210//void EscaigCrossSlipModelFCC<dim>::addToCrossSlip(const NetworkLinkType& link,
211// CrossSlipContainerType& crossSlipDeq)
212//{
213// const auto isCSLink(isCrossSlipLink(link));
214// if(isCSLink.first)
215// {
216// crossSlipDeq.emplace_back(link.source,
217// link.sink,
218// isCSLink.second.first,
219// isCSLink.second.second);
220// }
221//}
222
223 template <int dim>
225 /* init */ BaseCrossSlipModel<dim>(traitsIO)
226 /* init */,gen(rd())
227 /* init */,dist(0.0,1.0)
228 /* init */,enableBasalSlipSystems(material.enabledSlipSystems.count("<a>{basal}")!=0)
229 /* init */,enablePrismaticSlipSystems(material.enabledSlipSystems.count("<a>{prismatic}")!=0)
230 /* init */,enablePyramidalSlipSystems(material.enabledSlipSystems.count("<a>{pyramidal}")!=0)
231 /* init */,csw(TextFileParser(material.materialFile).readScalar<double>("csw_SI",true)*material.b_SI/material.cs_SI)
232 /* init */,csLb(enableBasalSlipSystems? TextFileParser(material.materialFile).readScalar<double>("csLb_SI",true)/material.b_SI : 0.0)
233 /* init */,csLp(enablePrismaticSlipSystems? TextFileParser(material.materialFile).readScalar<double>("csLp_SI",true)/material.b_SI : 0.0)
234 /* init */,csb2pE(enableBasalSlipSystems && enablePrismaticSlipSystems? TextFileParser(material.materialFile).readScalar<double>("csb2pE_eV",true)*material.eV2J/(material.mu_SI*std::pow(material.b_SI,3)) : 0.0)
235 /* init */,csb2pVeg(enableBasalSlipSystems && enablePrismaticSlipSystems? TextFileParser(material.materialFile).readScalar<double>("csb2pVeg_SI",true)/std::pow(material.b_SI,3) : 0.0)
236 /* init */,csb2pVsc(enableBasalSlipSystems && enablePrismaticSlipSystems? TextFileParser(material.materialFile).readScalar<double>("csb2pVsc_SI",true)/std::pow(material.b_SI,3) : 0.0)
237 /* init */,csb2pVec(enableBasalSlipSystems && enablePrismaticSlipSystems? TextFileParser(material.materialFile).readScalar<double>("csb2pVec_SI",true)/std::pow(material.b_SI,3) : 0.0)
238 /* init */,csp2bE(enableBasalSlipSystems && enablePrismaticSlipSystems? TextFileParser(material.materialFile).readScalar<double>("csp2bE_eV",true)*material.eV2J/(material.mu_SI*std::pow(material.b_SI,3)) : 0.0)
239 /* init */,csp2bVeg(enableBasalSlipSystems && enablePrismaticSlipSystems? TextFileParser(material.materialFile).readScalar<double>("csp2bVeg_SI",true)/std::pow(material.b_SI,3) : 0.0)
240 /* init */,csp2bVsc(enableBasalSlipSystems && enablePrismaticSlipSystems? TextFileParser(material.materialFile).readScalar<double>("csp2bVsc_SI",true)/std::pow(material.b_SI,3) : 0.0)
241 /* init */,csp2bVec(enableBasalSlipSystems && enablePrismaticSlipSystems? TextFileParser(material.materialFile).readScalar<double>("csp2bVec_SI",true)/std::pow(material.b_SI,3) : 0.0)
242 {
243 if(!std::isfinite(csw) || csw<0.0 || (enableBasalSlipSystems && (!std::isfinite(csLb) || csLb<=0.0)) ||
244 (enablePrismaticSlipSystems && (!std::isfinite(csLp) || csLp<=0.0)))
245 {
246 throw std::runtime_error("Thermal cross-slip requires positive physical nucleation lengths and nonnegative attempt frequency");
247 }
248 std::cout<<greenBoldColor<<"Creating EscaigCrossSlipModelHEX"<<defaultColor<<std::endl;
249 }
250
251 template <int dim>
253 const double& w,
254 const double& L,
255 const double& dE,
256 const double& Veg,
257 const double& Vsc,
258 const double& Vec) const
259 {
262 const double eg(link.slipSystem()->unitNormal.transpose()*link.quadraturePoint(k).stress*link.slipSystem()->unitNormal.cross(link.slipSystem()->s.cartesian().normalized()));
263 const double ss(css.unitNormal.transpose()*link.quadraturePoint(k).stress*css.s.cartesian().normalized());
264 const double ec(css.unitNormal.transpose()*link.quadraturePoint(k).stress*css.unitNormal.cross(css.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;
267 }
268
269 template <int dim>
271 {
272 return link.slipSystem()->n.base()(0)==0 && link.slipSystem()->n.base()(1)==0? csLb : csLp;
273 }
274
275 template <int dim>
276 std::pair<bool,std::pair<int,int>> EscaigCrossSlipModelHEX<dim>::isCrossSlipLink(const NetworkLinkType& link)
277 {
278 // Geometric eligibility only: no random draw until the branch is complete.
279 const auto candidate=this->isBaseCrossSlipLink(link,false);
280 return {candidate.first,{candidate.second,-1}};
281 }
282
283 template <int dim>
284 std::map<int,double> EscaigCrossSlipModelHEX<dim>::targetRates(const NetworkLinkType& link) const
285 {
286 std::map<int,double> rates;
287 if(!link.slipSystem() || !link.slipSystem()->mobility || link.network().ddBase.poly.T<=0.0)
288 {
289 return rates;
290 }
291 const auto& grain=**link.grains().begin();
292 for(size_t s=0;s<grain.slipSystems().size();++s)
293 {
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) // not current slip system
297 {
298
299 if(link.slipSystem()->mobility && slipSystem->mobility)
300 {
301
302 double csRate(0.0);
303 if( (link.slipSystem()->n.base()(0)==0 && link.slipSystem()->n.base()(1)==0)
304 && slipSystem->n.base()(2)==0)
305 {// basal to prismatic crossSlip
306 NetworkLinkType::QuadratureDynamicType::integrate(link.quadraturePoints().size(),this,csRate,&EscaigCrossSlipModelHEX<dim>::crossSlipRateKernel,link,*slipSystem,
308 }
309 else if( link.slipSystem()->n.base()(2)==0
310 && (slipSystem->n.base()(0)==0 && slipSystem->n.base()(1)==0))
311 {// prismatic to basal crossSlip
312 NetworkLinkType::QuadratureDynamicType::integrate(link.quadraturePoints().size(),this,csRate,&EscaigCrossSlipModelHEX<dim>::crossSlipRateKernel,link,*slipSystem,
314 }
315 if(!std::isfinite(csRate) || csRate<0.0)
316 {
317 throw std::runtime_error("Nonfinite or negative thermal cross-slip rate");
318 }
319 if(csRate>0.0)
320 {
321 rates.emplace(s,csRate);
322 }
323 }
324 }
325 }
326 return rates;
327 }
328
329 template <int dim>
330 std::optional<ThermalCrossSlipEvent> EscaigCrossSlipModelHEX<dim>::sampleBranch(const std::vector<const NetworkLinkType*>& links,const double dt)
331 {
332 if(links.empty())
333 {
334 return std::nullopt;
335 }
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)
340 {
341 lengths.push_back(link->chordLength());
342 rates.push_back(targetRates(*link));
343 for(const auto& [target,rate] : rates.back())
344 {
345 nuclei.emplace(target,nucleationLength(*link));
346 }
347 }
348 const double occurrence=dist(gen);
349 const double target=dist(gen);
350 const double position=dist(gen);
351 return sampleThermalCrossSlip(lengths,rates,nuclei,dt,occurrence,target,position);
352 }
353
354 template <int dim>
356 CrossSlipContainerType& crossSlipDeq)
357 {
358
359 throw std::runtime_error("Thermal cross-slip requires branch-based sampling");
360 }
361
362 template struct BaseCrossSlipModel<3>;
363 template struct AthermalCrossSlipModel<3>;
364 template struct EscaigCrossSlipModelHEX<3>;
365
366}
367#endif
const size_t & grainID
Definition Grain.h:49
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
std::pair< bool, int > isBaseCrossSlipLink(const NetworkLinkType &link, const bool enforceRemeshLength=true) const
BaseCrossSlipModel(const DefectiveCrystalTraitsIO &traitsIO)
TraitsType::NetworkLinkType NetworkLinkType
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
std::deque< CrossSlipTupleType > CrossSlipContainerType
double nucleationLength(const NetworkLinkType &link) const
void addToCrossSlip(const NetworkLinkType &link, CrossSlipContainerType &crossSlipDeq) override
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
const RationalLatticeDirection< 3 > s
Definition SlipSystem.h:29
const VectorDim unitNormal
Definition SlipSystem.h:30
REAL w[16]
newsubseg ss[0]
REAL dist
int k