OOFEM  2.4
OOFEM.org - Object Oriented Finite Element Solver
intmatbilinczfagerstromrate.C
Go to the documentation of this file.
1 /*
2  *
3  * ##### ##### ###### ###### ### ###
4  * ## ## ## ## ## ## ## ### ##
5  * ## ## ## ## #### #### ## # ##
6  * ## ## ## ## ## ## ## ##
7  * ## ## ## ## ## ## ## ##
8  * ##### ##### ## ###### ## ##
9  *
10  *
11  * OOFEM : Object Oriented Finite Element Code
12  *
13  * Copyright (C) 1993 - 2013 Borek Patzak
14  *
15  *
16  *
17  * Czech Technical University, Faculty of Civil Engineering,
18  * Department of Structural Mechanics, 166 29 Prague, Czech Republic
19  *
20  * This library is free software; you can redistribute it and/or
21  * modify it under the terms of the GNU Lesser General Public
22  * License as published by the Free Software Foundation; either
23  * version 2.1 of the License, or (at your option) any later version.
24  *
25  * This program is distributed in the hope that it will be useful,
26  * but WITHOUT ANY WARRANTY; without even the implied warranty of
27  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
28  * Lesser General Public License for more details.
29  *
30  * You should have received a copy of the GNU Lesser General Public
31  * License along with this library; if not, write to the Free Software
32  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
33  */
34 
35 
36 #include "gausspoint.h"
37 #include "floatmatrix.h"
38 #include "floatarray.h"
39 #include "mathfem.h"
40 #include "datastream.h"
41 #include "contextioerr.h"
42 #include "classfactory.h"
45 //#include "vld.h"
46 
47 namespace oofem {
48 
49  REGISTER_Material( IntMatBilinearCZFagerstromRate );
50 
52 {
53  // constructor
54 }
55 
56 
58 {
59  // destructor
60 }
61 
63 void
65  const FloatMatrix &F, TimeStep *tStep)
66 {
67  // returns real stress vector in 3d stress space of receiver according to
68  // previous level of stress and current
69  // strain increment, the only way, how to correctly update gp records
70  //
71 
73 
74  FloatMatrix Finv;
75 
76  Finv.beInverseOf(F);
77  status->letTempInverseDefGradBe(Finv);
78 
79  FloatArray dJ;
80  dJ.beProductOf(Finv,d);
81  status->letTempMaterialJumpBe(dJ);
82 
83  double oldDamage = status->giveDamage();
84  double dAlpha = 0.0;
85  double dt = tStep->giveTimeIncrement();
86 
87  FloatArray Qold(3), Qtemp(3), Qtemp_comp(3);
88  Qtemp.zero();
89  Qtemp_comp.zero();
90 
91  if ( dJ.at(3) < 0 ) {
92  Qtemp_comp.at(3) = this->knc*dJ.at(3);
93  }
94 
95 
96  // SUBROUTINE stress_damage_XFEM_direct_Mandel(dJ,N,Qold,old_alpha,Fci,Q,Ea,new_alpha,adtim,dalpha_new,dalpha_old,diss,sig_f,fall);
97  if (oldDamage < 0.99) {
98  FloatArray Qtrial = status->giveEffectiveMandelTraction();
99 
100  FloatMatrix Kstiff(3,3);
101  FloatArray help;
102 
103  Kstiff.zero();
104  Kstiff.at(1,1) = this->ks0;
105  Kstiff.at(2,2) = this->ks0;
106  Kstiff.at(3,3) = this->kn0;
107 
108 #if 0
109  if (dJ.at(3)>=0) {
110  Kstiff.at(3,3) = this->kn0;
111  } else {
112  Kstiff.at(3,3) = this->kn0/(1-oldDamage);
113  }
114 #endif
115 
116  dJ.subtract(status->giveOldMaterialJump());
117  //dJ.rotatedWith(Rot,'n');
118  //dJ.printYourself();
119 
120  help.beProductOf(Kstiff, dJ);
121  Qtrial.add(help);
122 
123  double Qn = Qtrial.at(3);
124  FloatArray QN(3);
125  QN.zero();
126  QN.at(3) = Qn;
127 
128 
129  FloatArray QtrialShear = Qtrial;
130  QtrialShear.subtract(QN);
131 
132  double Qt = QtrialShear.computeNorm();
133 
134 
135  //double S = this->GIc/this->sigf;
136  double sigf = this->sigf;
137  double gamma = this->gamma;
138  //double gammaGf = this->GIIc/this->GIc;
139  double mu = this->mu;
140  double c_star = this->c_star;
141  double m = this->m;
142  //double S = this->GIc/this->sigf;
143  double S = (this->GIc - pow(sigf,2)/(2*this->kn0))/sigf;
144  double gammaGf = gamma*(this->GIIc - pow(gamma*sigf,2)/(2*this->ks0))/(this->GIc - pow(sigf,2)/(2*this->kn0));
145 
146 
147 
148  double Qn_M = 0.5*(Qn + fabs(Qn));
149 
150 
151  //double loadFun = sigf*pow(Qt/(gamma*sigf),2) + sigf*pow((Qn_M/sigf),2) - sigf; ///@todo Martin: no use of parameter mu!!!
152  double loadFun = sigf*pow(Qt/(gamma*sigf),2) + (sigf/gamma)*(gamma-mu)*pow((Qn_M/sigf),2) - 1/gamma*(gamma*sigf-mu*Qn); // Added support for parameter mu
153 
154  Qold = status->giveEffectiveMandelTraction();
155  Qtemp = Qtrial;
156 
157  //Qold.rotatedWith(Rot,'n');
158 
159  //double alphaOld = status->giveDamage();
160 
161  //if (alphaOld>0.1) {
162  // double bbb=1; ///@todo Should this be used for anything Martin? /JB
163  //}
164 
165  if (loadFun/sigf < 0.0000001) {
166  dAlpha = 0.0; // new_alpha=old_alpha
167  status->letTempEffectiveMandelTractionBe(Qtemp);
168  Qtemp.times(1-oldDamage);
169  } else {
170  // dalpha = datr
171  double Qt1,Qt2;
172  Qt1 = Qtemp.at(1);
173  Qt2 = Qtemp.at(2);
174 
175  FloatArray M(3); // M = (/2*Q_t/(sig_f*gamma**2), 2*Q_n/sig_f, 0.d0/)
176  M.at(1) = 2*Qt1/(pow(gamma,2)*sigf); // Qt = sqrt(Qt1^2 + Qt2^2)
177  M.at(2) = 2*Qt2/(pow(gamma,2)*sigf);
178  M.at(3) = 2*Qn_M/sigf;
179 
180  FloatArray dJElastic;
181  dJElastic = dJ; // dJtn_e(1:2) = dJtn_v(1:2) - S*dalpha*M(1:2)
182  help = M;
183 
184  //dAlpha = (dt/(c_star*S))*pow(loadFun_M/sigf,m)*(1/M_norm);
185  help.times(S*dAlpha);
186  dJElastic.subtract(help);
187 
188  FloatMatrix Smat(4,4), Smati(4,4);
189  FloatArray R(4), inc(4), dJp(3);
190  double loadFunDyn = loadFun;
191 
192  const double errorTol = 0.0001;
193  for( int iter = 1; fabs(loadFunDyn)/sigf > errorTol; iter++) {
194  //printf("loadfun = %e \n",loadFun);
195  //double loadFun_M = 0.5*(loadFun + fabs(loadFun));
196  //double M_norm = sqrt(M.computeSquaredNorm());
197 
198  if (iter>40) {
199  OOFEM_ERROR("BilinearCZMaterialFagerstrom :: giveRealStressVector - no convergence in constitutive driver");
200  }
201  status->letTempDamageDevBe(true);
202  Smat.zero(); // S_mat=0.d0
203 
204  R.at(1) = dJElastic.at(1) - (dJ.at(1) - gammaGf*S*dAlpha*M.at(1)); // R(1:2) = dJtn_e(1:2) - (dJtn_v(1:2) - S*dalpha*M(1:2))
205  R.at(2) = dJElastic.at(2) - (dJ.at(2) - gammaGf*S*dAlpha*M.at(2));
206  R.at(3) = dJElastic.at(3) - (dJ.at(3) - S*dAlpha*M.at(3));
207  if (fabs(c_star)>0) {
208  //R.at(4) = loadFun - c_star*pow((dAlpha/dt),m);
209  //R.at(4) = loadFun - c_star*pow((sqrt(dJ.computeSquaredNorm())/dt),m);
210  dJp = dJ;
211  dJp.subtract(dJElastic);
212  R.at(4) = loadFun - c_star*pow((sqrt(dJp.computeSquaredNorm())/dt),m);
213  //R.at(4) = dAlpha - (dt/(c_star*S))*pow(loadFun_M/sigf,m)*(1/M_norm);
214  } else {
215  R.at(4) = loadFun; // R(3) = F/sig_f
216  }
217 
218  // dMdJtn_e(1,1:2) = (/2/(sig_f*gamma**2),0.d0/)
219  // IF (Q_nM>0) THEN
220  // dMdJtn_e(2,1:2) = (/0.d0,2/sig_f/)
221  // ELSE
222  // dMdJtn_e(2,1:2) = (/0.d0,0.d0/)
223  // END IF
224 
225  // dMdJtn_e = MATMUL(dMdJtn_e,Keye3(1:2,1:2))
226 
227  Smat.at(1,1) = 1.0 + gammaGf*dAlpha*S*2*Kstiff.at(1,1)/(pow(gamma,2)*sigf); // S_mat(1:2,1:2) = eye3(1:2,1:2)+ dalpha*S*dMdJtn_e(1:2,1:2)
228  Smat.at(2,2) = 1.0 + gammaGf*dAlpha*S*2*Kstiff.at(2,2)/(pow(gamma,2)*sigf);
229  //dJElastic.printYourself();
230  if (Qn_M>0) {
231  Smat.at(3,3) = 1.0 + dAlpha*S*2*Kstiff.at(3,3)/(sigf);
232  } else {
233  Smat.at(3,3) = 1.0;
234  }
235 
236  Smat.at(1,4) = gammaGf*S*M.at(1); // S_mat(1:2,3) = S*M(1:2)
237  Smat.at(2,4) = gammaGf*S*M.at(2);
238  Smat.at(3,4) = S*M.at(3);
239 
240  double fac1;
241  if (sqrt(dJp.computeSquaredNorm())>0) {
242  fac1 = c_star*m/(pow(dt,m))*pow(sqrt(dJp.computeSquaredNorm()),m-2);
243  } else {
244  fac1 = 0;
245  }
246 
247 
248  if ( fabs(c_star) > 0 ) { // Rate-dependent case
249  Smat.at(4,1) = M.at(1)*Kstiff.at(1,1) + fac1*dJp.at(1); // S_mat(3,1:2) = MATMUL(M(1:2),Keye3(1:2,1:2))
250  Smat.at(4,2) = M.at(2)*Kstiff.at(2,2) + fac1*dJp.at(2);
251  Smat.at(4,3) = (2*(gamma-mu)/(gamma*sigf)*Qn_M + mu/gamma)*Kstiff.at(3,3) + fac1*dJp.at(3); //Martin: included parameter mu
252  //Smat.at(4,4) = -c_star*m*pow((dAlpha/dt),m-1);
253  //Smat.at(4,1) = -fac1*(fac2*M.at(1)*Kstiff.at(1,1) - fac3*M.at(1)*Kstiff.at(1,1));
254  //Smat.at(4,2) = -fac1*(fac2*M.at(2)*Kstiff.at(2,2) - fac3*M.at(2)*Kstiff.at(2,2));
255  //Smat.at(4,1) = -fac1*(fac2*M.at(3)*Kstiff.at(3,3) - fac4*M.at(3)*Kstiff.at(3,3));
256  //Smat.at(4,4) = 1.0;
257  } else { // Rate-independent case
258  Smat.at(4,1) = M.at(1)*Kstiff.at(1,1); // S_mat(3,1:2) = MATMUL(M(1:2),Keye3(1:2,1:2))
259  Smat.at(4,2) = M.at(2)*Kstiff.at(2,2);
260  //Smat.at(4,3) = M.at(3)*Kstiff.at(3,3);
261  Smat.at(4,3) = (2*(gamma-mu)/(gamma*sigf)*Qn_M + mu/gamma)*Kstiff.at(3,3); //Martin: included parameter mu
262  }
263 
264  //FloatArray inc;
265  //bool transpose = false;
266  //Smat.SolveforRhs(R, inc, transpose);
267 
268  Smati.beInverseOf(Smat);
269 
270  inc.beProductOf(Smati,R);
271 
272  dJElastic.at(1) = dJElastic.at(1) - inc.at(1);
273  dJElastic.at(2) = dJElastic.at(2) - inc.at(2);
274  dJElastic.at(3) = dJElastic.at(3) - inc.at(3);
275  //dJElastic.printYourself();
276  dAlpha = dAlpha - inc.at(4);
277 
278  Qtemp.at(1) = Qold.at(1) + Kstiff.at(1,1)*dJElastic.at(1);
279  Qtemp.at(2) = Qold.at(2) + Kstiff.at(2,2)*dJElastic.at(2);
280  Qtemp.at(3) = Qold.at(3) + Kstiff.at(3,3)*dJElastic.at(3);
281 
282  Qt1 = Qtemp.at(1);
283  Qt2 = Qtemp.at(2);
284  Qt = sqrt(pow(Qt1,2) + pow(Qt2,2));
285  Qn = Qtemp.at(3); // Martin: included parameter mu
286  Qn_M = 0.5*(Qtemp.at(3)+fabs(Qtemp.at(3)));
287 
288  M.at(1) = 2*Qt1/(pow(gamma,2)*sigf); // Qt = sqrt(Qt1^2 + Qt2^2)
289  M.at(2) = 2*Qt2/(pow(gamma,2)*sigf);
290  M.at(3) = 2*Qn_M/sigf;
291 
292  //loadFun = sigf*pow(Qt/(gamma*sigf),2) + sigf*pow((Qn_M/sigf),2) - sigf;
293  loadFun = sigf*pow(Qt/(gamma*sigf),2) + (sigf/gamma)*(gamma-mu)*pow((Qn_M/sigf),2) - 1/gamma*(gamma*sigf-mu*Qn); //Martin: included parameter mu
294  loadFunDyn = loadFun - c_star*pow((sqrt(dJp.computeSquaredNorm())/dt),m);;
295  }
296  //printf("converged, loadfun = %e, oldDamage = %e \n",loadFun, oldDamage);
297  if (oldDamage + dAlpha > 1) {
298  dAlpha = 1. - oldDamage;
299  }
300 
301  FloatMatrix Iep(3,3);
302  IntArray Indx(3);
303  Indx.at(1) = 1;
304  Indx.at(2) = 2;
305  Indx.at(3) = 3;
306 
307  Iep.beSubMatrixOf(Smati,Indx,Indx);
308  status->letTempIepBe(Iep);
309 
310  FloatArray alpha_v(3);
311  alpha_v.at(1) = Smati.at(4,1); // alpha_v(1:2) = S_mati(3,1:2)
312  alpha_v.at(2) = Smati.at(4,2);
313  alpha_v.at(3) = Smati.at(4,3);
314 
315  status->letTempAlphavBe(alpha_v);
316  status->letTempEffectiveMandelTractionBe(Qtemp);
317  Qtemp.times(1-oldDamage-dAlpha);
318 
319  }
320 
321  //Qtemp.rotatedWith(Rot,'t'); // Q=Qe
322  //status->letTempRotationMatrix(Rot);
323  } else {
324  dAlpha = 1.0 - oldDamage;
325  dJ = status->giveTempJump();
326  status->letTempEffectiveMandelTractionBe(Qtemp); // SHOULD NEVER BE USED!!
327  //if (dJ.at(3)<0) {
328  // Qtemp.at(3) = kn0*dJ.at(3);
329  //}
330  }
331 
332  Qtemp.at(1) = Qtemp.at(1) + Qtemp_comp.at(1);
333  Qtemp.at(2) = Qtemp.at(2) + Qtemp_comp.at(2);
334  Qtemp.at(3) = Qtemp.at(3) + Qtemp_comp.at(3);
335 
336 
337  answer.beTProductOf(Finv,Qtemp); // t_1_hat = MATMUL(TRANSPOSE(Fci),Q)
338 // answer.times(1-oldDamage-dAlpha); // t1_s = (1-al)*t_1_hat
339 
340 
341  status->letTempDamageBe(oldDamage + dAlpha);
342 // status->letTempEffectiveMandelTractionBe(Qtemp); // NEW!
343 
344  status->letTempJumpBe(d);
345  status->letTempFirstPKTractionBe(answer);
346  status->letTempFBe(F);
347 }
348 
349 
350 const double tolerance = 1.0e-12; // small number
353 {
354  IRResultType result; // Required by IR_GIVE_FIELD macro
355 
357  this->knc = kn0; // Defaults to the same stiffness in compression and tension
359 
360  this->ks0 = kn0; // Defaults to kn0
362 
364 
365  this->GIIc = GIc; //Defaults to GIc
367 
369 
371 
373 
375 
377 
379 
380  this->checkConsistency(); // check validity of the material paramters
381  this->printYourself();
382  return IRRT_OK;
383 }
384 
386 {
388 
391 
392 }
393 
394 int
396 {
397  if ( this->kn0 < 0.0 ) {
398  OOFEM_ERROR("stiffness kn0 is negative (%.2e)", this->kn0);
399  } else if ( this->ks0 < 0.0 ) {
400  OOFEM_ERROR("stiffness ks0 is negative (%.2e)", this->ks0);
401  } else if ( this->GIc < 0.0 ) {
402  OOFEM_ERROR("GIc is negative (%.2e)", this->GIc);
403  } else if ( this->GIIc < 0.0 ) {
404  OOFEM_ERROR("GIIc is negative (%.2e)", this->GIIc);
405  } else if ( this->gamma < 0.0 ) {
406  OOFEM_ERROR("gamma (%.2e) is below zero which is unphysical",
407  this->gamma);
408  }
409  return 1;
410 }
411 
412 void
414 {
416  printf("-Rate parameters \n");
417  printf(" c_star = %e \n", this->c_star);
418  printf(" m = %e \n", this->m);
419 
420 }
421 
422 
423 } // end namespace oofem
void setField(int item, InputFieldType id)
void subtract(const FloatArray &src)
Subtracts array src to receiver.
Definition: floatarray.C:258
void letTempFBe(FloatMatrix v)
Assigns tempFVector to given vector v.
virtual IRResultType initializeFrom(InputRecord *ir)
Initializes receiver according to object description stored in input record.
virtual MaterialStatus * giveStatus(GaussPoint *gp) const
Returns material status of receiver in given integration point.
Definition: material.C:244
Class and object Domain.
Definition: domain.h:115
#define _IFT_IntMatBilinearCZFagerstrom_mu
IntMatBilinearCZFagerstromRate(int n, Domain *d)
Constructor.
double & at(int i)
Coefficient access function.
Definition: floatarray.h:131
void beSubMatrixOf(const FloatMatrix &src, int topRow, int bottomRow, int topCol, int bottomCol)
Assigns to the receiver the sub-matrix of another matrix.
Definition: floatmatrix.C:962
#define _IFT_IntMatBilinearCZFagerstrom_g1c
virtual void giveInputRecord(DynamicInputRecord &input)
Setups the input record string of receiver.
#define _IFT_IntMatBilinearCZFagerstrom_sigf
void printYourself()
Prints receiver state on stdout. Useful for debugging.
#define S(p)
Definition: mdm.C:481
Class implementing an array of integers.
Definition: intarray.h:61
int & at(int i)
Coefficient access function.
Definition: intarray.h:103
#define _IFT_IntMatBilinearCZFagerstrom_kn
double giveTimeIncrement()
Returns solution step associated time increment.
Definition: timestep.h:150
virtual void giveFirstPKTraction_3d(FloatArray &answer, GaussPoint *gp, const FloatArray &jump, const FloatMatrix &F, TimeStep *tStep)
#define _IFT_IntMatBilinearCZFagerstrom_ks
#define _IFT_IntMatBilinearCZFagerstromRate_m
#define OOFEM_ERROR(...)
Definition: error.h:61
#define _IFT_IntMatBilinearCZFagerstrom_g2c
double computeSquaredNorm() const
Computes the square of the norm.
Definition: floatarray.C:846
virtual void giveInputRecord(DynamicInputRecord &input)
Setups the input record string of receiver.
#define _IFT_IntMatBilinearCZFagerstrom_knc
void letTempJumpBe(FloatArray v)
Assigns tempJump to given vector v.
void beProductOf(const FloatMatrix &aMatrix, const FloatArray &anArray)
Receiver becomes the result of the product of aMatrix and anArray.
Definition: floatarray.C:676
double c_star
Rate dependence coefficient.
#define _IFT_IntMatBilinearCZFagerstrom_gamma
void beTProductOf(const FloatMatrix &aMatrix, const FloatArray &anArray)
Receiver becomes the result of the product of aMatrix^T and anArray.
Definition: floatarray.C:708
double at(int i, int j) const
Coefficient access function.
Definition: floatmatrix.h:176
const double tolerance
Definition: expczmaterial.C:45
void letTempFirstPKTractionBe(FloatArray v)
Assigns tempFirstPKTraction to given vector v.
Class representing vector of real numbers.
Definition: floatarray.h:82
Implementation of matrix containing floating point numbers.
Definition: floatmatrix.h:94
IRResultType
Type defining the return values of InputRecord reading operations.
Definition: irresulttype.h:47
virtual int checkConsistency()
Allows programmer to test some internal data, before computation begins.
double computeNorm() const
Computes the norm (or length) of the vector.
Definition: floatarray.C:840
Class representing the general Input Record.
Definition: inputrecord.h:101
void zero()
Zeroes all coefficients of receiver.
Definition: floatarray.C:658
Class representing the a dynamic Input Record.
void times(double s)
Multiplies receiver with scalar.
Definition: floatarray.C:818
Simple isotropic damage based model for 2d interface elements.
#define _IFT_IntMatBilinearCZFagerstromRate_cstar
void zero()
Zeroes all coefficient of receiver.
Definition: floatmatrix.C:1326
REGISTER_Material(DummyMaterial)
#define IR_GIVE_OPTIONAL_FIELD(__ir, __value, __id)
Macro facilitating the use of input record reading methods.
Definition: inputrecord.h:78
the oofem namespace is to define a context or scope in which all oofem names are defined.
This class implements associated Material Status for IntMatBilinearCZFagerstrom.
virtual IRResultType initializeFrom(InputRecord *ir)
Initializes receiver according to object description stored in input record.
void printYourself()
Prints receiver state on stdout. Useful for debugging.
#define IR_GIVE_FIELD(__ir, __value, __id)
Macro facilitating the use of input record reading methods.
Definition: inputrecord.h:69
const FloatArray & giveTempJump() const
Returns the const pointer to receiver&#39;s temporary jump.
void beInverseOf(const FloatMatrix &src)
Modifies receiver to become inverse of given parameter.
Definition: floatmatrix.C:835
Class representing integration point in finite element program.
Definition: gausspoint.h:93
Class representing solution step.
Definition: timestep.h:80
void add(const FloatArray &src)
Adds array src to receiver.
Definition: floatarray.C:156

This page is part of the OOFEM documentation. Copyright (c) 2011 Borek Patzak
Project e-mail: info@oofem.org
Generated at Tue Jan 2 2018 20:07:29 for OOFEM by doxygen 1.8.11 written by Dimitri van Heesch, © 1997-2011