Mechanics of Defect Evolution Library
Loading...
Searching...
No Matches
src/ClusterDynamics/ClusterDynamicsParameters.cpp
Go to the documentation of this file.
1/* This file is part of GreatWhite, a library for integrating
2 * MOOSE and MoDeLib.
3 *
4 * (c) 2018 Multiscale Materials Solutions, LLC
5 * ALL RIGTHS REVERVED
6 * Prepared by 2018 Multiscale Materials Solutions
7 * under contract N. 126180
8 * with the NAVAL NUCLEAR LABORATORY
9 *
10 * See COPYRIGHT for full restriction
11 */
12
13
14#ifndef model_ClusterDynamicsParameters_cpp_
15#define model_ClusterDynamicsParameters_cpp_
16
19
20namespace model
21{
22
23 template<int dim>
25 /* init */ kB(ddBase.poly.kB),
26 /* init */ T(ddBase.poly.T),
27 /* init */ omega(ddBase.poly.Omega),
28 /* init */ b(ddBase.poly.b),
29 /* init */ G0(true? TextFileParser(ddBase.poly.materialFile).readScalar<double>("doseRate_dpaPerSec",true)*(ddBase.poly.b_SI/ddBase.poly.cs_SI) : 0.0),
30 /* MOBILE SPECIES */
31 /* init */ msVector(true? TextFileParser(ddBase.poly.materialFile).readMatrix<int>("mobileSpeciesVector",1,mSize,true).array().template cast<double>().eval() : Eigen::Array<double,1,mSize>::Zero()),
32 /* init */ msRelRelaxVol(true? TextFileParser(ddBase.poly.materialFile).readMatrix<double>("mobileSpeciesRelRelaxVol",1,mSize,true).array().eval() : Eigen::Array<double,1,mSize>::Zero()),
33 /* init */ msEf(true? (TextFileParser(ddBase.poly.materialFile).readMatrix<double>("mobileSpeciesEnergyFormation_eV",1,mSize,true).array()*ddBase.poly.eV2J/ddBase.poly.mu_SI/pow(ddBase.poly.b_SI,3)).eval() : Eigen::Array<double,1,mSize>::Zero()),
34 /* init */ msEm(true? (TextFileParser(ddBase.poly.materialFile).readMatrix<double>("mobileSpeciesEnergyMigration_eV",mSize,dim*(dim+1)/2,true)*ddBase.poly.eV2J/ddBase.poly.mu_SI/pow(ddBase.poly.b_SI,3)).eval() : Eigen::Matrix<double,mSize,dim*(dim+1)/2>::Zero()),
35 /* init */ msD0(true? (TextFileParser(ddBase.poly.materialFile).readMatrix<double>("mobileSpeciesD0_SI",mSize,dim*(dim+1)/2,true)/ddBase.poly.b_SI/ddBase.poly.cs_SI).eval() : Eigen::Matrix<double,mSize,dim*(dim+1)/2>::Zero()),
36 /* init */ D(getD(ddBase.poly.grains)),
37 /* init */ invD(getInvD()),
38 /* init */ detD(getDetD()),
39 /* init */ Eb((true && iSize>0) ? TextFileParser(ddBase.poly.materialFile).readMatrix<double,1,mSize>("mobileSpeciesBindingEnergy_eV",true).array()*ddBase.poly.eV2J/ddBase.poly.mu_SI/pow(ddBase.poly.b_SI,3) : Eigen::Array<double,1,mSize>::Zero().eval()),
40 /* init */ msCascadeFractions((mSize>1 && G0>0.0) ? TextFileParser(ddBase.poly.materialFile).readMatrix<double>("mobileSpeciesCascadeFractions",1,mSize,true) : Eigen::Matrix<double,1,mSize>::Ones()),
41 /* init */ msSurvivingEfficiency(G0>0.0 ? TextFileParser(ddBase.poly.materialFile).readScalar<double>("mobileSpeciesSurvivingEfficiency",true) : 1.0),
43 /* init */ otherSinks(true? (TextFileParser(ddBase.poly.materialFile).readMatrix<double,1,mSize>("otherSinks_SI",true)*ddBase.poly.b_SI*ddBase.poly.b_SI).eval() : Eigen::Array<double,1,mSize>::Zero()),
44 /* init */ dislocationSinks(iSize>0 ? (TextFileParser(ddBase.poly.materialFile).readMatrix<double,1,iSize/2>("dislocationSinks_SI",true)*ddBase.poly.b_SI*ddBase.poly.b_SI).array().eval() : Eigen::Array<double,1,iSize/2>::Zero().eval()), // read only with immobile species
45 /* init */ initLoopSinks(iSize>0 ? getInitLoopSinks(TextFileParser(ddBase.poly.materialFile).readMatrix<double,1,iSize>("initLoopSinks_SI",true),ddBase.poly.b_SI) : Eigen::Array<double,1,iSize>::Zero().eval()), // read only with immobile species
46 /* init */ reactionMap((true && mSize>1) ? getMap(TextFileParser(ddBase.poly.materialFile).readMatrix<double,mSize*(mSize+1)/2,3>("reactionPrefactorMap",true)) : std::map<std::pair<int,int>,double>()),
47 /* init */ R1(mSize>1 ? getR1() : Eigen::Matrix<double,mSize,mSize>::Zero()),
48 /* init */ R1cd(iSize>0 ? msVector.abs().matrix().asDiagonal()*R1*(1.0/msVector.abs()).matrix().asDiagonal() : Eigen::Matrix<double,mSize,mSize>::Zero().eval()),
49 /* init */ R2(mSize>1 ? getR2() : std::vector<Eigen::Matrix<double,mSize,mSize>>(2,Eigen::Matrix<double,mSize,mSize>::Zero())),
50 /* init */ discreteDislocationBias(true? TextFileParser(ddBase.poly.materialFile).readMatrix<double,2,mSize>("discreteDislocationBias",true).eval() : Eigen::Array<double,2,mSize>::Zero()),
51 /* IMMOBILE SPECIES */
52 /* init */ immobileSpeciesVector((true && iSize>0) ? TextFileParser(ddBase.poly.materialFile).readMatrix<int>("immobileSpeciesVector",1,iSize/2,true).array().template cast<double>() : Eigen::Array<double,1,iSize/2>::Zero().eval()),
53 /* init */ immobileSpeciesRelRelaxVol((true && iSize>0) ? TextFileParser(ddBase.poly.materialFile).readMatrix<double,1,iSize/2>("immobileSpeciesRelRelaxVol",true).array() : Eigen::Array<double,1,iSize/2>::Zero().eval()),
54 /* init */ immobileSpeciesBurgers((true && iSize>0) ? TextFileParser(ddBase.poly.materialFile).readMatrix<double,dim,iSize/2>("immobileSpeciesBurgers",true) : Eigen::Matrix<double,dim,iSize/2>::Zero()),
55 /* init */ immobileSpeciesBurgersMagnitude((true && iSize>0) ? getImmobileSpeciesBurgersMagnitude(ddBase.poly.grains) : Eigen::Array<double,1,iSize/2>::Zero().eval()),
56 /* init */ immobileBias((true && iSize>0) ? TextFileParser(ddBase.poly.materialFile).readMatrix<double,1,iSize/2>("immobileBias",true) : Eigen::Array<double,1,iSize/2>::Zero()),
57 /* init */ a_bp((true && iSize>0) ? TextFileParser(ddBase.poly.materialFile).readScalar<double>("alpha_bp",true) : 0.0),
58 /* init */ delVPyramid((true && iSize>0) ? TextFileParser(ddBase.poly.materialFile).readScalar<double>("delVPyramid",true)/pow(ddBase.poly.b_SI,3) : 0.0),
59 /* init */ w0((true && iSize>0) ? TextFileParser(ddBase.poly.materialFile).readScalar<double>("w0",true) : 0.0),
60 /* init */ n_s((true && iSize>0) ? TextFileParser(ddBase.poly.materialFile).readScalar<double>("n_s",true) : 0.0 ),
61// /* init */ evc((true && iSize>0) ? TextFileParser(ddBase.poly.materialFile).readScalar<double>("evc",true) : 0.0 ),
62// /* init */ Nvmax((true && iSize>0) ? TextFileParser(ddBase.poly.materialFile).readScalar<double>("Nvmax",true)*pow(ddBase.poly.b_SI,3) : 0.0 ),
63 /* init */ nmin((true && iSize>0) ? TextFileParser(ddBase.poly.materialFile).readMatrix<double,1,iSize/2>("nmin",true) : Eigen::Array<double,1,iSize/2>::Zero()),
64 /* init */ nmax((true && iSize>0) ? TextFileParser(ddBase.poly.materialFile).readMatrix<double,1,iSize/2>("nmax",true) : Eigen::Array<double,1,iSize/2>::Zero()),
65 /* init */ n_min((true && iSize>0) ? TextFileParser(ddBase.poly.materialFile).readMatrix<double,1,iSize/2>("n_min",true).array() : Eigen::Array<double,1,iSize/2>::Zero().eval()),
66 /* init */ computeReactions((true && mSize>0 && mSize+iSize>1)? TextFileParser(ddBase.poly.materialFile).readScalar<int>("computeReactions",true) : 0),
67// /* init */ use0DsinkStrength((true && iSize>0) ? TextFileParser(ddBase.poly.materialFile).readScalar<int>("use0DsinkStrength",true) : 0),
68// /* init */ Zv((true && iSize>0) ? TextFileParser(ddBase.poly.materialFile).readMatrix<double,1,dim>("Zv",true) : Eigen::Array<double,1,dim>::Zero()),
69// /* init */ Zi((true && iSize>0) ? TextFileParser(ddBase.poly.materialFile).readMatrix<double,1,dim>("Zi",true) : Eigen::Array<double,1,dim>::Zero()),
70// /* init */ ZVec((true && iSize>0) ? TextFileParser(ddBase.poly.materialFile).readMatrix<double,1,mSize>("ZVec",true) : Eigen::Array<double,1,mSize>::Zero()),
71// /* init */ rc_il((true && iSize>0) ? TextFileParser(ddBase.poly.materialFile).readMatrix<double,1,dim>("rc_il",true)/ddBase.poly.b_SI : Eigen::Array<double,1,dim>::Zero().eval()),
72 // /* init */ discreteDistanceFactor((true && iSize>0) ? TextFileParser(ddBase.poly.materialFile).readScalar<double>("distanceFactor",true) : 0.0),
73 /* init */ discretizationFactor((true && iSize>0) ? TextFileParser(ddBase.poly.materialFile).readScalar<double>("clusterDiscretizationFactor",true) : 0.0),
74 /* init */ discretizationTime((true && iSize>0) ? TextFileParser(ddBase.poly.materialFile).readScalar<double>("clusterDiscretizationTime",true)*(ddBase.poly.cs_SI/ddBase.poly.b_SI) : 0.0),
75 /* init */ minimumLoopSize((true && iSize>0) ? TextFileParser(ddBase.poly.materialFile).readScalar<double>("minimumLoopSize",true)/ddBase.poly.b_SI : 0.0 )
76 {
77
78 double vacancySum(0.0);
79 double interstitialSum(0.0);
80 for(int k=0;k<mSize;++k)
81 {
82 if(msVector(k)<0)
83 {// vacancy cluster
84 vacancySum+=msCascadeFractions(k);
85 }
86 else if(msVector(k)>0)
87 {// interstitial cluster
88 interstitialSum+=msCascadeFractions(k);
89 }
90 }
91
92 if(fabs(vacancySum-1.0)>FLT_EPSILON)
93 {
94 // throw std::runtime_error("vacancy cluster fraction does not sum to one.");
95 std::cout<<redBoldColor<<"Warning: vacancy cluster fraction does not sum to one."<<defaultColor<<std::endl;
96 }
97 if(fabs(interstitialSum-1.0)>FLT_EPSILON)
98 {
99 // throw std::runtime_error("interstitial cluster fraction does not sum to one.");
100 std::cout<<redBoldColor<<"Warning: interstitial cluster fraction does not sum to one."<<defaultColor<<std::endl;
101 }
102
103 for(const auto& pair: reactionMap)
104 {
105 const auto key=pair.first;
106 std::cout<<"find the interaction between "<<key.first<<" - "<<key.second<<" and parameter: "<<pair.second<<std::endl;
107 }
108
109 std::cout<<"first-order interaction matrix (in 1/s) is: "<<std::endl;
110 std::cout<<R1*ddBase.poly.cs_SI/ddBase.poly.b_SI<<std::endl;
111
112 for(size_t k=0; k<mSize; k++)
113 {
114 std::cout<<"second-order interaction matrix (in 1/s) for "<<static_cast<int>(msVector(k))<<"-species is: "<<std::endl;
115 std::cout<<R2[k]*ddBase.poly.cs_SI/ddBase.poly.b_SI<<std::endl;
116 }
117 }
118
119 template<int dim>
120 std::map<std::pair<int,int>,double> ClusterDynamicsParameters<dim>::getMap(const Eigen::Array<double,mSize*(mSize+1)/2,3> matrix_in) const
121 {
122 std::map<std::pair<int,int>,double> tempMap;
123 for(int k=0; k<mSize*(mSize+1)/2; k++)
124 {
125 const int key0= matrix_in(k,0)<0? static_cast<int>(matrix_in(k,0)-msVector(0)): static_cast<int>(matrix_in(k,0)-msVector(0)-1);
126 const int key1= matrix_in(k,1)<0? static_cast<int>(matrix_in(k,1)-msVector(0)): static_cast<int>(matrix_in(k,1)-msVector(0)-1);
127 if(key0>key1)
128 {
129 throw std::runtime_error("Please keep the reaction map orders, key0<=key1.");
130 }
131 const std::pair<int,int> key(key0,key1);
132 tempMap.insert(std::pair<std::pair<int,int>,double>(key,matrix_in(k,2)));
133 }
134 return tempMap;
135 }
136
137 template<int dim>
138 Eigen::Matrix<double,ClusterDynamicsParameters<dim>::mSize,ClusterDynamicsParameters<dim>::mSize> ClusterDynamicsParameters<dim>::getR1() const
139 {
140 int vIndex, iIndex;
141 for(int k=0;k<mSize;k++)
142 {
143 if(fabs(msVector(k)+1)<FLT_EPSILON)
144 {
145 vIndex=k;
146 }
147 if(fabs(msVector(k)-1)<FLT_EPSILON)
148 {
149 iIndex=k;
150 }
151 }
152 if(iIndex-vIndex!=1 && msVector.matrix().squaredNorm()>0)
153 { // Expected sequence should look like ... -2,-1,+1,+2,+3 ...
154 throw std::runtime_error("intersitital Index must be after vacancy Index.");
155 }
156
157 Eigen::Array<double,1,mSize> aveD(Eigen::Array<double,1,mSize>::Zero());
158 for(int k=0;k<mSize;k++)
159 {
160 aveD(k)=pow(detD.begin()->second(k),1.0/3.0);
161 }
162
163 Eigen::Array<double,1,mSize> rn(Eigen::Array<double,1,mSize>::Zero());
164 for(int k=0;k<mSize;k++)
165 {
166 if(fabs(msVector(k)-1)<FLT_EPSILON || fabs(msVector(k)+1)<FLT_EPSILON)
167 {
168 rn(k)=pow(3.0*this->omega/4.0/M_PI,1.0/3.0);
169 }
170 else
171 {
172 rn(k)=pow(fabs(msVector(k)*this->omega/this->b/M_PI),1.0/2.0);
173 }
174 }
175
176 Eigen::Array<double,1,mSize> alpha(Eigen::Array<double,1,mSize>::Zero());
177 if(vIndex>0)
178 { // Dissociation rate for v-clusters [Christien and Barbu 2005 JNM 346]
179 for(int k=0;k<vIndex;k++)
180 {
181 auto it=reactionMap.find(std::pair<int,int>(k+1,vIndex));
182 if(it!=reactionMap.end())
183 {
184 alpha(k)=it->second*2.0*M_PI*rn(k)*aveD(vIndex)/omega*exp(-Eb(k)/kB/T);
185 }
186 }
187 }
188
189 if(mSize-1-iIndex>1)
190 { // Dissociation rate for i-clusters
191 for(int k=iIndex+1;k<mSize;k++)
192 {
193 auto it=reactionMap.find(std::pair<int,int>(iIndex,k-1));
194 if(it!=reactionMap.end())
195 {
196 // alpha(k)=it->second*2.0*M_PI*rn(k)*aveD(iIndex)/omega*exp(-Eb(k)/kB/T);
197 alpha(k)=it->second*8.0*M_PI*rn(iIndex)*aveD(iIndex)/omega*exp(-Eb(k)/kB/T);
198 }
199 }
200 }
201
202 Eigen::Matrix<double,mSize,mSize> tempR1(Eigen::Matrix<double,mSize,mSize>::Zero());
203 for(int k=0;k<mSize;k++)
204 {
205 // Add other sinks
206 tempR1(k,k) += (-otherSinks(k)*aveD(k));
207 // Add dissociations
208 tempR1(k,k) += (-alpha(k));
209 if(k>0 && k<=vIndex)
210 {
211 tempR1(k,k-1) += alpha(k-1);
212 tempR1(vIndex,k-1) += alpha(k-1);
213 }
214 else if(k>=iIndex && k<mSize-1)
215 {
216 tempR1(k,k+1) += alpha(k+1);
217 tempR1(iIndex,k+1) += alpha(k+1);
218 }
219
220 }
221
222 return tempR1;
223 }
224
225 template<int dim>
226 std::vector<Eigen::Matrix<double,ClusterDynamicsParameters<dim>::mSize,ClusterDynamicsParameters<dim>::mSize>> ClusterDynamicsParameters<dim>::getR2() const
227 {
228
229 Eigen::Array<double,1,mSize> aveD(Eigen::Array<double,1,mSize>::Zero());
230 for(int k=0;k<mSize;k++)
231 {
232 aveD(k)=pow(detD.begin()->second(k),1.0/3.0);
233 }
234
235 Eigen::Array<double,1,mSize> rn(Eigen::Array<double,1,mSize>::Zero());
236 for(int k=0;k<mSize;k++)
237 {
238 if(fabs(msVector(k)-1)<FLT_EPSILON || fabs(msVector(k)+1)<FLT_EPSILON)
239 {
240 rn(k)=pow(3.0*this->omega/4.0/M_PI,1.0/3.0);
241 }
242 else
243 {
244 rn(k)=pow(fabs(msVector(k)*this->omega/this->b/M_PI),1.0/2.0);
245 }
246 }
247
248 std::vector<Eigen::Matrix<double,mSize,mSize>> tempR2;
249 Eigen::Matrix<double,mSize,mSize> R2sum(Eigen::Matrix<double,mSize,mSize>::Zero());
250 double maxCoeff(0.0);
251
252 for(size_t k=0;k<mSize;++k)
253 {
254 Eigen::Matrix<double,mSize,mSize> tempR2_k(Eigen::Matrix<double,mSize,mSize>::Zero());
255 for(const auto& pair : reactionMap)
256 {
257 const auto key=pair.first;
258
259 if(int(k)==key.first || int(k)==key.second)
260 {// (key.first, key.second) consume k_specie
261// if(msVector(key.second)>1.0 && use0DsinkStrength)
262// { // 3D mobile + 1D immobile
263// tempR2_k(key.first ,key.second) -= pair.second*2.0*M_PI*(rn(key.second))*(aveD(key.first))/omega;
264// tempR2_k(key.second,key.first) -= pair.second*2.0*M_PI*(rn(key.second))*(aveD(key.first))/omega;
265// }
266// else
267// { // 3D mobile + 3D mobile
268// tempR2_k(key.first ,key.second) -= pair.second*4.0*M_PI*(rn(key.first)+rn(key.second))*(aveD(key.first)+aveD(key.second))/omega;
269// tempR2_k(key.second ,key.first) -= pair.second*4.0*M_PI*(rn(key.first)+rn(key.second))*(aveD(key.first)+aveD(key.second))/omega;
270// }
271 tempR2_k(key.first ,key.second) -= pair.second*4.0*M_PI*(rn(key.first)+rn(key.second))*(aveD(key.first)+aveD(key.second))/omega;
272 tempR2_k(key.second ,key.first) -= pair.second*4.0*M_PI*(rn(key.first)+rn(key.second))*(aveD(key.first)+aveD(key.second))/omega;
273 }
274 else if( fabs(msVector(key.first)+msVector(key.second)-msVector(k))<FLT_EPSILON )
275 {// (key.first, key.second) generate k_specie
276 const double same= (key.first==key.second) ? 0.5 : 1.0;
277// if(msVector(key.second)>1.0 && use0DsinkStrength)
278// { // 3D mobile + 1D immobile
279// tempR2_k(key.first ,key.second) += same*pair.second*2.0*M_PI*(rn(key.second))*(aveD(key.first))/omega;
280// tempR2_k(key.second ,key.first) += same*pair.second*2.0*M_PI*(rn(key.second))*(aveD(key.first))/omega;
281// }
282// else
283// { // 3D mobile + 3D mobile
284// tempR2_k(key.first ,key.second) += same*pair.second*4.0*M_PI*(rn(key.first)+rn(key.second))*(aveD(key.first)+aveD(key.second))/omega;
285// tempR2_k(key.second ,key.first) += same*pair.second*4.0*M_PI*(rn(key.first)+rn(key.second))*(aveD(key.first)+aveD(key.second))/omega;
286// }
287 tempR2_k(key.first ,key.second) += same*pair.second*4.0*M_PI*(rn(key.first)+rn(key.second))*(aveD(key.first)+aveD(key.second))/omega;
288 tempR2_k(key.second ,key.first) += same*pair.second*4.0*M_PI*(rn(key.first)+rn(key.second))*(aveD(key.first)+aveD(key.second))/omega;
289 }
290 }
291
292 tempR2.push_back(tempR2_k);
293 const double maxCoeffLocal(std::max(std::abs(tempR2.back().maxCoeff()),std::abs(tempR2.back().minCoeff())));
294
295 if((tempR2.back()-tempR2.back().transpose()).norm()/maxCoeffLocal>FLT_EPSILON)
296 {
297 throw std::runtime_error("ClusterDynamicsParameters: R2_"+std::to_string(k)+" is not symmetric.");
298 }
299 maxCoeff=std::max(maxCoeff,maxCoeffLocal);
300 R2sum+=tempR2.back()*msVector(k);
301 }
302
303 if(R2sum.norm()/maxCoeff>FLT_EPSILON)
304 {
305 // throw std::runtime_error("Sum of R2's must be zero.");
306 std::cout<<redBoldColor<<"Warning: Sum of R2 is not zero."<<defaultColor<<std::endl;
307 }
308
309 return tempR2;
310 }
311
312 template<int dim>
313 Eigen::Array<double,1,ClusterDynamicsParameters<dim>::iSize/2> ClusterDynamicsParameters<dim>::getImmobileSpeciesBurgersMagnitude(const GrainContainerType& grains) const
314 {
315 Eigen::Array<double,1,iSize/2> temp(Eigen::Array<double,1,iSize/2>::Zero());
316 const Eigen::Matrix<double,dim,dim> lat(grains.begin()->second->latticeBasis);
317 const Eigen::Matrix<double,dim,iSize/2> localBurgers(lat*immobileSpeciesBurgers);
318
319 for(size_t k=0; k<iSize/2; k++)
320 {
321 temp(k) = (localBurgers.col(k)).norm();
322 }
323
324 std::cout<< "immobileSpeciesBurgersMagnitude: "<<temp<<std::endl;
325 return temp;
326 }
327
328
329 template<int dim>
330 std::map<size_t,std::vector<Eigen::Matrix<double,dim,dim>>> ClusterDynamicsParameters<dim>::getD(const GrainContainerType& grains) const
331 {
332 std::map<size_t,std::vector<Eigen::Matrix<double,dim,dim>>> temp;
333
334 for(const auto& grainPair : grains)
335 {
336 auto grainIter(temp.emplace(grainPair.first,std::vector<Eigen::Matrix<double,dim,dim>>()));
337
338 for(size_t k=0; k<mSize; k++)
339 {
340 Eigen::Matrix<double,dim,dim> Dlocal;
341 Dlocal<< msD0(k,0)*exp(-msEm(k,0)/kB/T), msD0(k,1)*exp(-msEm(k,1)/kB/T), msD0(k,2)*exp(-msEm(k,2)/kB/T),
342 msD0(k,1)*exp(-msEm(k,1)/kB/T), msD0(k,3)*exp(-msEm(k,3)/kB/T), msD0(k,4)*exp(-msEm(k,4)/kB/T),
343 msD0(k,2)*exp(-msEm(k,2)/kB/T), msD0(k,4)*exp(-msEm(k,4)/kB/T), msD0(k,5)*exp(-msEm(k,5)/kB/T);
344
345 // g^T inv(Dg)*g = (C2G*c)^T*inv(Dg)*C2G*c = c^T*C2G^T*inv(Dg)*C2G*c= c^T*inv(inv(C2G)*Dg*inv(C2G^T))*c
346 // c^T*inv(C2G^T*Dg*C2G)*c
347 // Dc=C2G^T*Dg*C2G
348 // Dg = C2G*Dc*C2G^T
349 const Eigen::Matrix<double,dim,dim> Dglobal(grainPair.second->C2G*Dlocal*grainPair.second->C2G.transpose());
350 grainIter.first->second.emplace_back(Dglobal);
351
352 if( fabs(Dglobal.eigenvalues().imag()(0)*Dglobal.eigenvalues().imag()(1)*Dglobal.eigenvalues().imag()(2)) > FLT_EPSILON)
353 {
354 throw std::runtime_error("Diffusion tensor does not have proper eigen values.");
355 }
356 std::cout<<greenColor<<" Diffusion coefficient for "<<k<<":\n"<<Dglobal<<std::endl;
357 }
358 }
359
360 return temp;
361 }
362
363
364 template<int dim>
365 std::vector<Eigen::Matrix<double,dim,dim>> ClusterDynamicsParameters<dim>::getDlocal() const
366 {
367 std::vector<Eigen::Matrix<double,dim,dim>> temp;
368
369 for(size_t k=0; k<mSize; k++)
370 {
371 Eigen::Matrix<double,dim,dim> Dlocal;
372 Dlocal<< msD0(k,0)*exp(-msEm(k,0)/kB/T), msD0(k,1)*exp(-msEm(k,1)/kB/T), msD0(k,2)*exp(-msEm(k,2)/kB/T),
373 msD0(k,1)*exp(-msEm(k,1)/kB/T), msD0(k,3)*exp(-msEm(k,3)/kB/T), msD0(k,4)*exp(-msEm(k,4)/kB/T),
374 msD0(k,2)*exp(-msEm(k,2)/kB/T), msD0(k,4)*exp(-msEm(k,4)/kB/T), msD0(k,5)*exp(-msEm(k,5)/kB/T);
375
376 temp.emplace_back(Dlocal);
377 }
378
379 return temp;
380 }
381
382 template<int dim>
383 std::map<size_t,std::vector<Eigen::Matrix<double,dim,dim>>> ClusterDynamicsParameters<dim>::getInvD() const
384 {
385 std::map<size_t,std::vector<Eigen::Matrix<double,dim,dim>>> temp;
386 for(const auto& pair : D)
387 {
388 auto mapIter(temp.emplace(pair.first,std::vector<Eigen::Matrix<double,dim,dim>>()));
389 for(const auto& d : pair.second)
390 {
391 mapIter.first->second.push_back(d.inverse());
392 }
393 }
394 return temp;
395 }
396
397 template<int dim>
398 std::map<size_t,Eigen::Array<double,ClusterDynamicsParameters<dim>::mSize,1>> ClusterDynamicsParameters<dim>::getDetD() const
399 {
400 std::map<size_t,Eigen::Array<double,mSize,1>> temp;// (1,mSize);
401 for(const auto& pair : D)
402 {
403 auto mapIter(temp.emplace(pair.first,Eigen::Array<double,mSize,1>()));
404 for(int k=0;k<mSize;++k)
405 {
406 mapIter.first->second(k)=pair.second[k].determinant();
407 }
408 }
409 return temp;
410 }
411
412 template<int dim>
413 Eigen::Array<double,1,ClusterDynamicsParameters<dim>::iSize> ClusterDynamicsParameters<dim>::getInitLoopSinks(const Eigen::Array<double,1,iSize> initloopSinks_SI, const double b_SI) const
414 {
415 const Eigen::Array<double,1,iSize/2> initDen = initloopSinks_SI.template block<1,iSize/2>(0,0)*b_SI*b_SI*b_SI;
416 // const Eigen::Array<double,1,iSize/2> initRad = initloopSinks_SI.template block<1,iSize/2>(0,iSize/2)/b_SI;
417 const Eigen::Array<double,1,iSize/2> initRad = initloopSinks_SI.template block<1,iSize/2>(0,iSize/2);
418
419 Eigen::Array<double,1,iSize> temp;
420 temp<< initDen,initRad;
421
422 return temp;
423 }
424
425 template<int dim>
426 Eigen::Array<double,1,ClusterDynamicsParameters<dim>::mSize> ClusterDynamicsParameters<dim>::equilibriumMobileConcentration(const double& stressTrace) const
427 {
428
429 return msVector.abs()*exp(-(msEf-stressTrace*msVector*msRelRelaxVol*omega/3.0)/kB/T);
430 // return msVector.abs()*exp(-msEf/kB/T);
431 }
432
433 template<int dim>
434 Eigen::Array<double,1,ClusterDynamicsParameters<dim>::mSize> ClusterDynamicsParameters<dim>::boundaryMobileConcentration(const double& stressTrace,const double& normalTraction) const
435 {
436 return equilibriumMobileConcentration(stressTrace)*exp(-normalTraction*msVector*omega/kB/T);
437 // return msVector.abs()*exp(-msEf/kB/T);
438 }
439
440 template<int dim>
441 Eigen::Array<double,1,ClusterDynamicsParameters<dim>::mSize> ClusterDynamicsParameters<dim>::dislocationMobileConcentration(const VectorDim& b,
442 const VectorDim& t,
443 const VectorDim& fPK,
444 const MatrixDim& stress) const
445 {
446 const VectorDim bxt(b.cross(t));
447 const double bxtNorm2(bxt.squaredNorm());
448 if(bxtNorm2>FLT_EPSILON)
449 {
450 const double fc(fPK.dot(bxt));
451 return equilibriumMobileConcentration(stress.trace())*exp(-(msVector*omega*fc)/(kB*T*(bxtNorm2+0.05*b.squaredNorm())));
452 }
453 else
454 {// screw direction
455 return Eigen::Array<double,1,ClusterDynamicsParameters<dim>::mSize>::Zero();
456 }
457 }
458
459
460 // sigmoid function of number of vacancies FOR ALL SPECIES
461 template<int dim>
462 Eigen::Array<double,1,ClusterDynamicsParameters<dim>::iSize/2> ClusterDynamicsParameters<dim>::sigmoid(const Eigen::Array<double,1,iSize/2>& n) const
463 {
464 // parameters
465 const Eigen::Array<double,1,iSize/2> n0 = ((nmin+nmax)*(0.5) - n_s);
466 const Eigen::Array<double,1,iSize/2> w = w0*(nmax-nmin);
467
468 return 1.0/(1.0+exp(-(n - n0)/w));
469 }
470
471 // pyramid radius function of V
472 template<int dim>
473 Eigen::Array<double,1,ClusterDynamicsParameters<dim>::iSize/2> ClusterDynamicsParameters<dim>::rpyr(const Eigen::Array<double,1,iSize/2>& n) const
474 {
475 return pow(n*omega/sqrt(8),1.0/3.0); // Vp = sqrt(8)*r^3;
476 }
477
478 // loop radius function of V
479 template<int dim>
480 Eigen::Array<double,1,ClusterDynamicsParameters<dim>::iSize/2> ClusterDynamicsParameters<dim>::rloop(const Eigen::Array<double,1,iSize/2>& n) const
481 {
482 return sqrt(n*omega/(M_PI*b*immobileSpeciesBurgersMagnitude)); // Vl = pi*b*r^2;
483 }
484
485 template<int dim>
486 Eigen::Array<double,1,ClusterDynamicsParameters<dim>::iSize/2> ClusterDynamicsParameters<dim>::sigmoidalVectorInterpolation(const Eigen::Array<double,1,iSize/2>& CI, const Eigen::Array<double,1,iSize/2>& N, const Eigen::Array<double,1,iSize/2>& lowValue, const Eigen::Array<double,1,iSize/2>& highValue) const
487 {
488 const Eigen::Array<double,1,iSize/2> n = CI/N/omega;
489
490 return highValue*sigmoid(n) + lowValue*(1.0 - sigmoid(n));
491 }
492
493 template<int dim>
494 Eigen::Array<double,1,ClusterDynamicsParameters<dim>::iSize/2> ClusterDynamicsParameters<dim>::clusterRadius(const Eigen::Array<double,1,iSize/2>& CI, const Eigen::Array<double,1,iSize/2>& N) const
495 {
496 const Eigen::Array<double,1,iSize/2> n = CI/N/omega;
497
498 return sigmoidalVectorInterpolation(CI,N,rpyr(n),rloop(n));
499 }
500
501 template<int dim>
502 Eigen::Array<double,1,ClusterDynamicsParameters<dim>::iSize/2> ClusterDynamicsParameters<dim>::clusterDensity(const Eigen::Array<double,1,iSize/2>& CI, const Eigen::Array<double,1,iSize/2>& N) const
503 {
504 const Eigen::Array<double,1,iSize/2> n = CI/N/omega;
505 const Eigen::Array<double,1,iSize/2> LoopS = 2.0*M_PI*rloop(n)*N;
506 const Eigen::Array<double,1,iSize/2> PyrS = a_bp*4.0*M_PI*rpyr(n)*N;
507
508 return sigmoidalVectorInterpolation(CI,N,PyrS,LoopS);
509 }
510
511 template<int dim>
512 Eigen::Array<double,dim,dim> ClusterDynamicsParameters<dim>::sigmoidalMatrixInterpolation(const Eigen::Array<double,1,iSize/2>& CI, const Eigen::Array<double,1,iSize/2>& N, const Eigen::Array<double,dim,dim>& lowValue, const Eigen::Array<double,dim,dim>& highValue, const int& index) const
513 {
514 const Eigen::Array<double,1,iSize/2> n = CI/N/omega;
515
516 return highValue*sigmoid(n)(index) + lowValue*(1.0 - sigmoid(n)(index));
517 }
518
519 template<int dim>
520 Eigen::Array<double,1,ClusterDynamicsParameters<dim>::iSize/2> ClusterDynamicsParameters<dim>::sigmoidalPlotVectorInterpolation(const Eigen::Array<double,1,iSize/2>& CI, const Eigen::Array<double,1,iSize/2>& N, const Eigen::Array<double,1,iSize/2>& lowValue, const Eigen::Array<double,1,iSize/2>& highValue) const
521 {
522 const Eigen::Array<double,1,iSize/2> n = CI/N/omega;
523
524 return lowValue*sigmoid(n) + highValue*(1.0 - sigmoid(n));
525 }
526
527 template<int dim>
528 Eigen::Array<double,1,ClusterDynamicsParameters<dim>::iSize/2> ClusterDynamicsParameters<dim>::clusterPlotRadius(const Eigen::Array<double,1,iSize/2>& CI, const Eigen::Array<double,1,iSize/2>& N) const
529 {
530 const Eigen::Array<double,1,iSize/2> n = CI/N/omega;
531
533 }
534
535 template struct ClusterDynamicsParameters<3>;
536
537}
538#endif
the R vector(source to field) R
final point of the source segment t
static std::string redBoldColor
auto eval(const std::shared_ptr< T > &t)
double SplineSegment< dim, corder >::alpha
static std::string greenColor
static std::string defaultColor
const Eigen::Array< double, 1, mSize > otherSinks
Eigen::Array< double, 1, mSize > dislocationMobileConcentration(const VectorDim &b, const VectorDim &t, const VectorDim &fPK, const MatrixDim &stress) const
const Eigen::Array< double, 1, iSize/2 > nmax
const Eigen::Array< double, 1, iSize/2 > n_min
ClusterDynamicsParameters(const DefectiveCrystalBase< dim > &ddBase)
Eigen::Array< double, 1, iSize/2 > clusterRadius(const Eigen::Array< double, 1, iSize/2 > &CI, const Eigen::Array< double, 1, iSize/2 > &N) const
const Eigen::Array< double, 2, mSize > discreteDislocationBias
Eigen::Array< double, 1, iSize/2 > getImmobileSpeciesBurgersMagnitude(const GrainContainerType &grains) const
Eigen::Array< double, 1, mSize > equilibriumMobileConcentration(const double &stressTrace) const
const Eigen::Array< double, 1, iSize/2 > nmin
const std::vector< Eigen::Matrix< double, mSize, mSize > > R2
const Eigen::Array< double, 1, mSize > msRelRelaxVol
const std::map< std::pair< int, int >, double > reactionMap
const Eigen::Matrix< double, mSize, dim *(dim+1)/2 > msD0
Eigen::Matrix< double, dim, 1 > VectorDim
const Eigen::Matrix< double, mSize, 1 > G
const Eigen::Array< double, 1, iSize/2 > immobileSpeciesRelRelaxVol
Eigen::Array< double, 1, iSize/2 > sigmoid(const Eigen::Array< double, 1, iSize/2 > &n) const
std::map< size_t, std::vector< Eigen::Matrix< double, dim, dim > > > getInvD() const
std::map< std::pair< int, int >, double > getMap(const Eigen::Array< double, mSize *(mSize+1)/2, 3 > matrix_in) const
const Eigen::Matrix< double, mSize, mSize > R1
const std::map< size_t, std::vector< Eigen::Matrix< double, dim, dim > > > D
Eigen::Matrix< double, dim, dim > MatrixDim
const Eigen::Array< double, 1, mSize > Eb
const Eigen::Matrix< double, dim, iSize/2 > immobileSpeciesBurgers
Eigen::Array< double, 1, iSize > getInitLoopSinks(const Eigen::Array< double, 1, iSize > initloopSinks_SI, const double b_SI) const
Eigen::Array< double, 1, iSize/2 > rpyr(const Eigen::Array< double, 1, iSize/2 > &n) const
Polycrystal< dim >::GrainContainerType GrainContainerType
Eigen::Array< double, 1, iSize/2 > sigmoidalPlotVectorInterpolation(const Eigen::Array< double, 1, iSize/2 > &CI, const Eigen::Array< double, 1, iSize/2 > &N, const Eigen::Array< double, 1, iSize/2 > &lowValue, const Eigen::Array< double, 1, iSize/2 > &highValue) const
const Eigen::Array< double, 1, iSize/2 > dislocationSinks
Eigen::Matrix< double, mSize, mSize > getR1() const
const Eigen::Array< double, 1, mSize > msEf
const Eigen::Matrix< double, mSize, dim *(dim+1)/2 > msEm
Eigen::Array< double, 1, mSize > boundaryMobileConcentration(const double &stressTrace, const double &normalTraction) const
std::map< size_t, Eigen::Array< double, mSize, 1 > > getDetD() const
const Eigen::Matrix< double, mSize, mSize > R1cd
const std::map< size_t, std::vector< Eigen::Matrix< double, dim, dim > > > invD
Eigen::Array< double, 1, iSize/2 > clusterDensity(const Eigen::Array< double, 1, iSize/2 > &CI, const Eigen::Array< double, 1, iSize/2 > &N) const
Eigen::Array< double, dim, dim > sigmoidalMatrixInterpolation(const Eigen::Array< double, 1, iSize/2 > &CI, const Eigen::Array< double, 1, iSize/2 > &N, const Eigen::Array< double, dim, dim > &lowValue, const Eigen::Array< double, dim, dim > &highValue, const int &index) const
const std::map< size_t, Eigen::Array< double, mSize, 1 > > detD
std::vector< Eigen::Matrix< double, dim, dim > > getDlocal() const
const Eigen::Array< double, 1, iSize/2 > immobileSpeciesVector
Eigen::Array< double, 1, iSize/2 > rloop(const Eigen::Array< double, 1, iSize/2 > &n) const
const Eigen::Array< double, 1, mSize > msVector
const Eigen::Array< double, 1, iSize/2 > immobileBias
std::vector< Eigen::Matrix< double, mSize, mSize > > getR2() const
Eigen::Array< double, 1, iSize/2 > clusterPlotRadius(const Eigen::Array< double, 1, iSize/2 > &CI, const Eigen::Array< double, 1, iSize/2 > &N) const
const Eigen::Matrix< double, 1, mSize > msCascadeFractions
std::map< size_t, std::vector< Eigen::Matrix< double, dim, dim > > > getD(const GrainContainerType &grains) const
Eigen::Array< double, 1, iSize/2 > sigmoidalVectorInterpolation(const Eigen::Array< double, 1, iSize/2 > &CI, const Eigen::Array< double, 1, iSize/2 > &N, const Eigen::Array< double, 1, iSize/2 > &lowValue, const Eigen::Array< double, 1, iSize/2 > &highValue) const
const Eigen::Array< double, 1, iSize > initLoopSinks
const Eigen::Array< double, 1, iSize/2 > immobileSpeciesBurgersMagnitude
Eigen::MatrixXd matrix(const Form &form)
REAL w[16]
int index
int k
newbad key
vertex temp
b poly