10#ifndef model_PolyhedronInclusion_cpp_
11#define model_PolyhedronInclusion_cpp_
50 const std::map<
size_t,std::vector<size_t>>& faceIDs,
54 const double& _mobilityReduction,
59 ,
delta(MatrixDim::Identity())
65 VectorDim iC(VectorDim::Zero());
66 for(
const auto& face :
faces)
68 for(
const auto& nodePair : face.second)
70 iC+=nodePair.second/face.second.size()/
faces.size();
74 for(
const auto& face :
faces)
76 VectorDim C(VectorDim::Zero());
77 for(
const auto& nodePair : face.second)
90 C/=face.second.size();
92 VectorDim nA(VectorDim::Zero());
94 const VectorDim P0(face.second.front().second);
95 for(
size_t k=0;
k<face.second.size();++
k)
97 const size_t k1(
k<face.second.size()-1?
k+1 : 0);
100 const VectorDim Pk(face.second[
k].second);
101 const VectorDim Pk1(face.second[k1].second);
102 nA+= 0.5*(Pk-P0).cross(Pk1-Pk);
107 if( (C-iC).dot(nA)<0.0 )
116 for(
const auto& nodePair : face.second)
121 if(!plane.contains(nodePair.second))
123 throw std::runtime_error(
"PolyhedronInclusion: face plane does not include face vertex.");
127 this->emplace(face.first,plane);
134 VectorDim C(VectorDim::Zero());
135 for(
const auto& face :
faces)
137 for(
const auto& nodePair : face.second)
139 C+=nodePair.second/face.second.size()/
faces.size();
154 bool contained(
true);
155 for(
const auto& plane : this->planes())
157 contained=(contained && plane.second.isAbove(
x));
164 const std::map<
size_t,std::vector<size_t>>& faceIDs)
166 std::map<size_t,std::vector<std::pair<size_t,VectorDim>>>
temp;
167 for(
const auto& fID : faceIDs)
169 std::vector<std::pair<size_t,VectorDim>> tempV;
170 for(
const auto& nID : fID.second)
172 const auto nodeIter(nodesMap.find(nID));
173 if(nodeIter!=nodesMap.end())
175 tempV.emplace_back(nID,nodeIter->second.P);
179 throw std::runtime_error(
"PolyhedronInclusion node not found.");
182 temp.emplace(fID.first,tempV);
191 if (
a != 0 &&
b != 0 && le != 0) {
194 double temp =
a * le * abs(
b) / (
b * sqrt((
a *
a +
b *
b) * (
b *
b + le * le)));
198 temp = 1.0-DBL_EPSILON;
200 else if (
temp < -1.0)
202 temp = -1.0+DBL_EPSILON;
204 return -
a / abs(
a) * atan(le /
b) + asin(
temp);
221 double dis = sqrt(
a *
a +
b *
b + le * le);
222 auto adjust_temp = [](
double temp) {
225 return 1.0-DBL_EPSILON;
227 else if (
temp <= -1.0)
229 return -1.0+DBL_EPSILON;
233 if (
a != 0 &&
b != 0 && le != 0) {
234 double temp = adjust_temp(le / dis);
235 return (1.0 / (
b *
b + le * le)) * (
236 -le * dis + le * abs(
a) + (
b *
b + le * le) * atanh(
temp));
240 double temp = adjust_temp(le / dis);
241 return -le / dis + atanh(
temp);
248 if (
b != 0 && le == 0) {
251 else if (
b == 0 && le == 0) {
254 else if (
b == 0 && le != 0) {
255 double temp = adjust_temp(le / dis);
256 return (-dis + abs(
a)) / le + atanh(
temp);
267 if (
a != 0 &&
b != 0 && le != 0) {
268 return b * (
a *
a +
b *
b + le * le - sqrt(
a *
a +
b *
b + le * le) * abs(
a)) / ((
b *
b + le * le) * sqrt(
a *
a +
b *
b + le * le));
271 if (
b != 0 || le != 0) {
272 return b / sqrt(
b *
b + le * le);
279 if (
b != 0 && le == 0) {
280 return (sqrt(
a *
a +
b *
b) - abs(
a)) /
b;
282 else if (
b == 0 && le != 0) {
285 else if (
b == 0 && le == 0) {
331 double dis = sqrt(
a *
a +
b *
b + le * le);
332 if (
a < 0 &&
b != 0 && le != 0) {
333 return a *
b * le / ((
a *
a +
b *
b) * dis) + 2.0 * atan(le /
b) + 2.0 * atan(
a * le / (
b * dis));
335 else if (
a > 0 &&
b != 0 && le != 0) {
336 return a *
b * le / ((
a *
a +
b *
b) * dis) - 2.0 * atan(le /
b) + 2.0 * atan(
a * le / (
b * dis));
345 double dis = sqrt(
a *
a +
b *
b + le * le);
346 auto adjust_temp = [](
double temp) {
349 return 1.0-DBL_EPSILON;
351 else if (
temp <= -1.0)
353 return -1.0+DBL_EPSILON;
357 if (
a < 0 &&
b != 0 && le != 0) {
358 double temp = adjust_temp(le / dis);
359 return -le * (2.0 *
a *
a +
b *
b +
a *
b *
b / dis) / ((
a *
a +
b *
b) * (dis -
a)) + atanh(
temp);
361 else if (
a > 0 &&
b != 0 && le != 0) {
362 double temp = adjust_temp(le / dis);
363 return 2.0 *
a * le / (
b *
b + le * le) + (le / dis) * (-2.0 +
b *
b / (
a *
a +
b *
b) - 2.0 *
a *
a / (
b *
b + le * le)) + atanh(
temp);
367 double temp = adjust_temp(le / dis);
368 return -le / dis + atanh(
temp);
375 if (
b != 0 && le == 0) {
378 else if (
b == 0 && le != 0) {
379 double temp = adjust_temp(le / dis);
380 return 2.0 * (abs(
a) - dis) / le + atanh(
temp);
382 else if (
b == 0 && le == 0) {
393 double dis = sqrt(
a *
a +
b *
b + le * le);
394 if (
a != 0 &&
b != 0 && le != 0) {
395 return (
b / (
b *
b + le * le)) * (-2.0 * abs(
a) + dis + (
a *
a) / dis);
406 if (
b != 0 && le == 0) {
407 return ((2.0 *
a *
a +
b *
b) / dis - 2.0 * abs(
a)) /
b;
409 else if (
b == 0 && le != 0) {
412 else if (
b == 0 && le == 0) {
423 double dis = sqrt(
a *
a +
b *
b + le * le);
424 if (
a != 0 &&
b != 0 && le != 0) {
425 return (
a *
b * le / ((
a *
a +
b *
b) * pow(
b *
b + le * le, 2.0) * dis)) * (
426 2.0 * pow(
a, 4.0) - le * le * (
b *
b + le * le) +
a *
a * (3.0 *
b *
b + le * le) - 2.0 * (
a *
a +
b *
b) * dis * abs(
a)
437 double dis = sqrt(
a *
a +
b *
b + le * le);
438 if (
a != 0 &&
b != 0 && le != 0) {
439 return (
a / (pow(
b *
b + le * le, 2.0) * dis)) * (
440 -pow(
a *
b, 2.0) + (
a *
a +
b *
b) * le * le + pow(le, 4.0) + (
b *
b - le * le) * dis * abs(
a)
447 if (
b != 0 && le == 0) {
448 return a * (-
a *
a / dis + abs(
a)) / (
b *
b);
450 else if (
b == 0 && le != 0) {
451 return a * (dis - abs(
a)) / (le * le);
453 else if (
b == 0 && le == 0) {
454 return 0.5 *
a / abs(
a);
464 double dis = sqrt(
a *
a +
b *
b + le * le);
465 if (
a != 0 &&
b != 0 && le != 0) {
466 return -
a *
b * le * (
467 a *
a + dis * dis - 2.0 * dis * abs(
a)
468 ) / (pow(
b *
b + le * le, 2.0) * dis);
477 double dis = sqrt(
a *
a +
b *
b + le * le);
478 auto adjust_temp = [](
double temp) {
481 return 1.0-DBL_EPSILON;
483 else if (
temp <= -1.0)
485 return -1.0+DBL_EPSILON;
489 if (
a != 0 &&
b != 0 && le != 0) {
490 double temp = adjust_temp(le / dis);
491 return (1.0 / (3.0 * (
a *
a +
b *
b) * pow(
b *
b + le * le, 3.0) * dis)) * (
492 2.0 * pow(
a, 6.0) * le * (-3.0 *
b *
b + le * le) -
b *
b * le * pow(
b *
b + le * le, 2.0) * (3.0 *
b *
b + 4.0 * le * le)
493 -
a *
a * le * (
b *
b + le * le) * (3.0 * pow(
b, 4.0) + pow(le, 4.0)) + pow(
a, 4.0) * (-9.0 * pow(
b, 4.0) * le + pow(le, 5.0))
495 - 2.0 * le * (-3.0 *
b *
b + le * le) * pow(abs(
a), 3.0) / (3.0 * pow(
b *
b + le * le, 3.0))
500 double temp = adjust_temp(le / dis);
501 return -le * (3.0 *
b *
b + 4.0 * le * le) / (3.0 * dis * dis * dis) + atanh(
temp);
508 if (
b != 0 && le == 0) {
511 else if (
b == 0 && le != 0) {
512 double temp = adjust_temp(le / dis);
513 return (1.0 / (3.0 * pow(le, 3.0) * dis)) * (2.0 * pow(
a, 4.0) +
a *
a * le * le - pow(le, 4.0)) - 2.0 * pow(abs(
a), 3.0) / (3.0 * le * le * le) + atanh(
temp);
515 else if (
b == 0 && le == 0) {
526 double dis = sqrt(
a *
a +
b *
b + le * le);
527 if (
a != 0 &&
b != 0 && le != 0) {
528 return (
b / (3.0 * pow(
b *
b + le * le, 3.0) * dis)) * (
529 2.0 * pow(
a, 4.0) * (
b *
b - 3.0 * le * le) +
a *
a * (
b *
b - 3.0 * le * le) * (
b *
b + le * le)
530 + pow(
b *
b + le * le, 2.0) * (2.0 *
b *
b + 3.0 * le * le) - 2.0 * (
b *
b - 3.0 * le * le) * dis * pow(abs(
a), 3.0)
535 return b * (2.0 *
b *
b + 3.0 * le * le) / (3.0 * dis * dis * dis);
542 if (
b != 0 && le == 0) {
543 return (2.0 * pow(
a, 4.0) + pow(
a *
b, 2.0) + 2.0 * pow(
b, 4.0) - 2.0 * dis * pow(abs(
a), 3.0)) / (3.0 * pow(
b, 3.0) * dis);
545 else if (
b == 0 && le != 0) {
548 else if (
b == 0 && le == 0) {
559 double dis = sqrt(
a *
a +
b *
b + le * le);
560 if (
a != 0 &&
b != 0 && le != 0) {
561 return (le / (3.0 * pow(
b *
b + le * le, 3.0) * dis)) * (
562 pow(
a, 4.0) * (6.0 *
b *
b - 2.0 * le * le) +
a *
a * (3.0 *
b *
b - le * le) * (
b *
b + le * le)
563 + le * le * pow(
b *
b + le * le, 2.0) + 2.0 * (-3.0 *
b *
b + le * le) * dis * pow(abs(
a), 3.0)
568 return pow(le, 3.0) / (3.0 * dis * dis * dis);
578 if (
b != 0 && le == 0) {
581 else if (
b == 0 && le != 0) {
582 return (-2.0 * pow(
a, 4.0) - pow(
a * le, 2.0) + pow(le, 4.0) + 2.0 * dis * pow(abs(
a), 3.0)) / (3.0 * dis * pow(le, 3.0));
584 else if (
b == 0 && le == 0) {
595 double dis = sqrt(
a *
a +
b *
b + le * le);
596 if (
a != 0 &&
b != 0 && le != 0) {
597 return (
b / (3.0 * pow(
b *
b + le * le, 3.0) * dis)) * (
598 -2.0 * pow(
a, 4.0) * (
b *
b - 3.0 * le * le) -
a *
a * (
b *
b - 3.0 * le * le) * (
b *
b + le * le)
599 +
b *
b * pow(
b *
b + le * le, 2.0) + 2.0 * (
b *
b - 3.0 * le * le) * dis * pow(abs(
a), 3.0)
604 return pow(
b, 3.0) / (3.0 * dis * dis * dis);
611 if (
b != 0 && le == 0) {
612 return (-2.0 * pow(
a, 4.0) - pow(
a *
b, 2.0) + pow(
b, 4.0) + 2.0 * dis * pow(abs(
a), 3.0)) / (3.0 * dis * pow(
b, 3.0));
614 else if (
b == 0 && le != 0) {
617 else if (
b == 0 && le == 0) {
688 const double psi_val= (-psi.I1_a_a_a * Svnorm[
i] * Svnorm[
j] * Svnorm[
k] - psi.I1_b_b_b * Vnorm[
i] * Vnorm[
j] * Vnorm[
k]
689 - psi.I1_le_le_le * Vdir[
i] * Vdir[
j] * Vdir[
k] - psi.I1_a_a_b * (Svnorm[
i] * Svnorm[
j] * Vnorm[
k] + Svnorm[
i] * Vnorm[
j] * Svnorm[
k] + Vnorm[
i] * Svnorm[
j] * Svnorm[
k])
690 - psi.I1_a_a_le * (Svnorm[
i] * Svnorm[
j] * Vdir[
k] + Svnorm[
i] * Vdir[
j] * Svnorm[
k] + Vdir[
i] * Svnorm[
j] * Svnorm[
k]) - psi.I1_a_b_b * (Svnorm[
i] * Vnorm[
j] * Vnorm[
k] + Svnorm[
j] * Vnorm[
i] * Vnorm[
k] + Svnorm[
k] * Vnorm[
j] * Vnorm[
i])
691 - psi.I1_b_b_le * (Vdir[
i] * Vnorm[
j] * Vnorm[
k] + Vdir[
j] * Vnorm[
i] * Vnorm[
k] + Vdir[
k] * Vnorm[
i] * Vnorm[
j]) - psi.I1_a_le_le * (Svnorm[
i] * Vdir[
j] * Vdir[
k] + Svnorm[
j] * Vdir[
i] * Vdir[
k] + Svnorm[
k] * Vdir[
i] * Vdir[
j])
692 - psi.I1_b_le_le * (Vnorm[
i] * Vdir[
j] * Vdir[
k] + Vnorm[
j] * Vdir[
i] * Vdir[
k] + Vnorm[
k] * Vdir[
i] * Vdir[
j])
693 - psi.I1_a_b_le * (Svnorm[
i] * Vnorm[
j] * Vdir[
k] + Svnorm[
i] * Vnorm[
k] * Vdir[
j] + Svnorm[
j] * Vnorm[
i] * Vdir[
k] + Svnorm[
k] * Vnorm[
i] * Vdir[
j] + Svnorm[
j] * Vnorm[
k] * Vdir[
i] + Svnorm[
k] * Vnorm[
j] * Vdir[
i])) * (-Svnorm[l]);
696 return 0.125/(std::numbers::pi*(1.0-this->
nu))*(psi_val
697 -2.0*this->
nu*delta(
k,l)*PHI(
i,
j)
698 -(1.0-this->
nu)*(PHI(
i,l)*delta(
j,
k)
701 +PHI(
i,
k)*delta(
j,l)));
707 Eigen::Matrix<double,voigtSize,voigtSize>
temp(Eigen::Matrix<double,voigtSize,voigtSize>::Zero());
708 double psi_ijkl[3][3][3][3];
711 for(
const auto& face : faces)
713 const auto&
P0(face.second[0].second);
714 const auto&
P1(face.second[1].second);
715 const auto& P2(face.second[2].second);
716 const VectorDim Svnorm((P1-P0).cross(P2-P1).normalized());
721 const double a(Svnorm.dot(P0-
x));
722 for(
size_t e=0;
e<face.second.size();++
e)
724 const size_t e1(
e<face.second.size()-1?
e+1 : 0);
726 const VectorDim& vp(face.second[e1].second);
727 const VectorDim Vdir((vp-vm).normalized());
728 const VectorDim Vnorm(Vdir.cross(Svnorm));
729 const double b((vp-
x).dot(Vnorm));
730 const double lm((vm-
x).dot(Vdir));
731 const double lp((vp-
x).dot(Vdir));
733 psi.I1_a_a_a=Psi_I1_a_a_a(
a,
b, lp) - Psi_I1_a_a_a(
a,
b, lm);
734 psi.I1_b_b_b=Psi_I1_b_b_b(
a,
b, lp) - Psi_I1_b_b_b(
a,
b, lm);
735 psi.I1_le_le_le=Psi_I1_le_le_le(
a,
b, lp) - Psi_I1_le_le_le(
a,
b, lm);
736 psi.I1_a_a_b=Psi_I1_a_a_b(
a,
b, lp) - Psi_I1_a_a_b(
a,
b, lm);
737 psi.I1_a_a_le=Psi_I1_a_a_le(
a,
b, lp) - Psi_I1_a_a_le(
a,
b, lm);
738 psi.I1_a_b_b=Psi_I1_a_b_b(
a,
b, lp) - Psi_I1_a_b_b(
a,
b, lm);
739 psi.I1_b_b_le=Psi_I1_b_b_le(
a,
b, lp) - Psi_I1_b_b_le(
a,
b, lm);
740 psi.I1_a_le_le=Psi_I1_a_le_le(
a,
b, lp) - Psi_I1_a_le_le(
a,
b, lm);
741 psi.I1_b_le_le=Psi_I1_b_le_le(
a,
b, lp) - Psi_I1_b_le_le(
a,
b, lm);
742 psi.I1_a_b_le=Psi_I1_a_b_le(
a,
b, lp) - Psi_I1_a_b_le(
a,
b, lm);
755 const VectorDim PHI_j(-(Phi_u_II_a(
a,
b, lp) - Phi_u_II_a(
a,
b, lm))*Svnorm
756 -(Phi_u_II_b(
a,
b, lp) - Phi_u_II_b(
a,
b, lm))*Vnorm
757 -(Phi_u_II_le(
a,
b, lp))*Vdir + (Phi_u_II_le(
a,
b, lm))*Vdir);
767 const MatrixDim PHI(-Svnorm*PHI_j.transpose());
779 temp(iV,jV)+=eshelbyTensorComponent(
i,
j,
k,l,PHI,delta,psi,Svnorm,Vnorm,Vdir);
870 return this->eTNorm>FLT_EPSILON?
voigtTraits.v2m(eshelbyTensorVoigt(
x)*
voigtTraits.m2v(this->eT,
true),
true) : MatrixDim::Zero();
879 return strain(
x)-this->eT;
890 if(this->masterID>=0)
892 return MatrixDim::Zero();
895 return this->lambda*elStrain.trace()*MatrixDim::Identity()+2.0*this->
mu*elStrain;
899 const SymmetricVoigtTraits<dim> PolyhedronInclusion<dim>::voigtTraits=
SymmetricVoigtTraits<dim>((
typename SymmetricVoigtTraits<dim>::VoigtSizeMatrixType()<<0,0,1,1,2,2,1,2,0,2,0,1).finished());
EshelbyInclusionBase(const MatrixDim &_eT, const double &_nu, const double &_mu, const double &_mobilityReduction, const int &_phaseID, const std::shared_ptr< SecondPhase< dim > > &sph)
MatrixDim stress(const VectorDim &x) const override
const std::map< size_t, std::vector< std::pair< size_t, VectorDim > > > faces
const std::map< size_t, PolyhedronInclusionNodeIO< dim > > & nodes
static double Psi_I1_a_a_b(double a, double b, double le)
static double Psi_I1_b_le_le(double a, double b, double le)
static double Psi_I1_b_b_le(double a, double b, double le)
static std::map< size_t, std::vector< std::pair< size_t, VectorDim > > > getFaces(const std::map< size_t, PolyhedronInclusionNodeIO< dim > > &nodesMap, const std::map< size_t, std::vector< size_t > > &faceIDs)
static double Psi_I1_a_b_b(double a, double b, double le)
MatrixDim strain(const VectorDim &x) const
static double Phi_u_II_le(double a, double b, double le)
static const SymmetricVoigtTraits< dim > voigtTraits
const std::map< size_t, Plane< dim > > & planes() const
static double Phi_u_II_a(double a, double b, double le)
MatrixDim elasticStrain(const VectorDim &x) const
static double Psi_I1_b_b_b(double a, double b, double le)
static double Psi_I1_a_a_a(double a, double b, double le)
PolyhedronInclusion(const std::map< size_t, PolyhedronInclusionNodeIO< dim > > &nodesMap, const std::map< size_t, std::vector< size_t > > &faceIDs, const MatrixDim &_eT, const double &_nu, const double &_mu, const double &_mobilityReduction, const int &_phaseID, const std::shared_ptr< SecondPhase< dim > > &sph)
static double Psi_I1_a_le_le(double a, double b, double le)
static double Psi_I1_a_b_le(double a, double b, double le)
MatrixVoigtSize eshelbyTensorVoigt(const VectorDim &x) const
double eshelbyTensorComponent(const int &i, const int &j, const int &k, const int &l, const MatrixDim &PHI, const MatrixDim &delta, const Psi_I1 &psi, const VectorDim &Svnorm, const VectorDim &Vnorm, const VectorDim &Vdir) const
static double Psi_I1_a_a_le(double a, double b, double le)
bool contains(const VectorDim &x) const override
static double Psi_I1_le_le_le(double a, double b, double le)
static double Phi_u_II_b(double a, double b, double le)
const SymmetricVoigtTraits< dim > PolyhedronInclusion< dim >::voigtTraits
Eigen::Matrix< double, 3, 1 > VectorDim
Eigen::Matrix< size_t, voigtSize, 2 > VoigtSizeMatrixType