Mechanics of Defect Evolution Library
Loading...
Searching...
No Matches
ElasticDeformation.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#ifndef model_ElasticDeformation_cpp_
9#define model_ElasticDeformation_cpp_
10
11#ifdef _OPENMP
13#include <omp.h>
14#endif
15
16#include <ElasticDeformation.h>
17
18namespace model
19{
20
21 bool kd(const int& i,const int& j)
22 {
23 return i==j;
24 }
25
26 template <int dim>
27 std::unique_ptr<UniformController<SymmetricVoigtTraits<dim>::voigtSize>> getUniformEDcontroller(const DefectiveCrystalBase<dim>& ddBase)
28 {
29
30 typedef UniformController<SymmetricVoigtTraits<dim>::voigtSize> UniformControllerType;
31 typedef typename UniformControllerType::MatrixVoigt MatrixVoigt;
32 typedef typename UniformControllerType::MatrixVoigt MatrixVoigt;
33
34 // Build stiffness matrix
35 const double mu(ddBase.poly.mu);
36 const double nu(ddBase.poly.nu);
37 const double lam(2.0*nu*mu/(1.0-2.0*nu));
38 MatrixVoigt C(MatrixVoigt::Zero()); // C_ijkl=lam*d_ij*d_kl+mu*(d_ik*d_jl+d_il*d_jk)
39 for(int vI=0;vI<SymmetricVoigtTraits<dim>::voigtSize;++vI)
40 {
41 const auto& i(ddBase.voigtTraits.tensorIndex(vI,0));
42 const auto& j(ddBase.voigtTraits.tensorIndex(vI,1));
43 for(int vJ=0;vJ<SymmetricVoigtTraits<dim>::voigtSize;++vJ)
44 {
45 const auto& k(ddBase.voigtTraits.tensorIndex(vJ,0));
46 const auto& l(ddBase.voigtTraits.tensorIndex(vJ,1));
47 C(vI,vJ)= lam*kd(i,j)*kd(k,l)+mu*(kd(i,k)*kd(j,l)+kd(i,l)*kd(j,k));
48 }
49 }
50
51 TextFileParser parser(ddBase.simulationParameters.traitsIO.inputFilesFolder+"/ElasticDeformation.txt");
52
53 const auto f0(parser.readMatrix<double,SymmetricVoigtTraits<dim>::voigtSize,1>("ExternalStress0",true));
54 const auto f0Dot(parser.readMatrix<double,SymmetricVoigtTraits<dim>::voigtSize,1>("ExternalStressRate",true));
55 const auto g0(parser.readMatrix<double,SymmetricVoigtTraits<dim>::voigtSize,1>("ExternalStrain0",true));
56 const auto g0Dot(parser.readMatrix<double,SymmetricVoigtTraits<dim>::voigtSize,1>("ExternalStrainRate",true));
57 const auto stiffnessRatio(parser.readMatrix<double,SymmetricVoigtTraits<dim>::voigtSize,1>("stiffnessRatio",true));
58 const double t0(0.0);
59 return std::unique_ptr<UniformControllerType>(new UniformControllerType(t0,C,stiffnessRatio,g0,g0Dot,f0,f0Dot));
60 }
62 template<int dim>
64 /* init */ MicrostructureBase<dim>("ElasticDeformation",mc)
65 /* init */,useElasticDeformationFEM(this->microstructures.ddBase.elasticDeformation().useElasticDeformationFEM)
68 /* init */,inertiaReliefPenaltyFactor(this->microstructures.ddBase.elasticDeformation().inertiaReliefPenaltyFactor)
69 /* init */,solverInitialized(false)
70 {
72 {
74 }
75 }
76
77 template<int dim>
79 {
80 // Free periodic jumps are solved jointly with the nodal field. Reset the
81 // prescribed offset before solving; the solved gradient is stored afterwards.
82 elasticDeformationFEM->u->setPeriodicGradient(MatrixDim::Zero());
83 }
84
85 template<int dim>
87 {
88 auto settings=getUniformEDcontroller(this->microstructures.ddBase);
89 femLoadController=std::make_shared<FEMControllerType>(elasticDeformationFEM->u,*settings);
90 auto penalty=std::make_shared<GlobalRigidMotionPenalty<typename ElasticDeformationFEM<dim>::TrialFunctionType>>(elasticDeformationFEM->u,inertiaReliefPenaltyFactor,true);
91 auto total=elasticDeformationFEM->bWF+penalty+femLoadController;
92 auto rhs=femLoadController->rightHandSide(Eigen::VectorXd::Zero(elasticDeformationFEM->u->gSize()),0.0,FEMControllerType::Vector6::Zero());
94 weakProblemSolver->setAffineModes(femLoadController->affineModes());
95 weakProblemSolver->setLinearConstraints(femLoadController->constraintRows());
97 }
98
99 template<int dim>
100 void ElasticDeformation<dim>::initializeConfiguration(const DefectiveCrystalConfigIO<dim>& configIO,const std::ofstream& f_file,const std::ofstream& F_labels)
101 {
102 this->lastUpdateTime=this->microstructures.ddBase.simulationParameters.totalTime;
103
105 {
106 const MatrixDim apd(this->microstructures.averagePlasticDistortion());
107 const MatrixDim aps(0.5*(apd+apd.transpose()));
108 uniformLoadController->gs=this->microstructures.ddBase.voigtTraits.m2v(aps,true);
109 }
110 else
111 {
113 if(size_t(configIO.displacementMatrix().size())==elasticDeformationFEM->u->gSize()+elasticDeformationFEM->z->gSize())
114 {
115 std::cout<<" from configIO,"<<std::flush;
116 const size_t nNodes(elasticDeformationFEM->u->fe().nodes().size());
117 *elasticDeformationFEM->u=configIO.displacementMatrix().block(0,0,nNodes,dim).transpose().reshaped(elasticDeformationFEM->u->gSize(),1);
118 *elasticDeformationFEM->z=configIO.displacementMatrix().block(0,dim,nNodes,dim).transpose().reshaped(elasticDeformationFEM->z->gSize(),1);
119 }
120 else
121 {
122 if(configIO.displacementMatrix().size())
123 {
124 throw std::runtime_error("ElasticDeformation: TrialFunction u initializatoin size mismatch");
125 }
126 }
127 zDot.setZero(elasticDeformationFEM->z->gSize());
128 }
129 }
130
131template<int dim>
133{
135 {
136// const MatrixDim apd(this->microstructures.averagePlasticDistortion());
137// const MatrixDim aps(0.5*(apd+apd.transpose()));
138// uniformLoadController->gs=this->microstructures.ddBase.voigtTraits.m2v(aps,true);
139 }
140 else
141 {
142 std::cout<<", zDot "<<std::flush;
143 for(const auto& node : elasticDeformationFEM->z->fe().nodes())
144 {
145 zDot.template segment<dim>(dim*node.gID)=this->microstructures.inelasticDisplacementRate(node.P0,&node,nullptr,nullptr);
146 }
147 }
148}
149
150 template<int dim>
152 {
154 {
155 const MatrixDim apd(this->microstructures.averagePlasticDistortion());
156 const MatrixDim aps(0.5*(apd+apd.transpose()));
157 uniformLoadController->gs=this->microstructures.ddBase.voigtTraits.m2v(aps,true);
158 }
159 else
160 {
163 {
165
166 }
167 const auto& base=this->microstructures.ddBase;
168 Eigen::VectorXd source=Eigen::VectorXd::Zero(elasticDeformationFEM->u->gSize());
169 typename FEMControllerType::Vector6 otherStress=FEMControllerType::Vector6::Zero();
171 // Volume virtual work includes both physical-face tractions and the
172 // work conjugate to free periodic jumps; face-only loading misses the latter.
173 for(const auto& entry : base.fe->elements())
174 {
175 const auto& e=entry.second;
176 for(size_t k=0;k<Q::quadratureOrder;++k)
177 {
178 const auto bary=BarycentricTraits<dim>::x2l(Q::abscissa(k));
179 MatrixDim stress=MatrixDim::Zero();
180 for(const auto& physics : this->microstructures)
181 {
182 if(physics.get()!=static_cast<const MicrostructureBase<dim>*>(this))
183 {
184 stress+=physics->stress(e.position(bary),nullptr,&e,nullptr);
185 }
186 }
187 const auto voigt=base.voigtTraits.m2v(stress,false);
188 const double weight=e.absJ(bary)*Q::weight(k);
189 otherStress+=weight/base.mesh.volume()*voigt;
190 const auto local=(-weight*elasticDeformationFEM->u->sfmDef(e,bary).transpose()*voigt).eval();
191 for(int node=0;node<ElementType::nodesPerElement;++node)
192 {
193 source.template segment<dim>(dim*e.node(node).gID)+=local.template segment<dim>(dim*node);
194 }
195 }
196 }
197 const MatrixDim plastic=this->microstructures.averagePlasticDistortion();
198 const typename FEMControllerType::Vector6 strainOffset=base.voigtTraits.m2v(0.5*(plastic+plastic.transpose()),true)+elasticDeformationFEM->C.ldlt().solve(otherStress);
199 const double time=base.simulationParameters.totalTime;
200 weakProblemSolver->setRightHandSide(femLoadController->rightHandSide(source,time,strainOffset));
201 weakProblemSolver->setLinearConstraintValues(femLoadController->constraintValues(time,strainOffset));
202 weakProblemSolver->solveWithMasterSlaveConstraints();
203 elasticDeformationFEM->u->setPeriodicGradient(femLoadController->gradient(weakProblemSolver->affineCoefficients()));
204
205 // Compute zDot
206 std::cout<<", zDot "<<std::flush;
207// zDot.setZero(elasticDeformationFEM->z->gSize());
208 for(const auto& node : elasticDeformationFEM->z->fe().nodes())
209 {
210 zDot.template segment<dim>(dim*node.gID)=this->microstructures.inelasticDisplacementRate(node.P0,&node,nullptr,nullptr);
211 }
212 }
213 }
214
215 template<int dim>
217 {
218 this->lastUpdateTime=this->microstructures.ddBase.simulationParameters.totalTime;
219
221 {// already updated in solve()
222 }
223 else
224 {
225 // Update z
227 }
228 }
229
230 template<int dim>
232 {
233 return this->microstructures.ddBase.simulationParameters.dtMax;
234 }
235
236 template<int dim>
237 void ElasticDeformation<dim>::output(DefectiveCrystalConfigIO<dim>& configIO,DefectiveCrystalAuxIO<dim>& auxIO,std::ofstream& f_file,std::ofstream& F_labels) const
238 {
240 {
241 const auto epsil(uniformLoadController->grad(this->microstructures.ddBase.simulationParameters.totalTime));
242 const auto sigma(uniformLoadController->flux(this->microstructures.ddBase.simulationParameters.totalTime));
243
244 f_file<<epsil.transpose()<<" "<<sigma.transpose()<<" ";
245
246 if(this->microstructures.ddBase.simulationParameters.runID==0)
247 {
249 {
250 const auto& i(this->microstructures.ddBase.voigtTraits.tensorIndex(k,0)+1); // 1-based notation
251 const auto& j(this->microstructures.ddBase.voigtTraits.tensorIndex(k,1)+1); // 1-based notation
252 const std::string lab("e_"+std::to_string(i)+std::to_string(j));
253 F_labels<<lab<<"\n";
254 }
256 {
257 const auto& i(this->microstructures.ddBase.voigtTraits.tensorIndex(k,0)+1); // 1-based notation
258 const auto& j(this->microstructures.ddBase.voigtTraits.tensorIndex(k,1)+1); // 1-based notation
259 const std::string lab("s_"+std::to_string(i)+std::to_string(j));
260 F_labels<<lab<<"\n";
261 }
262 }
263 }
264 else
265 {
266 const size_t nNodes(elasticDeformationFEM->u->fe().nodes().size());
267 configIO.displacementMatrix().resize(nNodes,dim+dim);
268 configIO.displacementMatrix().block(0,0,nNodes,dim)=elasticDeformationFEM->u->dofVector().reshaped(dim,nNodes).transpose();
269 configIO.displacementMatrix().block(0,dim,nNodes,dim)=elasticDeformationFEM->z->dofVector().reshaped(dim,nNodes).transpose();
270 }
271 }
272
273 template<int dim>
275 {
276 return VectorDim::Zero();
277 }
278
279 template<int dim>
281 {
282 return MatrixDim::Zero();
283 }
284
285 template<int dim>
287 {
288 return MatrixDim::Zero();
289 }
290
291 template<int dim>
292 typename ElasticDeformation<dim>::VectorDim ElasticDeformation<dim>::displacement(const VectorDim& x,const NodeType* const node,const ElementType* const ele,const SimplexDim* const guess) const
293 {
295 {
296 return this->microstructures.ddBase.voigtTraits.v2m(uniformLoadController->grad(this->microstructures.ddBase.simulationParameters.totalTime),true)*x;
297 }
298 else
299 {
300 if(node)
301 {
302 return (*eval(elasticDeformationFEM->u))(*node);
303// return (*eval(elasticDeformationFEM->u))(*node)+(*eval(elasticDeformationFEM->z))(*node);
304 }
305 else
306 {
307 if(ele)
308 {
309 return (*eval(elasticDeformationFEM->u))(*ele,ele->simplex.pos2bary(x));
310// return (*eval(elasticDeformationFEM->u))(*ele,ele->simplex.pos2bary(x))+(*eval(elasticDeformationFEM->z))(*ele,ele->simplex.pos2bary(x));
311
312 }
313 else
314 {
315 return (*eval(elasticDeformationFEM->u))(x,guess);
316// return (*eval(elasticDeformationFEM->u))(x,guess)+(*eval(elasticDeformationFEM->z))(x,guess);
317 }
318 }
319 }
320 }
321
322 template<int dim>
323 typename ElasticDeformation<dim>::MatrixDim ElasticDeformation<dim>::stress(const VectorDim& x,const NodeType* const node,const ElementType* const ele,const SimplexDim* const guess) const
324 {
326 {
327 return this->microstructures.ddBase.voigtTraits.v2m(uniformLoadController->flux(this->microstructures.ddBase.simulationParameters.totalTime),false);
328 }
329 else
330 {
331 if(node)
332 {
333 return this->microstructures.ddBase.voigtTraits.v2m((*eval(elasticDeformationFEM->s))(*node),false);
334 }
335 else
336 {
337 if(ele)
338 {
339 return this->microstructures.ddBase.voigtTraits.v2m((*eval(elasticDeformationFEM->s))(*ele,ele->simplex.pos2bary(x)),false);
340 }
341 else
342 {
343 return this->microstructures.ddBase.voigtTraits.v2m((*eval(elasticDeformationFEM->s))(x,guess),false);
344 }
345 }
346 }
347 }
348
349 template<int dim>
351 {
352 return VectorMSize::Zero();
353 }
354
355 template<int dim>
357 {
358 return VectorISize::Zero();
359 }
360
361 template<int dim>
363 {
365 {
366 return this->microstructures.ddBase.voigtTraits.v2m(uniformLoadController->flux(this->microstructures.ddBase.simulationParameters.totalTime),false);
367 }
368 else
369 {
371 {
372 return MatrixDim::Zero();
373 }
374 return this->microstructures.ddBase.voigtTraits.v2m(elasticDeformationFEM->C*femLoadController->averageStrain(),false);
375 }
376 }
377
378 template struct ElasticDeformation<3>;
379}
380#endif
381
382
383// template <int dim>
384// std::unique_ptr<ExternalLoadControllerBase<dim>> selectExternalLoadController(const DefectiveCrystalBase<dim>& ddBase)
385// {
386// if(ddBase.simulationParameters.externalLoadControllerName=="UniformExternalLoadController")
387// {
388// return std::unique_ptr<ExternalLoadControllerBase<dim>>(new UniformExternalLoadController<dim>(ddBase));
389// }
390// else
391// {
392// std::cout<<"Unknown externalLoadController name "<<ddBase.simulationParameters.externalLoadControllerName<<"No controller applied."<<std::endl;
393// return std::unique_ptr<ExternalLoadControllerBase<dim>>(nullptr);
394// }
395// }
396
397
398//template <int dim>
399//typename VoigtTraits<dim,dim>::VoigtStorageType getVoigtOrder()
400//{
401// typename VoigtTraits<dim,dim>::VoigtStorageType voigtOrder;
402// for(int i=0;i<dim;++i)
403// {
404// for(int j=0;j<dim;++j)
405// {
406// voigtOrder(dim*i+j,0)=i;
407// voigtOrder(dim*i+j,1)=j;
408// }
409// }
410// return voigtOrder;
411//}
412
413//template <int dim>
414//std::unique_ptr<UniformController<dim,dim>> getUniformController(const DefectiveCrystalBase<dim>& ddBase, const VoigtTraits<dim,dim>& vt)
415//{
416// typedef typename UniformController<dim,dim>::MatrixGrad MatrixGrad;
417// typedef typename UniformController<dim,dim>::MatrixGrad MatrixGrad;
418//
419// const double mu(ddBase.poly.mu);
420// const double nu(ddBase.poly.nu);
421// const double lam(2.0*nu*mu/(1.0-2.0*nu));
422//
423// MatrixGrad C(MatrixGrad::Zero()); // C_ijkl=lam*d_ij*d_kl+mu*(d_ik*d_jl+d_il*d_jk)
424// for(int vI=0;vI<VoigtTraits<dim,dim>::voigtSize;++vI)
425// {
426// const auto& i(vt.tensorIndex(vI,0));
427// const auto& j(vt.tensorIndex(vI,1));
428// for(int vJ=0;vJ<VoigtTraits<dim,dim>::voigtSize;++vJ)
429// {
430// const auto& k(vt.tensorIndex(vJ,0));
431// const auto& l(vt.tensorIndex(vJ,1));
432// C(vI,vJ)= lam*kd(i,j)*kd(k,l)+mu*(kd(i,k)*kd(j,l)+kd(i,l)*kd(j,k));
433// }
434// }
435//
436// TextFileParser parser(ddBase.simulationParameters.traitsIO.inputFilesFolder+"/uniformExternalLoadControllerNew.txt");
437//
438// SymmetricVoigtTraits<dim> svt(parser.readMatrix<size_t,SymmetricVoigtTraits<dim>::voigtSize,2>("voigtOrder",true));
439// const auto f0(vt.m2v(svt.v2m(parser.readMatrix<double,SymmetricVoigtTraits<dim>::voigtSize,1>("ExternalStress0",true),false)));
440// const auto f0Dot(vt.m2v(svt.v2m(parser.readMatrix<double,SymmetricVoigtTraits<dim>::voigtSize,1>("ExternalStressRate",true),false)));
441// const auto g0(vt.m2v(svt.v2m(parser.readMatrix<double,SymmetricVoigtTraits<dim>::voigtSize,1>("ExternalStrain0",true),true)));
442// const auto g0Dot(vt.m2v(svt.v2m(parser.readMatrix<double,SymmetricVoigtTraits<dim>::voigtSize,1>("ExternalStrainRate",true),true)));
443// const auto stiffnessRatio(vt.m2v(svt.v2m(parser.readMatrix<double,SymmetricVoigtTraits<dim>::voigtSize,1>("stiffnessRatio",true),false)));
444// const double t0(0.0);
445// std::cout<<f0<<std::endl<<std::endl;
446// std::cout<<f0Dot<<std::endl<<std::endl;
447// std::cout<<g0<<std::endl<<std::endl;
448// std::cout<<g0Dot<<std::endl<<std::endl;
449//
450// return std::unique_ptr<UniformController<dim,dim>>(new UniformController<dim,dim>(t0,C,stiffnessRatio,g0,g0Dot,f0,f0Dot));
451//}
Eigen::Matrix< double, 6, 1 > Vector6
static constexpr int nodesPerElement
const Simplex< dim, dim > & simplex
A const reference to the Simplex that this element refers to.
Eigen::Matrix< double, dim+1, 1 > pos2bary(const Eigen::Matrix< double, dim, 1 > &P) const
Definition Simplex.cpp:374
x
Definition int_R.m:12
auto weakProblem(std::shared_ptr< BWF > bwf, std::shared_ptr< LWF > lwf, WeakProblemOptions options={})
std::unique_ptr< UniformController< SymmetricVoigtTraits< dim >::voigtSize > > getUniformEDcontroller(const DefectiveCrystalBase< dim > &ddBase)
auto eval(const std::shared_ptr< T > &t)
bool kd(const int &i, const int &j)
static VectorHigherDimD x2l(const VectorDimD &X)
MatrixDim averageStress() const override
const std::unique_ptr< ElasticDeformationFEM< dim > > elasticDeformationFEM
MicrostructureBase< dim >::MatrixDim MatrixDim
VectorDim inelasticDisplacementRate(const VectorDim &, const NodeType *const, const ElementType *const, const SimplexDim *const) const override
MicrostructureContainer< dim > MicrostructureContainerType
double getDt() const override
const std::unique_ptr< UniformControllerType > uniformLoadController
MicrostructureBase< dim >::VectorDim VectorDim
VectorMSize mobileConcentration(const VectorDim &, const NodeType *const, const ElementType *const, const SimplexDim *const) const override
MicrostructureBase< dim >::VectorMSize VectorMSize
void initializeConfiguration(const DefectiveCrystalConfigIO< dim > &configIO, const std::ofstream &f_file, const std::ofstream &F_labels) override
MatrixDim averagePlasticDistortionRate() const override
MatrixDim stress(const VectorDim &, const NodeType *const, const ElementType *const, const SimplexDim *const) const override
void output(DefectiveCrystalConfigIO< dim > &configIO, DefectiveCrystalAuxIO< dim > &auxIO, std::ofstream &f_file, std::ofstream &F_labels) const override
MicrostructureBase< dim >::VectorISize VectorISize
MicrostructureBase< dim >::SimplexDim SimplexDim
MatrixDim averagePlasticDistortion() const override
std::shared_ptr< FEMControllerType > femLoadController
ElasticDeformation(MicrostructureContainerType &mc)
UniformController< SymmetricVoigtTraits< dim >::voigtSize > UniformControllerType
MicrostructureBase< dim >::NodeType NodeType
std::shared_ptr< WeakProblemType > weakProblemSolver
VectorDim displacement(const VectorDim &, const NodeType *const, const ElementType *const, const SimplexDim *const) const override
VectorISize immobileClusters(const VectorDim &, const NodeType *const, const ElementType *const, const SimplexDim *const) const override
MicrostructureBase< dim >::ElementType ElementType
MicrostructureBase(const std::string &tag_in, MicrostructureContainer< dim > &m_in)
MicrostructureContainerType & microstructures
A static class template for generating quadrature abcsissas and weights for arbitrary-order and Quadr...
Definition Quadrature.h:50
static constexpr int voigtSize
Definition VoigtTraits.h:21
const double mu
const double nu
Q
int j
REAL t0
int k
int i
int e