Mechanics of Defect Evolution Library
Loading...
Searching...
No Matches
DislocationQuadraturePoint.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//Implements non-uniform open quadrature rule
9
10#ifndef model_DislocationQuadraturePoint_cpp_
11#define model_DislocationQuadraturePoint_cpp_
12
15#include <DislocationSegment.h>
16
17
18namespace model
19{
20
21 template<int dim>
23 const int& q,const int& qOrder,
24 const MatrixNcoeff& SFCH,
25 const MatrixNcoeffDim& qH) :
26 /* init */ sourceID(parentSegment.source->sID)
27 /* init */,sinkID(parentSegment.sink->sID)
28 /* init */,qID(q)
29 /* init */,abscissa(QuadratureDynamicType::abscissa(qOrder,qID))
30 /* init */,weight(QuadratureDynamicType::weight(qOrder,qID))
31 /* init */,SF(QuadPowDynamicType::uPow(qOrder).row(qID)*SFCH)
32 /* init */,r(SF*qH)
33 /* init */,ru(QuadPowDynamicType::duPow(qOrder).row(qID)*SFCH.template block<Ncoeff-1,Ncoeff>(1,0)*qH)
34 /* init */,j(ru.norm())
35 /* init */,rl(j > FLT_EPSILON ? (ru/j).eval() : VectorDim::Zero())
36 /* init */,dL(j*weight)
37 /* init */,internalStress(MatrixDim::Zero())
38 /* init */,stress(MatrixDim::Zero())
39 /* init */,pkForce(VectorDim::Zero())
40 /* init */,stackingFaultForce(VectorDim::Zero())
41 /* init */,lineTensionForce(VectorDim::Zero())
42 /* init */,velocity(VectorDim::Zero())
43 /* init */,elasticEnergyPerLength(0.0)
44 /* init */,coreEnergyPerLength(0.0)
45 /* init */,inclusionID(-1)
46 /* init */,slipVectors(std::make_pair(VectorDim::Zero(),VectorDim::Zero()))
47 /* init */,cCD(Eigen::Matrix<double,1,ClusterDynamicsParameters<dim>::mSize>::Zero())
48 /* init */,cDD(Eigen::Matrix<double,1,ClusterDynamicsParameters<dim>::mSize>::Zero())
49 {
50 if(parentSegment.network().inclusions())
51 {
52 for(const auto& inclusion : parentSegment.network().inclusions()->eshelbyInclusions())
53 {// Add EshelbyInclusions stress
54 if(inclusion.second->contains(r))
55 {
56 inclusionID=inclusion.second->sID;
57 break;
58 }
59 }
60 }
61 }
62
63 template<int dim>
65 const size_t sinkID_in,
66 const int& q,const int& qOrder,
67 const MatrixNcoeff& SFCH,
68 const MatrixNcoeffDim& qH) :
69 /* init */ sourceID(sourceID_in)
70 /* init */,sinkID(sinkID_in)
71 /* init */,qID(q)
72 /* init */,abscissa(QuadratureDynamicType::abscissa(qOrder,qID))
73 /* init */,weight(QuadratureDynamicType::weight(qOrder,qID))
74 /* init */,SF(QuadPowDynamicType::uPow(qOrder).row(qID)*SFCH)
75 /* init */,r(SF*qH)
76 /* init */,ru(QuadPowDynamicType::duPow(qOrder).row(qID)*SFCH.template block<Ncoeff-1,Ncoeff>(1,0)*qH)
77 /* init */,j(ru.norm())
78 /* init */,rl(j > FLT_EPSILON ? (ru/j).eval() : VectorDim::Zero())
79 /* init */,dL(j*weight)
80 /* init */,stress(MatrixDim::Zero())
81 /* init */,pkForce(VectorDim::Zero())
82 /* init */,stackingFaultForce(VectorDim::Zero())
83 /* init */,lineTensionForce(VectorDim::Zero())
84 /* init */,velocity(VectorDim::Zero())
85 /* init */,elasticEnergyPerLength(0.0)
86 /* init */,coreEnergyPerLength(0.0)
87 /* init */,inclusionID(-1)
88 /* init */,slipVectors(std::make_pair(VectorDim::Zero(),VectorDim::Zero()))
89 /* init */,cCD(Eigen::Matrix<double,1,ClusterDynamicsParameters<dim>::mSize>::Zero())
90 /* init */,cDD(Eigen::Matrix<double,1,ClusterDynamicsParameters<dim>::mSize>::Zero())
91 {
93 }
94
95 template<int dim>
97 /* init */ sourceID(0)
98 /* init */,sinkID(0)
99 /* init */,qID(0)
100 /* init */,abscissa(0.0)
101 /* init */,weight(0.0)
102 /* init */,SF(Eigen::Matrix<double,1,Ncoeff>::Zero())
103 /* init */,r(VectorDim::Zero())
104 /* init */,ru(VectorDim::Zero())
105 /* init */,j(0.0)
106 /* init */,rl(VectorDim::Zero())
107 /* init */,dL(0.0)
108 /* init */,stress(MatrixDim::Zero())
109 /* init */,pkForce(VectorDim::Zero())
110 /* init */,stackingFaultForce(VectorDim::Zero())
111 /* init */,lineTensionForce(VectorDim::Zero())
112 /* init */,velocity(VectorDim::Zero())
113 /* init */,elasticEnergyPerLength(0.0)
114 /* init */,coreEnergyPerLength(0.0)
115 /* init */,inclusionID(-1)
116 /* init */,slipVectors(std::make_pair(VectorDim::Zero(),VectorDim::Zero()))
117 /* init */,cCD(Eigen::Matrix<double,1,ClusterDynamicsParameters<dim>::mSize>::Zero())
118 /* init */,cDD(Eigen::Matrix<double,1,ClusterDynamicsParameters<dim>::mSize>::Zero())
119 {
120
121 }
122
123 template<int dim>
125 {
127 MatrixDimNdof temp(MatrixDimNdof::Zero());
128 for (size_t n=0;n<Ncoeff;++n)
129 {
130 temp.template block<dim,dim>(0,n*dim)=MatrixDim::Identity()*SF(n);
131 }
132 return temp;
133 }
134
135 template<int dim>
137 const VectorDim& , // position x
138 const VectorDim& fPK,
139 const MatrixDim& S,
140 const VectorDim& rl,
141 const double& dL,
142 const int& inclusionID
143 )
144 {
145 // std::cout<<"parentSegment "<<parentSegment.tag()<<" has slipSystem Compare to nullPtr"<<(parentSegment.slipSystem()==nullptr)<<std::endl;
146
147 if(parentSegment.slipSystem())
148 {
149// VectorDim n(parentSegment.glidePlaneNormal()); // plane normal
150// VectorDim b(parentSegment.burgers()); // Burgers vector
151// VectorDim t(rl); // tangent vector
152//
153// // Select right-handed normal whenever possible
154// if(parentSegment.loopLinks().size()==1)
155// {// pick right-handed normal for n
156// const typename LinkType::LoopLinkType& loopLink(**parentSegment.loopLinks().begin());
157// if(std::fabs(loopLink.loop->slippedArea())>FLT_EPSILON)
158// {
159// if(parentSegment.source->sID!=loopLink.source->sID)
160// {// NetworkLink and LoopLink are oriented in opposite direction
161// b*=-1.0;
162// t*=-1.0;
163// }
164// }
165// }
166
167 const VectorDim& n(parentSegment.slipSystem()->unitNormal);
168 const VectorDim& b(parentSegment.burgers()); // Burgers vector
169 const VectorDim& t(rl); // tangent vector
170
171 VectorDim glideDirection=n.cross(t);
172 const double glideDirectionNorm=glideDirection.norm();
173 if(glideDirectionNorm<FLT_EPSILON)
174 {
175 return VectorDim::Zero();
176 }
177 glideDirection/=glideDirectionNorm;
178 // Curvature is normal to the auxiliary spline tangent, not
179 // necessarily to this quadrature segment. Only its glide component
180 // may drive physical motion (no tangential reparametrization).
181 VectorDim glideForce=fPK.dot(glideDirection)*glideDirection;
182 double glideForceNorm(glideForce.norm());
183
184 if(glideForceNorm<FLT_EPSILON && parentSegment.network().stochasticForceGenerator)
185 {
186 glideForce=-glideDirection;
187 glideForceNorm=glideForce.norm();
188 if(glideForceNorm>FLT_EPSILON)
189 {
190 glideForce/=glideForceNorm;
191 }
192 }
193
194 VectorDim vv=VectorDim::Zero();
195 if(glideForceNorm>FLT_EPSILON)
196 {
197 // std::cout<<"a"<<std::endl;
198
199 // double v =parentSegment.network().poly.mobility->velocity(S,b,t,n,
200 double v =parentSegment.slipSystem()->mobility->velocity(S,b,t,n,
201 parentSegment.network().ddBase.poly.T,
202 dL,parentSegment.network().ddBase.simulationParameters.dt,parentSegment.network().stochasticForceGenerator);
203 // std::cout<<"v is "<<v<<std::endl;
204 if(v<0.0 && v>=-FLT_EPSILON && !parentSegment.network().stochasticForceGenerator)
205 {
206 v=0.0; // kill roundoff errors for small negative velocities
207 }
208
209 if(inclusionID>=0 && parentSegment.network().inclusions())
210 {
211 v*=parentSegment.network().inclusions()->eshelbyInclusions().at(inclusionID)->mobilityReduction;
212 }
213
214 assert((parentSegment.network().stochasticForceGenerator || v>= 0.0) && "Velocity must be a positive scalar");
215 const bool useNonLinearVelocity=true;
216 if(useNonLinearVelocity && v>FLT_EPSILON && !parentSegment.network().stochasticForceGenerator)
217 {
218 v= 1.0-std::exp(-v);
219 }
220
221 vv= v * glideForce/glideForceNorm;
222 }
223 return vv;
224
225 }
226 else
227 {
228 return VectorDim::Zero();
229 }
230
231 }
232
233 template<int dim>
234 void DislocationQuadraturePoint<dim>::updateForcesAndVelocities(const LinkType& parentSegment,const bool& isClimbStep)
235 {
236
237 // Add other stress contributions, and compute PK force
238 MatrixDim externalStress(MatrixDim::Zero());
239 for(const auto& microstructure : parentSegment.network().microstructures)
240 {
241 if(microstructure.get()!=static_cast<const MicrostructureBase<dim>* const>(&parentSegment.network()))
242 {// not the DD physics, which we already accounted for above
243 externalStress += microstructure->stress(r,nullptr,nullptr,parentSegment.source->includingSimplex());
244 }
245 }
246 stress=internalStress+externalStress;
247
248 const bool useSplineTangents(false);
249 if(parentSegment.loopLinks().size()==1 && useSplineTangents)
250 {
251 const auto ll(*parentSegment.loopLinks().begin());
252 const VectorDim prevNodePos(ll->prev->twin()? ll->prev->twin()->source->periodicPrev()->get_P()
253 -ll->source->periodicPlanePatch()->shift
254 +ll->prev->twin()->source->periodicPrev()->periodicPlanePatch()->shift
255 : ll->source->periodicPrev()->get_P());
256 const VectorDim nextNodePos(ll->next->twin()? ll->next->twin()-> sink->periodicNext()->get_P()
257 -ll-> sink->periodicPlanePatch()->shift
258 +ll->next->twin()-> sink->periodicNext()->periodicPlanePatch()->shift
259 : ll-> sink->periodicNext()->get_P());
260
261
262 const VectorDim node0(ll->source->networkNode==parentSegment.source? prevNodePos : nextNodePos);
263 const VectorDim node1(ll->source->networkNode==parentSegment.source? ll->source->get_P() : ll->sink->get_P());
264 const VectorDim node2(ll->source->networkNode==parentSegment.source? ll->sink->get_P() : ll->source->get_P());
265 const VectorDim node3(ll->source->networkNode==parentSegment.source? nextNodePos : prevNodePos);
266
267 CatmullRomSplineSegment<dim> cmSeg(node0,node1,node2,node3);
268 // const double paramU(QuadratureDynamicType::abscissa(parentSegment.quadraturePoints().size(),qID));
269 const VectorDim llunitTangent(cmSeg.get_rl(abscissa));
270
271 pkForce=(stress*parentSegment.burgers()).cross(llunitTangent);
272 const MatrixDim totalStress(stress+forceToStress(stackingFaultForce+lineTensionForce,llunitTangent,parentSegment));
274 velocity=getGlideVelocity(parentSegment,r,totalForce,totalStress,llunitTangent,dL,inclusionID);
275 }
276 else
277 {
278 pkForce=(stress*parentSegment.burgers()).cross(rl);
280 }
281 if(isClimbStep && parentSegment.network().climbSolver)
282 {
283 // cCD=eval(parentSegment.network().climbSolver->CD->mobileClusters)(r,parentSegment.source->includingSimplex());
284 cCD.setZero();
285 for(const auto& microstructure : parentSegment.network().microstructures)
286 {
287 if(microstructure.get()!=static_cast<const MicrostructureBase<dim>* const>(&parentSegment.network()))
288 {// not the DislocationDynamics physics
289 cCD += microstructure->mobileConcentration(r,nullptr,nullptr,parentSegment.source->includingSimplex());
290 }
291 }
292// cDD=parentSegment.network().climbSolver->CD->cdp.dislocationMobileConcentration(parentSegment.burgers(),rl,pkForce,stress);
293 cDD=parentSegment.network().climbSolver->CD->cdp.dislocationMobileConcentration(parentSegment.burgers(),rl,pkForce+lineTensionForce+stackingFaultForce,stress);
294
295 // std::cout<<"concentrations:"<<std::endl;
296// std::cout<<"cCD="<<cCD<<std::endl;
297// std::cout<<"cDD="<<cDD<<std::endl;
298// std::cout<<"cEQ="<<parentSegment.network().climbSolver->CD->cdp.equilibriumMobileConcentration(stress.trace())<<std::endl;
299// std::cout<<"cEQ0="<<parentSegment.network().climbSolver->CD->cdp.equilibriumMobileConcentration(0.0)<<std::endl;
300 }
301 }
302
303 template<int dim>
305 {
306 const double burgersNorm=parentSegment.burgers().norm();
307 VectorDim glideDirection=parentSegment.glidePlaneNormal().cross(unitTangent);
308 const double directionNorm=glideDirection.norm();
309 if(burgersNorm>FLT_EPSILON && directionNorm>FLT_EPSILON)
310 {
311 glideDirection/=directionNorm;
312 const double resolvedForce=force.dot(glideDirection);
313 const VectorDim unitBurgers=parentSegment.burgers()/burgersNorm;
314 const VectorDim normal=parentSegment.glidePlaneNormal();
315 const MatrixDim unitStress=unitBurgers*normal.transpose()+normal*unitBurgers.transpose();
316 const double resolvedUnitForce=((unitStress*parentSegment.burgers()).cross(unitTangent)).dot(glideDirection);
317 if(std::abs(resolvedUnitForce)>FLT_EPSILON)
318 {
319 return (resolvedForce/resolvedUnitForce)*unitStress;
320 }
321 }
322 return MatrixDim::Zero();
323 }
324
325 template struct DislocationQuadraturePoint<3>;
326
327 template<int dim>
328 typename DislocationQuadraturePointContainer<dim>::VectorNdof DislocationQuadraturePointContainer<dim>::nodalVelocityLinearKernel(const int& k) const
329 {
332 return quadraturePoint(k).SFgaussEx().transpose()*quadraturePoint(k).velocity*quadraturePoint(k).j;
333 }
334
335 template<int dim>
336 typename DislocationQuadraturePointContainer<dim>::MatrixNdof DislocationQuadraturePointContainer<dim>::nodalVelocityBilinearKernel(const int& k) const
337 {
343 const MatrixDimNdof SFEx(quadraturePoint(k).SFgaussEx());
344 return SFEx.transpose()*SFEx*quadraturePoint(k).j;
345 }
346
347 template<int dim>
348 typename DislocationQuadraturePointContainer<dim>::VectorDim DislocationQuadraturePointContainer<dim>::pkKernel(const int& k) const
349 {
353 return quadraturePoint(k).pkForce*quadraturePoint(k).j;
354 }
355
356 template<int dim>
357 typename DislocationQuadraturePointContainer<dim>::MatrixDim DislocationQuadraturePointContainer<dim>::stressKernel(const int& k) const
358 {
362 return quadraturePoint(k).stress*quadraturePoint(k).j;
363 }
364
365 template<int dim>
366 typename DislocationQuadraturePointContainer<dim>::VectorDim DislocationQuadraturePointContainer<dim>::glideVelocityKernel(const int& k) const
367 {
368 return quadraturePoint(k).velocity*this->quadraturePoint(k).j;
369 }
370
371 template<int dim>
372 void DislocationQuadraturePointContainer<dim>::updateKernel(const LinkType& parentSegment,
373 const StraightDislocationSegment<dim>& ss,
374 const double& L0,
375 const VectorDim& c)
376 {
377 for(const auto& shift : parentSegment.network().ddBase.periodicShifts)
378 {
379 // std::cout<<"shift="<<shift.transpose()<<std::endl;
380
381 SegmentSegmentDistance<dim> ssd(ss.P0,ss.P1,parentSegment.source->get_P()+shift,parentSegment.sink->get_P()+shift);
382 // const double dr(ssd.dMin/(L0+ss.length));
383 const double dr(ssd.dMin/(L0));
384
385 if(dr<10.0)
386 {// full interaction
387 for (auto& qPoint : quadraturePoints())
388 {
389 // std::cout<<"qPoint="<<qPoint.qID<<", r="<<qPoint.r.transpose()<<std::endl;
390 qPoint.internalStress += ss.stress(qPoint.r+shift);
391 }
392 }
393 else if(dr<100.0)
394 {// 2pt interpolation
395 const MatrixDim stressSource(ss.stress(parentSegment.source->get_P()+shift));
396 const MatrixDim stressSink(ss.stress(parentSegment.sink->get_P()+shift));
397 for (auto& qPoint : quadraturePoints())
398 {
399 qPoint.internalStress += (1.0-qPoint.abscissa)*stressSource+qPoint.abscissa*stressSink;
400 }
401 }
402 else
403 {// 1pt interpolation
404 const MatrixDim stressC(ss.stress(c+shift));
405 for (auto& qPoint : quadraturePoints())
406 {
407 qPoint.internalStress += stressC;
408 }
409 }
410
411 if(parentSegment.network().computeElasticEnergyPerLength)
412 {
413 for (auto& qPoint : quadraturePoints())
414 {
415 qPoint.elasticEnergyPerLength += ss.elasticInteractionEnergy(qPoint.r+shift,qPoint.rl,parentSegment.burgers());
416 }
417 }
418
419 }
420 }
421
422 template<int dim>
423 void DislocationQuadraturePointContainer<dim>::update(const LinkType& parentSegment,const bool& isClimbStep)
424 {
425 // std::cout<<parentSegment.tag()<<" updating"<<std::endl;
426
427 const bool useLoopBasedKernels(false);
428
429 if(this->size())
430 {
431 if(parentSegment.network().computeDDinteractions)
432 {
433 const double L0(parentSegment.chord().norm());
434 const VectorDim c(0.5*(parentSegment.source->get_P()+parentSegment.sink->get_P()));
435 if(useLoopBasedKernels)
436 {
437 for(const auto& loop : parentSegment.network().loops())
438 {
439 for(const auto& patch : loop.second.lock()->patches().globalPatches())
440 {
441 for(size_t k0=0;k0<patch.second.size();++k0)
442 {
443 const size_t k1(k0+1<patch.second.size()? k0+1 : 0);
444 const VectorDim& P0(patch.second[k0]);
445 const VectorDim& P1(patch.second[k1]);
446 const VectorDim chord(P1-P0);
447 const double chordLength(chord.norm());
448 if(chordLength>FLT_EPSILON)
449 {
450 const VectorDim tangent(chord/chordLength);
451 // const StraightDislocationSegment<dim> ss(parentSegment.network().poly,P0-patch.first->shift,P1-patch.first->shift,loop.second.lock()->burgers(),chordLength,tangent);
452 const StraightDislocationSegment<dim> ss(parentSegment.network().ddBase.poly,P0,P1,loop.second.lock()->burgers(),chordLength,tangent,parentSegment.network().ddBase.dislocationDynamics().EwaldLength);
453 updateKernel(parentSegment,ss,L0,c);
454 }
455 }
456 }
457 }
458 }
459 else
460 {
461 for(const auto& link : parentSegment.network().networkLinks())
462 {
463 if(!link.second.lock()->hasZeroBurgers())
464 {
465 const StraightDislocationSegment<dim>& ss(link.second.lock()->straight);
466 updateKernel(parentSegment,ss,L0,c);
467 }
468 }
469 }
470 }
471
472 // Stacking fault contribution in the matrix
473 if(parentSegment.slipSystem() && parentSegment.glidePlanes().size()==1)
474 {
475 const auto& glidePlane(**parentSegment.glidePlanes().begin());
476 const auto& slipSystem(*parentSegment.slipSystem());
477
478
479 // Add stacking fault force
480 const double eps=1.0e-2;
481 VectorDim outDir(parentSegment.unitDirection().cross(slipSystem.unitNormal));
482 const double outDirNorm(outDir.norm());
483 if(outDirNorm>FLT_EPSILON)
484 {
485 outDir/=outDirNorm;
486 std::vector<std::pair<VectorDim,VectorDim>> qPointSlip(quadraturePoints().size(),std::make_pair(VectorDim::Zero(),VectorDim::Zero())); // accumulated slip vectors (outside,inside) for each qPoint
487
488 for(const auto& weakSourceLoop : parentSegment.network().loops())
489 {
490 const auto sourceLoop(weakSourceLoop.second.lock());
491 if(sourceLoop->slipSystem())
492 {
493 if(slipSystem.n.base()==sourceLoop->slipSystem()->n.base()) // "opposite" slip systems have same normal and opposite slip directions, so this is ok
494 {// same glide plane family
495
496 for(auto& qPoint : quadraturePoints())
497 {
498 if(qPoint.inclusionID>=0 || sourceLoop->slipSystem()->isPartial())
499 {// point inside inclusion, or contribution of a partial slip system
500 qPoint.slipVectors.first -=sourceLoop->patches().windingNumber(qPoint.r + eps*outDir)*sourceLoop->burgers(); // slip vector is negative the burgers vector. windingNumber will skip parallel planes
501 qPoint.slipVectors.second-=sourceLoop->patches().windingNumber(qPoint.r - eps*outDir)*sourceLoop->burgers(); // slip vector is negative the burgers vector. windingNumber will skip parallel planes
502 }
503 }
504 }
505 }
506 }
507
508 for(auto& qPoint : quadraturePoints())
509 {
510 if((qPoint.slipVectors.first-qPoint.slipVectors.second).squaredNorm()>FLT_EPSILON)
511 {
512 // auto& qPoint(loopLink->networkLink()->quadraturePoints()[q]);
513 if(qPoint.inclusionID<0)
514 {// qPoint is not inside an inclusion, we use the matrix gamma-surface
515
516 const double gamma1(slipSystem.n.misfitEnergy(qPoint.slipVectors.first)); // outer point
517 const double gamma2(slipSystem.n.misfitEnergy(qPoint.slipVectors.second)); // inner point
518
519 double gammaNoise(0.0);
520 if(slipSystem.planeNoise)
521 {
522 gammaNoise=std::get<2>(slipSystem.gridInterp(qPoint.r-glidePlane.P));
523 }
524 qPoint.stackingFaultForce+= -(gamma2-gamma1+gammaNoise)*outDir;
525 }
526 else
527 {// qPoint is inside an inclusion, we use the inclusion gamma-surface
528
529 const auto& secondPhase(parentSegment.network().inclusions()->eshelbyInclusions().at(qPoint.inclusionID)->secondPhase);
530 if(secondPhase)
531 {
532 const double gamma1(secondPhase->misfitEnergy(qPoint.slipVectors.first ,&slipSystem.n)); // outer point
533 const double gamma2(secondPhase->misfitEnergy(qPoint.slipVectors.second,&slipSystem.n)); // inner point
534 qPoint.stackingFaultForce+= -(gamma2-gamma1)*outDir;
535 }
536 }
537 }
538 }
539 }
540
541 // Add solid-soution noise
542 if(slipSystem.planeNoise)
543 {
544 for (auto& qPoint : quadraturePoints())
545 {
546 const auto noiseVal(slipSystem.gridInterp(qPoint.r-glidePlane.P));
547 qPoint.internalStress += std::get<0>(noiseVal);
548 }
549 }
550 }
551
552 for (auto& qPoint : quadraturePoints())
553 {
554
555 //Add line tension contribution
556 if (parentSegment.network().alphaLineTension>0.0 && !parentSegment.hasZeroBurgers() && parentSegment.chordLength()>FLT_EPSILON)
557 {
558 //Add the line tension contribution due to only non -zero segments
559 // for (const auto &ll : parentSegment.loopLinks())
560 // {
561 // const double paramU (ll->source->networkNode==parentSegment.source ? qPoint.abscissa : 1.0-qPoint.abscissa);
562 // const auto spline(ll->spline());
563 // const VectorDim llunitTangent(spline.get_rl(paramU));
564 // const double qPointEnergyDensity (parentSegment.network().alphaLineTension * parentSegment.network().ddBase.poly.C2 * (ll->loop->burgers().squaredNorm()-parentSegment.network().ddBase.poly.nu*(std::pow(llunitTangent.dot(ll->loop->burgers()),2))));
565 // qPoint.coreEnergyPerLength+=qPointEnergyDensity;
566 //
567 // const VectorDim rll(spline.get_rll(paramU));
568 // if(!std::isnan(rll.squaredNorm()))
569 // {// curvature can be nan for straight lines
570 // const VectorDim qPointForceVector (qPointEnergyDensity * rll);
571 // qPoint.lineTensionForce+=qPointForceVector;
572 // }
573 // }
574
575 // Collect burgers,tangent,curvature for each loopLink
576 std::vector<std::tuple<VectorDim,VectorDim,VectorDim>> linkSplineVector; // burgers,tangent,curvature
577 for (const auto &ll : parentSegment.loopLinks())
578 {
579 const double paramU (ll->source->networkNode==parentSegment.source ? qPoint.abscissa : 1.0-qPoint.abscissa);
580 const auto spline(ll->spline());
581 linkSplineVector.emplace_back(ll->loop->burgers(),spline.get_rl(paramU),spline.get_rll(paramU));
582 }
583
584 // Compute core energy
585 for(size_t ii=0;ii<linkSplineVector.size();++ii)
586 {
587 for(size_t jj=ii;jj<linkSplineVector.size();++jj)
588 {
589 const double preFactor(ii==jj? parentSegment.network().alphaLineTension * parentSegment.network().ddBase.poly.C2 : 2.0*parentSegment.network().alphaLineTension * parentSegment.network().ddBase.poly.C2);
590 const auto& bii(std::get<0>(linkSplineVector[ii]));
591 const auto& bjj(std::get<0>(linkSplineVector[jj]));
592 const auto& tii(std::get<1>(linkSplineVector[ii]));
593 const auto& tjj(std::get<1>(linkSplineVector[jj]));
594 qPoint.coreEnergyPerLength+=preFactor*(bii.dot(bjj)*tii.dot(tjj)-parentSegment.network().ddBase.poly.nu*bii.dot(tii)*bjj.dot(tii));
595 }
596 }
597
598 // Compute line tension force
599 for(size_t ii=0;ii<linkSplineVector.size();++ii)
600 {
601 const auto& kii(std::get<2>(linkSplineVector[ii]));
602 if(!std::isnan(kii.squaredNorm()))
603 {
604 qPoint.lineTensionForce+=qPoint.coreEnergyPerLength*kii;
605 }
606 }
607 }
608
609// // Add other stress contributions, and compute PK force
610// for(const auto& microstructure : parentSegment.network().microstructures)
611// {
612// if(microstructure.get()!=static_cast<const MicrostructureBase<dim>* const>(&parentSegment.network()))
613// {// not the DD physics, which we already accounted for above
614// qPoint.stress += microstructure->stress(qPoint.r,nullptr,nullptr,parentSegment.source->includingSimplex());
615// }
616// }
617
618 qPoint.updateForcesAndVelocities(parentSegment,isClimbStep);
619 }
620
621 }
622 }
623
624 template<int dim>
625 void DislocationQuadraturePointContainer<dim>::create(const LinkType& parentSegment,
626 const double& quadPerLength,
627 const bool& isClimbStep)
628 {
629
630 this->clear();
631
632 if( !parentSegment.hasZeroBurgers()
633 && !parentSegment.isBoundarySegment()
634 && !parentSegment.isGrainBoundarySegment()
635 && ((parentSegment.isGlissile() && !isClimbStep) || (parentSegment.isSessile() && isClimbStep) || parentSegment.network().computeElasticEnergyPerLength)
636 )
637 {
638 const int order=QuadPowDynamicType::lowerOrder(quadPerLength*parentSegment.chord().norm());
639 const MatrixNcoeff SFCH(parentSegment.sfCoeffs());
640 const MatrixNcoeffDim qH(parentSegment.hermiteDofs());
641 for(int q=0;q<order;++q)
642 {
643 this->emplace_back(parentSegment,q,order,SFCH,qH);
644 }
645 }
646 }
647
648 template<int dim>
649 const typename DislocationQuadraturePointContainer<dim>::DislocationQuadraturePointContainerType& DislocationQuadraturePointContainer<dim>::quadraturePoints() const
650 {
651 return *this;
652 }
653
654 template<int dim>
655 typename DislocationQuadraturePointContainer<dim>::DislocationQuadraturePointContainerType& DislocationQuadraturePointContainer<dim>::quadraturePoints()
656 {
657 return *this;
658 }
659
660 template<int dim>
661 const typename DislocationQuadraturePointContainer<dim>::DislocationQuadraturePointType& DislocationQuadraturePointContainer<dim>::quadraturePoint(const int& k) const
662 {
663 return this->operator[](k);
664 }
665
666 template<int dim>
667 typename DislocationQuadraturePointContainer<dim>::VectorNdof DislocationQuadraturePointContainer<dim>::nodalVelocityVector(const LinkType& parentSegment) const
668 { /*\returns The segment-integrated nodal velocity vector int N^T*v dL
669 */
670 VectorNdof Fq(VectorNdof::Zero());
671 if(parentSegment.chordLength()>FLT_EPSILON)
672 {
673 QuadratureDynamicType::integrate(this->size(),this,Fq,&DislocationQuadraturePointContainerType::nodalVelocityLinearKernel);
674 }
675 return Fq;
676 }
677
678 template<int dim>
679 typename DislocationQuadraturePointContainer<dim>::MatrixNdof DislocationQuadraturePointContainer<dim>::nodalVelocityMatrix(const LinkType& parentSegment) const
680 {
681 // MatrixNdof Kqq(MatrixNdof::Zero());
682 // if(corder==0)
683 // {// Analytical integral can be performed
684 // const double L(parentSegment.chordLength());
685 // Kqq<<L/3.0, 0.0, 0.0, L/6.0, 0.0, 0.0,
686 // /**/ 0.0,L/3.0, 0.0, 0.0,L/6.0, 0.0,
687 // /**/ 0.0, 0.0,L/3.0, 0.0, 0.0,L/6.0,
688 // /**/ L/6.0, 0.0, 0.0, L/3.0, 0.0, 0.0,
689 // /**/ 0.0,L/6.0, 0.0, 0.0,L/3.0, 0.0,
690 // /**/ 0.0, 0.0,L/6.0, 0.0, 0.0,L/3.0;
691 // }
692 // else
693 // {// Numerical integral must be performed
694 // assert(0 && "WE NEED TO INCREASE qOrder FOR THE FOLLOWING INTEGRATION, SINCE EVEN FOR LINEAR SEGMENTS Kqq IS NOT INTEGRATED CORRECLTY FOR SMALL qOrder");
695 // assert(0 && "THIS MUST RETURN A NON_ZERO VALUE EVEN FOR SEGMENTS WHICH DONT HAAVE QUADRATURE POINTS TO CORRECTLY SOVE K*V=F");
696 // QuadratureDynamicType::integrate(this->size(),this,Kqq,&DislocationQuadraturePointContainerType::nodalVelocityBilinearKernel);
697 // }
698 // return Kqq;
699
700 const double L(parentSegment.chordLength());
701 return (MatrixNdof()<<L/3.0, 0.0, 0.0, L/6.0, 0.0, 0.0,
702 /* */ 0.0,L/3.0, 0.0, 0.0,L/6.0, 0.0,
703 /* */ 0.0, 0.0,L/3.0, 0.0, 0.0,L/6.0,
704 /* */ L/6.0, 0.0, 0.0, L/3.0, 0.0, 0.0,
705 /* */ 0.0,L/6.0, 0.0, 0.0,L/3.0, 0.0,
706 /* */ 0.0, 0.0,L/6.0, 0.0, 0.0,L/3.0).finished();
707 }
708
709 template<int dim>
710 typename DislocationQuadraturePointContainer<dim>::VectorDim DislocationQuadraturePointContainer<dim>::glideVelocityIntegral() const
711 {
713 VectorDim V(VectorDim::Zero());
714 QuadratureDynamicType::integrate(this->quadraturePoints().size(),this,V,&DislocationQuadraturePointContainerType::glideVelocityKernel);
715 return V;
716 }
717
718 template<int dim>
719 typename DislocationQuadraturePointContainer<dim>::VectorDim DislocationQuadraturePointContainer<dim>::pkIntegral() const
720 {
722 VectorDim F(VectorDim::Zero());
723 QuadratureDynamicType::integrate(this->quadraturePoints().size(),this,F,&DislocationQuadraturePointContainerType::pkKernel);
724 return F;
725 }
726
727 template<int dim>
728 typename DislocationQuadraturePointContainer<dim>::MatrixDim DislocationQuadraturePointContainer<dim>::stressIntegral() const
729 {
731 MatrixDim stressInt(MatrixDim::Zero());
732 QuadratureDynamicType::integrate(this->quadraturePoints().size(),this,stressInt,&DislocationQuadraturePointContainerType::stressKernel);
733 return stressInt;
734 }
735
737
738}
739#endif
Eigen::Vector3d V
const DislocationQuadraturePointType & quadraturePoint(const int &k) const
VectorNdof nodalVelocityVector(const LinkType &parentSegment) const
void create(const LinkType &parentSegment, const double &quadPerLength, const bool &isClimbStep)
void update(const LinkType &parentSegment, const bool &isClimbStep)
MatrixNdof nodalVelocityMatrix(const LinkType &parentSegment) const
const DislocationQuadraturePointContainerType & quadraturePoints() const
GlidePlaneContainerType glidePlanes() const
const VectorDim & glidePlaneNormal() const
const VectorDim & burgers() const
const std::shared_ptr< SlipSystem > & slipSystem() const
const LoopNetworkType & network() const
Definition NetworkBase.h:57
VectorDim get_rl(const double &u) const
MatrixNcoeff sfCoeffs() const
const VectorDim & unitDirection() const
MatrixNcoeffDim hermiteDofs() const
const VectorDim & chord() const
const double & chordLength() const
the tangent vector S
the magnitude of the R vector q
final point of the source segment t
c
Definition int_R.m:15
b
Definition int_R.m:16
double DislocationSegment< dim >::quadPerLength
const Eigen::Matrix< double, Eigen::Dynamic, pOrder+1 > QuadPow< pOrder, qOrder, QuadratureRule >::uPow
Definition QuadPow.h:112
auto eval(const std::shared_ptr< T > &t)
const Eigen::Matrix< double, Eigen::Dynamic, pOrder > QuadPow< pOrder, qOrder, QuadratureRule >::duPow
Definition QuadPow.h:115
Eigen::Matrix< double, 3, 1 > VectorDim
Definition pyMoDELib.cxx:66
Eigen::Matrix< double, 3, 3 > MatrixDim
Definition pyMoDELib.cxx:67
Eigen::Matrix< double, Ncoeff, dim > MatrixNcoeffDim
const Eigen::Matrix< double, 1, Ncoeff > SF
MatrixDim forceToStress(const VectorDim &force, const VectorDim &unitTangent, const LinkType &parentSegment) const
void updateForcesAndVelocities(const LinkType &parentSegment, const bool &isClimbStep)
std::pair< VectorDim, VectorDim > slipVectors
Eigen::Matrix< double, dim, Ndof > MatrixDimNdof
Eigen::Matrix< double, 1, ClusterDynamicsParameters< dim >::mSize > cDD
Eigen::Matrix< double, dim, dim > MatrixDim
DislocationQuadraturePoint(const LinkType &parentSegment, const int &q, const int &qOrder, const MatrixNcoeff &SFCH, const MatrixNcoeffDim &qH)
Eigen::Matrix< double, Ncoeff, Ncoeff > MatrixNcoeff
QuadratureDynamic< 1, UniformOpen, 1, 2, 3, 4, 5, 6, 7, 8, 16, 32, 64, 128, 256, 512, 1024 > QuadratureDynamicType
Eigen::Matrix< double, 1, ClusterDynamicsParameters< dim >::mSize > cCD
static VectorDim getGlideVelocity(const LinkType &parentSegment, const VectorDim &r, const VectorDim &fPK, const MatrixDim &S, const VectorDim &rl, const double &dL, const int &inclusionID)
Eigen::Matrix< double, dim, 1 > VectorDim
QuadPowDynamic< pOrder, UniformOpen, 1, 2, 3, 4, 5, 6, 7, 8, 16, 32, 64, 128, 256, 512, 1024 > QuadPowDynamicType
newsubseg ss[0]
b order
int ii
int k
vertex temp
REAL v[4]