@@ -42,6 +42,19 @@ void MateSystem::MieheLinearElasticMaterial(const int &nDim,const double &t,cons
4242 UseHist=0 ;
4343 }
4444
45+ // we use the seventh one to indicate which decomposition method we want to use
46+ // InputParams[7-1]=0--> use strain decomposition(default)
47+ // InputParams[7-1]=1--> use stress decomposition(can be used for anisotropic case and compressive failure!)
48+ int DecompositionMode=0 ;
49+ if (InputParams.size ()==7 ){
50+ if (int (InputParams[0 ])==0 ){
51+ DecompositionMode=0 ;
52+ }
53+ else {
54+ DecompositionMode=1 ;
55+ }
56+ }
57+
4558 // *********************************************
4659 // *** IMPORTANT!!!
4760 // *** in this model, d=0--->for undamaged case
@@ -77,51 +90,102 @@ void MateSystem::MieheLinearElasticMaterial(const int &nDim,const double &t,cons
7790 Strain=(_Rank2Materials[2 ]+_Rank2Materials[2 ].Transpose ())*0.5 ;
7891 // our total strain
7992 _Rank2Materials[0 ]=Strain;
80-
93+
94+
8195 RankTwoTensor eigvec (0.0 );
8296 double eigval[3 ];
8397
84- RankFourTensor ProjPos=Strain. CalcPostiveProjTensor (eigval,eigvec );
98+ RankFourTensor ProjPos ( 0.0 );
8599 RankFourTensor I4Sym (RankFourTensor::InitIdentitySymmetric4);
86- RankFourTensor ProjNeg=I4Sym-ProjPos ;
100+ RankFourTensor ProjNeg ( 0.0 ) ;
87101
88- StrainPos=ProjPos.DoubleDot (Strain);
89- StrainNeg=Strain-StrainPos;
90-
91- double StrainTrace=Strain.Trace ();
92-
93- double TrPos= (abs (StrainTrace)+StrainTrace)*0.5 ;
94- double TrNeg=-(abs (StrainTrace)-StrainTrace)*0.5 ;
102+ double StrainTrace,TrPos,TrNeg;
95103
96104 // now we can split the positive and negative stress
97105 RankTwoTensor I (0.0 );
98- I.SetToIdentity ();// Unity tensor
99- StressPos=I*lambda*TrPos+StrainPos*2.0 *mu;
100- StressNeg=I*lambda*TrNeg+StrainNeg*2.0 *mu;
101- // now we can have the final stress
102- double d=gpU[nDim];
103- if (d<1.0e-2 ) d=1.0e-2 ;
104- if (d>1.0 -1.0e-2 ) d=1.0 -1.0e-2 ;
106+
105107 const double k=1.0e-3 ; // to avoid the zero stiffness matrix
106- Stress=((1 -d)*(1 -d)+k)*StressPos+StressNeg;
107- // store the stress and dstress/dd in rank2 material
108- _Rank2Materials[1 ]=Stress;
109- _Rank2Materials[2 ]=(-2 +2 *d)*StressPos;// dStress/dD
110- // for our constitutive law
108+ double d;
111109 double SignPos,SignNeg;
112- SignPos=0.0 ;
113- if (StrainTrace>=0.0 ) SignPos=1.0 ;
114- SignNeg=0.0 ;
115- if (StrainTrace<=0.0 ) SignNeg=1.0 ;
116- _Rank4Materials[0 ]=(I.CrossDot (I)*lambda*SignPos+ProjPos*2 *mu)*((1 -d)*(1 -d)+k)
117- +(I.CrossDot (I)*lambda*SignNeg+ProjNeg*2 *mu);
110+ double Psi,PsiPos,PsiNeg;
118111
112+ if (DecompositionMode==0 ){
113+ // We use the strain decomposition for isotropic case
114+ ProjPos=Strain.CalcPostiveProjTensor (eigval,eigvec);
115+ ProjNeg=I4Sym-ProjPos;
119116
120- // for the fracture free energy
121- double Psi,PsiPos,PsiNeg;
122- PsiPos=0.5 *lambda*TrPos*TrPos+mu*((StrainPos*StrainPos).Trace ());
123- PsiNeg=0.5 *lambda*TrNeg*TrNeg+mu*((StrainNeg*StrainNeg).Trace ());
124- Psi=(1 -d)*(1 -d)*PsiPos+PsiNeg;
117+ StrainPos=ProjPos.DoubleDot (Strain);
118+ StrainNeg=Strain-StrainPos;
119+
120+ StrainTrace=Strain.Trace ();
121+
122+ TrPos= (abs (StrainTrace)+StrainTrace)*0.5 ;
123+ TrNeg=-(abs (StrainTrace)-StrainTrace)*0.5 ;
124+
125+ // now we can split the positive and negative stress
126+ I.SetToIdentity ();// Unity tensor
127+ StressPos=I*lambda*TrPos+StrainPos*2.0 *mu;
128+ StressNeg=I*lambda*TrNeg+StrainNeg*2.0 *mu;
129+ // now we can have the final stress
130+ d=gpU[nDim];
131+ if (d<1.0e-2 ) d=1.0e-2 ;
132+ if (d>1.0 -1.0e-2 ) d=1.0 -1.0e-2 ;
133+
134+ Stress=((1 -d)*(1 -d)+k)*StressPos+StressNeg;
135+ // store the stress and dstress/dd in rank2 material
136+ _Rank2Materials[1 ]=Stress;
137+ _Rank2Materials[2 ]=(-2 +2 *d)*StressPos;// dStress/dD
138+ // for our constitutive law
139+ SignPos=0.0 ;
140+ if (StrainTrace>=0.0 ) SignPos=1.0 ;
141+ SignNeg=0.0 ;
142+ if (StrainTrace<=0.0 ) SignNeg=1.0 ;
143+ _Rank4Materials[0 ]=(I.CrossDot (I)*lambda*SignPos+ProjPos*2 *mu)*((1 -d)*(1 -d)+k)
144+ +(I.CrossDot (I)*lambda*SignNeg+ProjNeg*2 *mu);
145+
146+
147+ // for the fracture free energy
148+ PsiPos=0.5 *lambda*TrPos*TrPos+mu*((StrainPos*StrainPos).Trace ());
149+ PsiNeg=0.5 *lambda*TrNeg*TrNeg+mu*((StrainNeg*StrainNeg).Trace ());
150+ Psi=(1 -d)*(1 -d)*PsiPos+PsiNeg;
151+ }
152+ else if (DecompositionMode==1 ){
153+ // We use the stress to do the decomposition
154+ // in this case, we can apply this model to anisotropic case and compressive failure
155+ // for more details, one is referred to :
156+ // "https://dukespace.lib.duke.edu/dspace/handle/10161/18247"
157+ // Yingjie Liu's thesis:
158+ // "A Computational Framework for Fracture Modeling in Coupled Field Problems"
159+ RankFourTensor ElasticityTensor (0.0 );
160+ ElasticityTensor.SetFromEandNu (EE ,nu);
161+ Stress=ElasticityTensor.DoubleDot (Strain);
162+ ProjPos=Stress.CalcPostiveProjTensor (eigval,eigvec);
163+ ProjNeg=I4Sym-ProjPos;
164+
165+ StressPos=ProjPos.DoubleDot (Stress);
166+ StressNeg=Stress-StressPos;
167+
168+ // Now we store the final stress:
169+ d=gpU[nDim];
170+ if (d<1.0e-2 ) d=1.0e-2 ;
171+ if (d>1.0 -1.0e-2 ) d=1.0 -1.0e-2 ;
172+
173+ // Now the Psi^{+} and Psi^{-} become extremelly easy
174+ PsiPos=0.5 *StressPos.DoubleDot (Strain);
175+ PsiNeg=0.5 *StressNeg.DoubleDot (Strain);
176+
177+ Psi=(1 -d)*(1 -d)*PsiPos+PsiNeg;
178+
179+
180+ _Rank2Materials[1 ]=StressPos*((1 -d)*(1 -d)+k)+StressNeg;
181+
182+ // Now its the dStress/dD term
183+ _Rank2Materials[2 ]=StressPos*(-2 +2 *d);
184+
185+ // For the final jacobian, we can use
186+ _Rank4Materials[0 ]=(I4Sym+((1 -d)*(1 -d)+k)*ProjPos).DoubleDot (ElasticityTensor);
187+ }
188+
125189
126190
127191 // calculate H, and update the history variable
0 commit comments