Mechanics of Defect Evolution Library
Loading...
Searching...
No Matches
FirstOrderReaction.h
Go to the documentation of this file.
1
2#ifndef model_FirstOrderReaction_H_
3#define model_FirstOrderReaction_H_
4
5#include <Eigen/Dense>
6#include <EvalFunction.h>
9
10namespace model
11{
12
13template <typename MobileTrialFunctionType, typename ImmobileTrialFunctionType>
14struct FirstOrderReaction : public EvalFunction<FirstOrderReaction<MobileTrialFunctionType,ImmobileTrialFunctionType>>
15{
16
17 constexpr static int rows = MobileTrialFunctionType::rows;
18 constexpr static int cols = rows;
19 constexpr static int iSize = ImmobileTrialFunctionType::rows;
20 constexpr static int mSize = MobileTrialFunctionType::rows;
21 constexpr static int dim = MobileTrialFunctionType::dim;
22
25
27 const std::shared_ptr<ImmobileTrialFunctionType> sink;
28 const std::shared_ptr<ImmobileEvalFunctionType> sinke;
29
30 const Eigen::Matrix<double,rows,1> inFactors;
31 const Eigen::Matrix<double,rows,1> outFactors;
32
33 FirstOrderReaction(const std::shared_ptr<ImmobileTrialFunctionType>& sink_in, const ClusterDynamicsParameters<3>& cdp_in, const PolycrystallineMaterialBase& mat_in) :
34 /* init */ cdp(cdp_in),
35 /* init */ mat(mat_in),
36 /* init */ sink(sink_in),
37 /* init */ sinke(eval(sink_in)),
38 // /* init */ stress(stress_in),
39 // /* init */ stresse(eval(stress_in)),
40 /* init */ inFactors((1.0/cdp.msVector.abs()).matrix()),
41 /* init */ outFactors(cdp.msVector.abs().matrix())
42 {
43
44 }
45
46 // // /**********************************************************************/
47 // Eigen::Array<double,iSize/2,mSize> biasSIPA(const Eigen::Matrix<double,3,3>& ExternalS, const size_t& gID) const
48 // {
49 // const Eigen::Matrix<double,3,3> lat(poly.grains().at(gID).latticeBasis);
50 // const Eigen::Matrix<double,3,1> a1(lat.col(0).normalized());
51 // const Eigen::Matrix<double,3,1> a2(lat.col(1).normalized());
52 // const Eigen::Matrix<double,3,1> a3((a2-a1).normalized());
53 // const Eigen::Matrix<double,3,1> c(lat.col(2).normalized());
54
55 // const Eigen::Matrix<double,iSize/2,1> temp((Eigen::Matrix<double,iSize/2,1>()<< -(ExternalS*c).dot(c)*cdp.omega/cdp.kB/cdp.T, // SIPA c
56 // /* */ -(ExternalS*a1).dot(a1)*cdp.omega/cdp.kB/cdp.T, // SIPA a1
57 // /* */ -(ExternalS*a2).dot(a2)*cdp.omega/cdp.kB/cdp.T, // SIPA a2
58 // /* */ -(ExternalS*a3).dot(a3)*cdp.omega/cdp.kB/cdp.T).finished());
59
60 // return exp((temp*cdp.speciesVector.matrix()).array());
61 // }
62
63 /**********************************************************************/
64 Eigen::Array<double,iSize/2,mSize> biasDRIFT() const
65 {
66 const Eigen::Matrix<double,iSize/2,1> temp(Eigen::MatrixXd::Constant(iSize/2,1,1.0));
67 return (temp*cdp.immobileBias.matrix()).array();
68 }
69
70 /**********************************************************************/
71 Eigen::Array<double,iSize/2,mSize> biasDAD(Eigen::Array<double,1,mSize>& p) const
72 {
73 Eigen::Array<double,iSize/2,mSize> temp(Eigen::Array<double,iSize/2,mSize>::Zero());
74 if(iSize>0)
75 {
76 for(int i=0; i<iSize/2; i++)
77 {
78 for(int j=0;j<mSize;j++)
79 {
80 temp(i,j) = i%(iSize/2)==0 ? p[j] : (p[j]+1.0/p[j]/p[j])/2.0;
81 }
82 }
83 }
84
85 return temp;
86 }
87
88 /**********************************************************************/
89 // Eigen::Matrix<double,iSize,mSize> sinkStrengths(const Eigen::Matrix<double,iSize,1>& sinkValue, const Eigen::Matrix<double,3,3>& ExternalS, const size_t& gID) const
90 Eigen::Matrix<double,iSize,mSize> sinkStrengths(const Eigen::Matrix<double,iSize,1>& sinkValue, const size_t& gID) const
91 {// Get the stress and the grainID in and compute SIPA in sink strengthes
92 // a1, a2, a3 and c can be get in poly.grains.at(grainID).latticeBasis
93
94 Eigen::Matrix<double,iSize,1> correctedSinkValue(sinkValue);
95 for(int dof=0;dof<iSize/2;dof++)
96 { // Corrected sink strength is to adjust for negative values at the barycenter of the quadratic elements where we have a sharp gradient of sink values between two end nodes
97 const double cmin = cdp.n_min(dof)*cdp.omega*correctedSinkValue(dof);
98 if(correctedSinkValue(iSize/2+dof)<cmin)
99 { // defect size cannot be smaller than a minimal value
100 correctedSinkValue(iSize/2+dof)=cmin;
101 }
102 }
103
104 const std::vector<Eigen::Matrix<double,3,3>> Dlocal(cdp.getDlocal());
105 Eigen::Array<double,1,mSize> aveD(Eigen::Array<double,1,mSize>::Zero()); // Average diffusion coefficient
106 Eigen::Array<double,1,mSize> p(Eigen::Array<double,1,mSize>::Zero()); // Diffusion difference
107 for(int k=0;k<mSize;k++)
108 {
109 aveD(k)=pow(Dlocal[k].determinant(),1.0/3.0);
110 p(k) =pow(Dlocal[k](2,2)/Dlocal[k](0,0),1.0/6.0);
111 }
112
113 // const Eigen::Array<double,iSize/2,mSize> ZSIPA(biasSIPA(ExternalS,gID));
114 const Eigen::Array<double,iSize/2,mSize> ZDRIFT(biasDRIFT());
115 const Eigen::Array<double,iSize/2,mSize> ZDAD(biasDAD(p));
116
117 //std::cout<<sinkValue.minCoeff()<<std::endl;
118 assert(correctedSinkValue.minCoeff()>=0.0 && "Sink Value is smaller than or equals 0.");
119 // std::cout<<"sinkValue: \n"<<sinkValue.transpose()<<std::endl;
120
121 // <c> cluster is in pyramidal shape at first
122 //Eigen::Array<double,iSize/2,1> loopRadius( (correctedSinkValue.template block<iSize/2,1>(iSize/2,0).array()/correctedSinkValue.template block<iSize/2,1>(0,0).array()/M_PI/cdp.immobileSpeciesBurgersMagnitude.transpose()).sqrt() );
123 //Eigen::Matrix<double,iSize/2,1> loopsDensity(2.0*M_PI*loopRadius*correctedSinkValue.template block<iSize/2,1>(0,0).array());
124 //loopRadius(0) = cdp.vclusterRadius(correctedSinkValue(iSize/2),correctedSinkValue(0));
125 //loopsDensity(0) = 0.2*4.0*M_PI*loopRadius(0)*correctedSinkValue(0);
126
127 const Eigen::Matrix<double,iSize/2,1> disDensity((Eigen::Matrix<double,iSize/2,1>()<<cdp.dislocationSinks(0), //dislocation density c
128 cdp.dislocationSinks(1), //a1
129 cdp.dislocationSinks(2), //a2
130 cdp.dislocationSinks(3)).finished());
131 const Eigen::Matrix<double,iSize/2,1> defectDensity(cdp.clusterDensity(correctedSinkValue.template block<iSize/2,1>(iSize/2,0).array(),correctedSinkValue.template block<iSize/2,1>(0,0).array()).transpose().matrix());
132 const Eigen::Array<double,iSize/2,mSize> rholD((defectDensity*aveD.matrix()).array());
133 const Eigen::Array<double,iSize/2,mSize> rhodD((disDensity*aveD.matrix()).array());
134
135 // const Eigen::Array<double,iSize/2,mSize> Zloop = ZSIPA*ZDRIFT*ZDAD;
136 const Eigen::Array<double,iSize/2,mSize> Zloop = ZDAD*ZDRIFT;
137 const Eigen::Array<double,iSize/2,mSize> Zpyr(Eigen::Array<double,iSize/2,mSize>::Ones());
138 Eigen::Array<double,iSize/2,mSize> Ztotal(Eigen::Array<double,iSize/2,mSize>::Zero());
139
140 for(int k=0;k<mSize;k++)
141 {
142 Ztotal.col(k) = cdp.sigmoidalVectorInterpolation(correctedSinkValue.template block<iSize/2,1>(iSize/2,0).array(),correctedSinkValue.template block<iSize/2,1>(0,0).array(),Zpyr.col(k),Zloop.col(k));
143 }
144
145 const Eigen::Matrix<double,iSize/2,mSize> loopStrength(Ztotal*rholD); // note that the array multiplication is element-wise
146 const Eigen::Matrix<double,iSize/2,mSize> disStrengh(Zloop*rhodD); // note that the array multiplication is element-wise
147
148 Eigen::Matrix<double,iSize,mSize> sStrengh;
149 sStrengh << loopStrength,
150 disStrengh;
151
152 return sStrengh;
153 }
154 /**********************************************************************/
155
156 // Eigen::Matrix<double,mSize,mSize> buildR1(const Eigen::Matrix<double,iSize,1>& sinkValue, const Eigen::Matrix<double,3,3>& ExternalS, const size_t& gID) const
157 Eigen::Matrix<double,mSize,mSize> buildR1(const Eigen::Matrix<double,iSize,1>& sinkValue, const size_t& gID) const
158 {
159 Eigen::Matrix<double,iSize,mSize> sStrengh(sinkStrengths(sinkValue,gID));
160
161 Eigen::Matrix<double,mSize,mSize> R1sink(Eigen::Matrix<double,mSize,mSize>::Zero());
162 for(int k=0;k<mSize;k++)
163 {
164 R1sink(k,k) -= sStrengh.col(k).sum();
165 }
166
167 return R1sink;
168 }
169 /**********************************************************************/
170 /**********************************************************************/
171
172
173 template<typename ElementType, typename BaryType>
174 const Eigen::Matrix<double,rows,cols> operator() (const ElementType& ele, const BaryType& bary) const
175 {
179
180 const Eigen::Matrix<double,iSize,1> sinkvalue((*sinke)(ele,bary));
181 const Eigen::Matrix<double,iSize/2,1> loopsDensity((Eigen::Matrix<double,iSize/2,1>()<<2.0*M_PI*sinkvalue(0)*sinkvalue(4), // Loop density c
182 /* */ 2.0*M_PI*sinkvalue(1)*sinkvalue(5), // Loop density a1
183 /* */ 2.0*M_PI*sinkvalue(2)*sinkvalue(6), // Loop density a2
184 /* */ 2.0*M_PI*sinkvalue(3)*sinkvalue(7)).finished());
185
186 // const Eigen::Matrix<double,6,1> tempS(stresse(ele,bary));
187 // Eigen::Matrix<double,3,3> ExternalS;
188 // ExternalS(0,0)=tempS(0); // s11
189 // ExternalS(1,1)=tempS(1); // s22
190 // ExternalS(2,2)=tempS(2); // s33
191 // ExternalS(1,0)=tempS(3); // s21
192 // ExternalS(2,1)=tempS(4); // s32
193 // ExternalS(2,0)=tempS(5); // s31
194 // ExternalS(0,1)=ExternalS(1,0); //symm
195 // ExternalS(1,2)=ExternalS(2,1); //symm
196 // ExternalS(0,2)=ExternalS(2,0); //symm
197
198
199 const size_t gID(*(ele.simplex.regionIDs().begin()));
200 // Eigen::Matrix<double,rows,cols> temp(buildR1(sinkvalue,ExternalS,gID));
201 Eigen::Matrix<double,rows,cols> temp(buildR1(sinkvalue,gID));
202
203 return outFactors.asDiagonal()*(temp)*inFactors.asDiagonal();
204 }
205
206};
207
208} // namespace model
209
210#endif
auto eval(const std::shared_ptr< T > &t)
EvalExpression< ImmobileTrialFunctionType > ImmobileEvalFunctionType
Eigen::Matrix< double, iSize, mSize > sinkStrengths(const Eigen::Matrix< double, iSize, 1 > &sinkValue, const size_t &gID) const
static constexpr int iSize
static constexpr int cols
const PolycrystallineMaterialBase & mat
const ClusterDynamicsParameters< dim > & cdp
Eigen::Array< double, iSize/2, mSize > biasDRIFT() const
const Eigen::Matrix< double, rows, 1 > outFactors
const std::shared_ptr< ImmobileEvalFunctionType > sinke
const Eigen::Matrix< double, rows, 1 > inFactors
Eigen::Array< double, iSize/2, mSize > biasDAD(Eigen::Array< double, 1, mSize > &p) const
static constexpr int mSize
FirstOrderReaction(const std::shared_ptr< ImmobileTrialFunctionType > &sink_in, const ClusterDynamicsParameters< 3 > &cdp_in, const PolycrystallineMaterialBase &mat_in)
static constexpr int rows
Eigen::Matrix< double, mSize, mSize > buildR1(const Eigen::Matrix< double, iSize, 1 > &sinkValue, const size_t &gID) const
const std::shared_ptr< ImmobileTrialFunctionType > sink
const Eigen::Matrix< double, rows, cols > operator()(const ElementType &ele, const BaryType &bary) const
Eigen::MatrixXd matrix(const Form &form)
int j
vertex p[3]
int k
int i
vertex temp