OOFEM  2.4
OOFEM.org - Object Oriented Finite Element Solver
mdm.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 #include "mdm.h"
36 #include "gausspoint.h"
37 #include "floatmatrix.h"
38 #include "floatarray.h"
39 #include "mathfem.h"
41 #include "mmaclosestiptransfer.h"
42 #include "nonlocalmaterialext.h"
43 #include "microplane.h"
44 #include "contextioerr.h"
45 #include "classfactory.h"
46 #include "dynamicinputrecord.h"
47 #include "datastream.h"
48 
49 namespace oofem {
51 
52 #ifndef MDM_MAPPING_DEBUG
53 
54  #ifdef MDM_USE_MMAClosestIPTransfer
55 MMAClosestIPTransfer MDM :: mapper;
56  #endif
57 
58  #ifdef MDM_USE_MMAShapeFunctProjection
59 MMAShapeFunctProjection MDM :: mapper;
60  #endif
61 
62  #ifdef MDM_USE_MMALeastSquareProjection
63 MMALeastSquareProjection MDM :: mapper;
64  #endif
65 
66 #else
67 MMAShapeFunctProjection MDM :: mapperSFT;
68 MMALeastSquareProjection MDM :: mapperLST;
69 
70 #endif
71 
72 MMAClosestIPTransfer MDM :: mapper2;
73 
74 MaterialStatus *
76 {
77  if ( dynamic_cast< Microplane * >(gp) ) {
78  return NULL;
79  } else {
80  return new MDMStatus(1, this->nsd, this->numberOfMicroplanes, MicroplaneMaterial :: giveDomain(), gp);
81  }
82 }
83 
84 
85 int
87 //
88 // returns whether receiver supports given mode
89 //
90 {
91  return mode == _3dMat || mode == _PlaneStress || mode == _PlaneStrain;
92 }
93 
94 void
96  const FloatArray &totalStrain, TimeStep *tStep)
97 {
98  FloatArray reducedStrain, strainPDC, stressPDC, stress;
99  FloatArray tempDamageTensorEigenVals;
100  FloatMatrix tempDamageTensor, tempDamageTensorEigenVec;
101  MDMStatus *status = static_cast< MDMStatus * >( this->giveStatus(gp) );
102 
103  this->giveStressDependentPartOfStrainVector(reducedStrain, gp, totalStrain,
104  tStep, VM_Total);
105 
106  // computeDamageTensor : locaL OR nonlocal
107  this->computeDamageTensor(tempDamageTensor, totalStrain, gp, tStep);
108  // compute principal direction and corresponding eigenvalues
109  this->computePDC(tempDamageTensor, tempDamageTensorEigenVals, tempDamageTensorEigenVec);
110 
111  // check the sign
112  for ( int ii = 1; ii <= nsd; ii++ ) {
113  if ( tempDamageTensorEigenVals.at(ii) < 0.0 ) {
114  OOFEM_ERROR("negative eigenvalue of damage tensor detected, element %d, ip %d",
115  gp->giveElement()->giveNumber(), gp->giveNumber() );
116  }
117  }
118 
119  // Transform local strain
120  // into principal damage coordinates (PDC)
121  transformStrainToPDC(strainPDC, reducedStrain, tempDamageTensorEigenVec, gp);
122 
123  // Evaluate effective strain in PDC
124  applyDamageTranformation(strainPDC, tempDamageTensorEigenVals);
125 
126  // Compute effective stress in PDC
127  computeEffectiveStress(stressPDC, strainPDC, gp, tStep);
128 
129  // Evaluate true stress in PDC
130  applyDamageTranformation(stressPDC, tempDamageTensorEigenVals);
131 
132  // Transform stress into global coordinates
133  transformStressFromPDC(stress, stressPDC, tempDamageTensorEigenVec, gp);
134 
135 
136  // update status
137  status->setTempDamageTensorEigenVals(tempDamageTensorEigenVals);
138  status->setTempDamageTensorEigenVec(tempDamageTensorEigenVec);
139  status->letTempStrainVectorBe(totalStrain);
140  status->letTempStressVectorBe(stress);
141  status->setTempDamageTensor(tempDamageTensor);
142 
143  /*
144  * // debug test
145  * for (int i=1; i<=stress.giveSize(); i++) {
146  * if (!finite(stress.at(i))) {
147  * char buff[1024];
148  * sprintf (buff, "giveRealStressVector: INF or NAN error detected, element %d, ip %d",
149  * gp->giveElement()->giveNumber(), gp->giveNumber());
150  * OOFEM_ERROR(buff);
151  * }
152  * }
153  * // end debug test
154  */
155 
156  answer = stress;
157 }
158 
159 
160 void
161 MDM :: computeDamageTensor(FloatMatrix &damageTensor, const FloatArray &totalStrain,
162  GaussPoint *gp, TimeStep *tStep)
163 {
164  // local or nonlocal
165  if ( nonlocal ) {
166  FloatMatrix nonlocalDamageTensor(nsd, nsd);
167  MDMStatus *nonlocStatus, *status = static_cast< MDMStatus * >( this->giveStatus(gp) );
168 
169  this->buildNonlocalPointTable(gp);
170  this->updateDomainBeforeNonlocAverage(tStep);
171 
172  // compute nonlocal strain increment first
173  for ( auto &lir: *this->giveIPIntegrationList(gp) ) {
174  nonlocStatus = static_cast< MDMStatus * >( this->giveStatus(lir.nearGp) );
175  const FloatMatrix &nonlocalContribution = nonlocStatus->giveLocalDamageTensorForAverage();
176 
177  if ( ndc == 3 ) {
178  nonlocalDamageTensor.at(1, 1) += nonlocalContribution.at(1, 1) * lir.weight;
179  nonlocalDamageTensor.at(2, 2) += nonlocalContribution.at(2, 2) * lir.weight;
180  nonlocalDamageTensor.at(1, 2) += nonlocalContribution.at(1, 2) * lir.weight;
181  } else {
182  nonlocalDamageTensor.at(1, 1) += nonlocalContribution.at(1, 1) * lir.weight;
183  nonlocalDamageTensor.at(2, 2) += nonlocalContribution.at(2, 2) * lir.weight;
184  nonlocalDamageTensor.at(3, 3) += nonlocalContribution.at(3, 3) * lir.weight;
185  nonlocalDamageTensor.at(1, 2) += nonlocalContribution.at(1, 2) * lir.weight;
186  nonlocalDamageTensor.at(1, 3) += nonlocalContribution.at(1, 3) * lir.weight;
187  nonlocalDamageTensor.at(2, 3) += nonlocalContribution.at(2, 3) * lir.weight;
188  }
189  }
190 
191  nonlocalDamageTensor.times( 1. / status->giveIntegrationScale() );
192  nonlocalDamageTensor.symmetrized();
193  this->endIPNonlocalAverage(gp); // !
194 
195  damageTensor = nonlocalDamageTensor;
196  } else {
197  computeLocalDamageTensor(damageTensor, totalStrain, gp, tStep);
198  }
199 }
200 
201 
202 
203 
204 
205 void
206 MDM :: computeLocalDamageTensor(FloatMatrix &damageTensor, const FloatArray &totalStrain,
207  GaussPoint *gp, TimeStep *tStep)
208 {
209  int im1;
210  double PsiOld, Psi;
211  FloatArray damageVector(6);
212  Microplane *mPlane;
213  MDMStatus *status = static_cast< MDMStatus * >( this->giveStatus(gp) );
214 
215  // Loop over microplanes.
216  for ( int im = 0; im < numberOfMicroplanes; im++ ) {
217  mPlane = this->giveMicroplane(im, gp);
218  im1 = im + 1;
219 
220  Psi = computeDamageOnPlane(gp, mPlane, totalStrain);
221 
222  PsiOld = status->giveMicroplaneDamage(im1);
223  if ( PsiOld > Psi ) {
224  Psi = PsiOld;
225  }
226 
227  // update damage on microplane
228  status->setMicroplaneTempDamage(im1, Psi);
229 
230  if ( formulation == COMPLIANCE_DAMAGE ) {
231  //for (int i=1; i<=ndc; i++) DamageVector->at(i) += MP->N[im][i] * MP->W[im] * PsiActive;
232  for ( int i = 1; i <= 6; i++ ) {
233  damageVector.at(i) += this->N [ im ] [ i - 1 ] * this->microplaneWeights [ im ] * Psi;
234  }
235  } else if ( formulation == STIFFNESS_DAMAGE ) {
236  //for (int i=1; i<=ndc; i++) DamageVector->at(i) += MP->N[im][i] * MP->W[im] / PsiActive;
237  for ( int i = 1; i <= 6; i++ ) {
238  damageVector.at(i) += this->N [ im ] [ i - 1 ] * this->microplaneWeights [ im ] / Psi;
239  }
240  }
241  //else MicroplaneMaterial::_error("Unknown type of formulation");
242  else {
243  OOFEM_ERROR("Unknown type of formulation");
244  }
245  }
246 
247  if ( ndc == 3 ) {
248  // 2d case
249  damageTensor.resize(2, 2);
250  damageVector.times(2. / M_PI);
251 
252  damageTensor.at(1, 1) = damageVector.at(1);
253  damageTensor.at(2, 2) = damageVector.at(2);
254  damageTensor.at(1, 2) = damageTensor.at(2, 1) = damageVector.at(6);
255  } else if ( ndc == 6 ) {
256  // 3d case
257  damageTensor.resize(3, 3);
258  damageVector.times(6.0);
259 
260  damageTensor.at(1, 1) = damageVector.at(1);
261  damageTensor.at(2, 2) = damageVector.at(2);
262  damageTensor.at(3, 3) = damageVector.at(3);
263  damageTensor.at(2, 3) = damageTensor.at(3, 2) = damageVector.at(4);
264  damageTensor.at(3, 1) = damageTensor.at(1, 3) = damageVector.at(5);
265  damageTensor.at(1, 2) = damageTensor.at(2, 1) = damageVector.at(6);
266 
267  //} else MicroplaneMaterial::_error("computeDamageTensor: unknown ndc value encountered");
268  } else {
269  OOFEM_ERROR("unknown ndc value encountered");
270  }
271 }
272 
273 #define LARGE_EXPONENT 50.0
274 #define HUGE_RELATIVE_COMPLIANCE 1.e20
275 
276 double
278 {
279  double en, em, el, Ep, Efp, ParEpp;
280  double Enorm = 0.0, sv = 0.0, answer = 0.0;
281  double fmicroplane;
282  IntArray mask;
283  FloatArray fullStrain, prevStress = static_cast< StructuralMaterialStatus * >( this->giveStatus(gp) )->giveStressVector();
285 
287  en = this->computeNormalStrainComponent(mplane, fullStrain);
288  em = this->computeShearMStrainComponent(mplane, fullStrain);
289  el = this->computeShearLStrainComponent(mplane, fullStrain);
290 
291 
292  // request raw parameters
293  this->giveRawMDMParameters(Efp, Ep, strain, gp);
294 
295  // compute trace of stressTensor
296  if ( prevStress.isNotEmpty() ) {
297  for ( int i = 1; i <= nsd; i++ ) {
298  if ( mask.at(i) ) {
299  sv += prevStress.at( mask.at(i) );
300  }
301  }
302  }
303 
304  ParEpp = Ep / ( 1. - ParMd ); // 1d sv reduction
305  fmicroplane = linearElasticMaterial->give('E', gp) * ParEpp;
306  // en /= (1.-ParMd*sv);
307  en /= ( 1. - ParMd * sv / ( fmicroplane ) ); // suggested by P.Grassl (ParMd is unit dependent)
308 
309  if ( type_dam == 0 ) {
310  if ( en < 0. ) {
311  en = 0.; // take the positive part of normal strain
312  }
313 
314  Enorm = en;
315  } else if ( type_dam == 1 ) {
316  if ( en < 0. ) {
317  en = 0.; // take the positive part of normal strain
318  }
319 
320  Enorm = sqrt(en * en + em * em + el * el);
321  //} else MicroplaneMaterial::_error("Unknown type of damage law");
322  } else {
323  OOFEM_ERROR("Unknown type of damage law");
324  }
325 
326 
327  // evaluate softening law
328  if ( type_soft == 0 ) {
329  if ( Enorm <= ParEpp ) {
330  answer = 1.;
331  } else {
332  double aux = ( Enorm - ParEpp ) / Efp;
333  if ( aux < LARGE_EXPONENT ) {
334  answer = sqrt( ( Enorm / ParEpp ) * exp(aux) );
335  } else {
336  answer = HUGE_RELATIVE_COMPLIANCE;
337  }
338  }
339 
340  //} else MicroplaneMaterial::_error("Unknown type of softening");
341  } else {
342  OOFEM_ERROR("Unknown type of softening");
343  }
344 
345  return answer;
346 }
347 
348 void
349 MDM :: computePDC(FloatMatrix &tempDamageTensor, FloatArray &tempDamageTensorEigenVals,
350  FloatMatrix &tempDamageTensorEigenVec)
351 {
352  FloatMatrix help = tempDamageTensor;
353 
354  // resize the results
355  tempDamageTensorEigenVals.resize(nsd);
356  tempDamageTensorEigenVec.resize(nsd, nsd);
357 
358 #if 0
359  int nrot;
360  help.Jacobi(& tempDamageTensorEigenVals, & tempDamageTensorEigenVec, & nrot);
361 #else
362  help.jaco_(tempDamageTensorEigenVals, tempDamageTensorEigenVec, 10);
363 #endif
364 }
365 
366 
367 #define N(p, q) t.at(q, p)
368 #define E(p) fullStrain.at(p)
369 
370 void
372  FloatMatrix &t, GaussPoint *gp)
373 {
374  FloatArray fullStrain;
375 
376  if ( mdmMode == mdm_3d ) {
378 
379  answer.resize(6);
380  answer.at(1) = N(1, 1) * ( N(1, 1) * E(1) + N(1, 2) * E(6) + N(1, 3) * E(5) )
381  + N(1, 2) * ( N(1, 2) * E(2) + N(1, 3) * E(4) )
382  + N(1, 3) * N(1, 3) * E(3);
383  answer.at(2) = N(2, 1) * ( N(2, 1) * E(1) + N(2, 2) * E(6) + N(2, 3) * E(5) )
384  + N(2, 2) * ( N(2, 2) * E(2) + N(2, 3) * E(4) )
385  + N(2, 3) * N(2, 3) * E(3);
386  answer.at(3) = N(3, 1) * ( N(3, 1) * E(1) + N(3, 2) * E(6) + N(3, 3) * E(5) )
387  + N(3, 2) * ( N(3, 2) * E(2) + N(3, 3) * E(4) )
388  + N(3, 3) * N(3, 3) * E(3);
389  answer.at(4) = N(2, 1) * ( N(3, 1) * E(1) + N(3, 2) * E(6) / 2 + N(3, 3) * E(5) / 2 )
390  + N(2, 2) * ( N(3, 1) * E(6) / 2 + N(3, 2) * E(2) + N(3, 3) * E(4) / 2 )
391  + N(2, 3) * ( N(3, 1) * E(5) / 2 + N(3, 2) * E(4) / 2 + N(3, 3) * E(3) );
392  answer.at(4) *= 2;
393  answer.at(5) = N(1, 1) * ( N(3, 1) * E(1) + N(3, 2) * E(6) / 2 + N(3, 3) * E(5) / 2 )
394  + N(1, 2) * ( N(3, 1) * E(6) / 2 + N(3, 2) * E(2) + N(3, 3) * E(4) / 2 )
395  + N(1, 3) * ( N(3, 1) * E(5) / 2 + N(3, 2) * E(4) / 2 + N(3, 3) * E(3) );
396  answer.at(5) *= 2;
397  answer.at(6) = N(1, 1) * ( N(2, 1) * E(1) + N(2, 2) * E(6) / 2 + N(2, 3) * E(5) / 2 )
398  + N(1, 2) * ( N(2, 1) * E(6) / 2 + N(2, 2) * E(2) + N(2, 3) * E(4) / 2 )
399  + N(1, 3) * ( N(2, 1) * E(5) / 2 + N(2, 2) * E(4) / 2 + N(2, 3) * E(3) );
400  answer.at(6) *= 2;
401  } else if ( mdmMode == mdm_2d ) {
402  fullStrain = strain;
403 
404  answer.resize(3);
405  answer.at(1) = N(1, 1) * ( N(1, 1) * E(1) + N(1, 2) * E(3) )
406  + N(1, 2) * N(1, 2) * E(2);
407  answer.at(2) = N(2, 1) * ( N(2, 1) * E(1) + N(2, 2) * E(3) )
408  + N(2, 2) * N(2, 2) * E(2);
409  answer.at(3) = N(1, 1) * ( N(2, 1) * E(1) + N(2, 2) * E(3) / 2 )
410  + N(1, 2) * ( N(2, 1) * E(3) / 2 + N(2, 2) * E(2) );
411  answer.at(3) *= 2;
412  }
413 }
414 
415 void
416 MDM :: applyDamageTranformation(FloatArray &strainPDC, const FloatArray &tempDamageTensorEigenVals)
417 {
418  if ( mdmMode == mdm_3d ) {
419  double psi1 = tempDamageTensorEigenVals.at(1);
420  double psi2 = tempDamageTensorEigenVals.at(2);
421  double psi3 = tempDamageTensorEigenVals.at(3);
422 
423  if ( formulation == COMPLIANCE_DAMAGE ) {
424  strainPDC.at(1) /= psi1;
425  strainPDC.at(2) /= psi2;
426  strainPDC.at(3) /= psi3;
427  strainPDC.at(4) /= sqrt(psi2 * psi3);
428  strainPDC.at(5) /= sqrt(psi1 * psi3);
429  strainPDC.at(6) /= sqrt(psi1 * psi2);
430  } else if ( formulation == STIFFNESS_DAMAGE ) {
431  strainPDC.at(1) *= psi1;
432  strainPDC.at(2) *= psi2;
433  strainPDC.at(3) *= psi3;
434  strainPDC.at(4) *= sqrt(psi2 * psi3);
435  strainPDC.at(5) *= sqrt(psi1 * psi3);
436  strainPDC.at(6) *= sqrt(psi1 * psi2);
437  } else {
438  //MicroplaneMaterial::_error("Unknown type of formulation");
439  OOFEM_ERROR("Unknown type of formulation");
440  }
441  } else if ( mdmMode == mdm_2d ) {
442  double psi1 = tempDamageTensorEigenVals.at(1);
443  double psi2 = tempDamageTensorEigenVals.at(2);
444  if ( formulation == COMPLIANCE_DAMAGE ) {
445  strainPDC.at(1) /= psi1;
446  strainPDC.at(2) /= psi2;
447  strainPDC.at(3) /= sqrt(psi1 * psi2);
448  } else if ( formulation == STIFFNESS_DAMAGE ) {
449  strainPDC.at(1) *= psi1;
450  strainPDC.at(2) *= psi2;
451  strainPDC.at(3) *= sqrt(psi1 * psi2);
452  } else {
453  //MicroplaneMaterial::_error("Unknown type of formulation");
454  OOFEM_ERROR("Unknown type of formulation");
455  }
456 
457  //} else MicroplaneMaterial::_error("Unknown type of mdm mode");
458  } else {
459  OOFEM_ERROR("Unknown type of mdm mode");
460  }
461 }
462 
463 
464 void
465 MDM :: computeEffectiveStress(FloatArray &stressPDC, const FloatArray &strainPDC, GaussPoint *gp, TimeStep *tStep)
466 {
467  FloatMatrix de;
468  if ( mdmMode == mdm_3d ) {
469  // PDC components in 3d mode are in full 3d format, even in planeStrain situation
470  this->giveLinearElasticMaterial()->give3dMaterialStiffnessMatrix(de, TangentStiffness, gp, tStep);
471  } else {
472  this->giveLinearElasticMaterial()->giveStiffnessMatrix(de, TangentStiffness, gp, tStep);
473  }
474 
475  stressPDC.beProductOf(de, strainPDC);
476 }
477 
478 
479 
480 #define Nt(p, q) t.at(p, q)
481 #define S(p) stressPDC.at(p)
482 
483 void
485 {
486  if ( mdmMode == mdm_3d ) {
487  FloatArray fullAnswer(6);
488  //answer.resize (6);
489 
490  fullAnswer.at(1) = Nt(1, 1) * ( Nt(1, 1) * S(1) + 2 * Nt(1, 2) * S(6) + 2 * Nt(1, 3) * S(5) )
491  + Nt(1, 2) * ( Nt(1, 2) * S(2) + 2 * Nt(1, 3) * S(4) )
492  + Nt(1, 3) * Nt(1, 3) * S(3);
493  fullAnswer.at(2) = Nt(2, 1) * ( Nt(2, 1) * S(1) + 2 * Nt(2, 2) * S(6) + 2 * Nt(2, 3) * S(5) )
494  + Nt(2, 2) * ( Nt(2, 2) * S(2) + 2 * Nt(2, 3) * S(4) )
495  + Nt(2, 3) * Nt(2, 3) * S(3);
496  fullAnswer.at(3) = Nt(3, 1) * ( Nt(3, 1) * S(1) + 2 * Nt(3, 2) * S(6) + 2 * Nt(3, 3) * S(5) )
497  + Nt(3, 2) * ( Nt(3, 2) * S(2) + 2 * Nt(3, 3) * S(4) )
498  + Nt(3, 3) * Nt(3, 3) * S(3);
499  fullAnswer.at(4) = Nt(2, 1) * ( Nt(3, 1) * S(1) + Nt(3, 2) * S(6) + Nt(3, 3) * S(5) )
500  + Nt(2, 2) * ( Nt(3, 1) * S(6) + Nt(3, 2) * S(2) + Nt(3, 3) * S(4) )
501  + Nt(2, 3) * ( Nt(3, 1) * S(5) + Nt(3, 2) * S(4) + Nt(3, 3) * S(3) );
502  fullAnswer.at(5) = Nt(1, 1) * ( Nt(3, 1) * S(1) + Nt(3, 2) * S(6) + Nt(3, 3) * S(5) )
503  + Nt(1, 2) * ( Nt(3, 1) * S(6) + Nt(3, 2) * S(2) + Nt(3, 3) * S(4) )
504  + Nt(1, 3) * ( Nt(3, 1) * S(5) + Nt(3, 2) * S(4) + Nt(3, 3) * S(3) );
505  fullAnswer.at(6) = Nt(1, 1) * ( Nt(2, 1) * S(1) + Nt(2, 2) * S(6) + Nt(2, 3) * S(5) )
506  + Nt(1, 2) * ( Nt(2, 1) * S(6) + Nt(2, 2) * S(2) + Nt(2, 3) * S(4) )
507  + Nt(1, 3) * ( Nt(2, 1) * S(5) + Nt(2, 2) * S(4) + Nt(2, 3) * S(3) );
508 
510  } else if ( mdmMode == mdm_2d ) {
511  answer.resize(3);
512 
513  answer.at(1) = Nt(1, 1) * ( Nt(1, 1) * S(1) + Nt(1, 2) * 2. * S(3) )
514  + Nt(1, 2) * Nt(1, 2) * S(2);
515  answer.at(2) = Nt(2, 1) * ( Nt(2, 1) * S(1) + Nt(2, 2) * 2. * S(3) )
516  + Nt(2, 2) * Nt(2, 2) * S(2);
517  answer.at(3) = Nt(1, 1) * ( Nt(2, 1) * S(1) + Nt(2, 2) * S(3) )
518  + Nt(1, 2) * ( Nt(2, 1) * S(3) + Nt(2, 2) * S(2) );
519  }
520 }
521 
522 
523 
524 void
526  MatResponseMode mode,
527  GaussPoint *gp,
528  TimeStep *tStep)
529 {
530  MDMStatus *status = static_cast< MDMStatus * >( this->giveStatus(gp) );
531 
532  this->giveLinearElasticMaterial()->giveStiffnessMatrix(answer, TangentStiffness, gp, tStep);
533  //answer = de;
534  //return;
535  // if (isVirgin()) return ;
536  if ( ( mode == TangentStiffness ) || ( mode == SecantStiffness ) ) {
537  // Apply damage in principal coordinates
538  this->applyDamageToStiffness(answer, gp);
539 
540  // Transform to global coordinates (in reduced space)
541  this->transformStiffnessfromPDC( answer, status->giveTempDamageTensorEigenVec() );
542  }
543 }
544 
545 
546 #define MAX_REL_COMPL_TRESHOLD 1.e6
547 
548 void
550 {
551  MDMStatus *status = static_cast< MDMStatus * >( this->giveStatus(gp) );
552 
553  if ( mdmMode == mdm_3d ) {
554  double psi1 = 0.0, psi2 = 0.0, psi3 = 0.0;
555  if ( formulation == COMPLIANCE_DAMAGE ) {
556  psi1 = status->giveTempDamageTensorEigenVals().at(1);
557  psi2 = status->giveTempDamageTensorEigenVals().at(2);
558  psi3 = status->giveTempDamageTensorEigenVals().at(3);
559  } else if ( formulation == STIFFNESS_DAMAGE ) {
560  psi1 = 1. / ( status->giveTempDamageTensorEigenVals().at(1) );
561  psi2 = 1. / ( status->giveTempDamageTensorEigenVals().at(2) );
562  psi3 = 1. / ( status->giveTempDamageTensorEigenVals().at(3) );
563  //} else MicroplaneMaterial::_error("Unknown type of formulation");
564  } else {
565  OOFEM_ERROR("Unknown type of formulation");
566  }
567 
568  //if ((psi1 > MAX_REL_COMPL_TRESHOLD) || (psi2 > MAX_REL_COMPL_TRESHOLD) || (psi3 > MAX_REL_COMPL_TRESHOLD)) printf (":");
569 
570  psi1 = min(psi1, MAX_REL_COMPL_TRESHOLD);
571  psi2 = min(psi2, MAX_REL_COMPL_TRESHOLD);
572  psi3 = min(psi3, MAX_REL_COMPL_TRESHOLD);
573 
574  if ( d.giveNumberOfRows() == 6 ) {
575  d.at(1, 1) /= ( psi1 * psi1 );
576  d.at(1, 2) /= ( psi1 * psi2 );
577  d.at(1, 3) /= ( psi1 * psi3 );
578  d.at(2, 1) /= ( psi2 * psi1 );
579  d.at(2, 2) /= ( psi2 * psi2 );
580  d.at(2, 3) /= ( psi2 * psi3 );
581  d.at(3, 1) /= ( psi3 * psi1 );
582  d.at(3, 2) /= ( psi3 * psi2 );
583  d.at(3, 3) /= ( psi3 * psi3 );
584  d.at(4, 4) /= ( psi2 * psi3 );
585  d.at(5, 5) /= ( psi1 * psi3 );
586  d.at(6, 6) /= ( psi1 * psi2 );
587  } else if ( d.giveNumberOfRows() == 4 ) {
588  d.at(1, 1) /= ( psi1 * psi1 );
589  d.at(1, 2) /= ( psi1 * psi2 );
590  d.at(1, 3) /= ( psi1 * psi3 );
591  d.at(2, 1) /= ( psi2 * psi1 );
592  d.at(2, 2) /= ( psi2 * psi2 );
593  d.at(2, 3) /= ( psi2 * psi3 );
594  d.at(3, 1) /= ( psi3 * psi1 );
595  d.at(3, 2) /= ( psi3 * psi2 );
596  d.at(3, 3) /= ( psi3 * psi3 );
597  d.at(4, 4) /= ( psi1 * psi2 );
598  //} else MicroplaneMaterial::_error("Unknown type stiffness");
599  } else {
600  OOFEM_ERROR("Unknown type stiffness");
601  }
602 
603  return;
604  } else if ( mdmMode == mdm_2d ) {
605  double psi1 = 0.0, psi2 = 0.0;
606  if ( formulation == COMPLIANCE_DAMAGE ) {
607  psi1 = status->giveTempDamageTensorEigenVals().at(1);
608  psi2 = status->giveTempDamageTensorEigenVals().at(2);
609  } else if ( formulation == STIFFNESS_DAMAGE ) {
610  psi1 = 1. / ( status->giveTempDamageTensorEigenVals().at(1) );
611  psi2 = 1. / ( status->giveTempDamageTensorEigenVals().at(2) );
612  //} else MicroplaneMaterial::_error("Unknown type of formulation");
613  } else {
614  OOFEM_ERROR("Unknown type of formulation");
615  }
616 
617 
618  //if ((psi1 > MAX_REL_COMPL_TRESHOLD) || (psi2 > MAX_REL_COMPL_TRESHOLD)) printf (":");
619  psi1 = min(psi1, MAX_REL_COMPL_TRESHOLD);
620  psi2 = min(psi2, MAX_REL_COMPL_TRESHOLD);
621 
622  d.at(1, 1) /= psi1 * psi1;
623  d.at(1, 2) /= psi1 * psi2;
624  d.at(2, 1) /= psi2 * psi1;
625  d.at(2, 2) /= psi2 * psi2;
626  d.at(3, 3) /= psi1 * psi2;
627 
628  return;
629  }
630 }
631 
632 
633 void
635 {
636  this->rotateTensor4(de, t);
637 }
638 
639 
640 void
642  MatResponseMode mode,
643  GaussPoint *gp,
644  TimeStep *tStep)
645 {
646  this->giveMaterialStiffnessMatrix(answer, mode, gp, tStep);
647 }
648 
649 void
651  GaussPoint *gp, TimeStep *tStep)
652 {
653  this->giveMaterialStiffnessMatrix(answer, mode, gp, tStep);
654 }
655 
656 
657 void
659  GaussPoint *gp, TimeStep *tStep)
660 {
661  this->giveMaterialStiffnessMatrix(answer, mode, gp, tStep);
662 }
663 
664 
665 
666 int
668 {
669  MDMStatus *status = static_cast< MDMStatus * >( this->giveStatus(gp) );
670 
671  if ( type == IST_DamageTensor ) {
672  // DamageTensor = I-Phi*Phi \approx I - Phi^{-1}*Phi*^{-1}
673  // d corresponds damage compliance
674  // c corresponds to damage
675  FloatMatrix d, c;
676  if ( formulation == COMPLIANCE_DAMAGE ) {
677  c.beInverseOf(status->giveDamageTensor());
678  } else {
679  c = status->giveDamageTensor();
680  }
681 
682  d.beProductOf(c, c);
683  if ( ndc == 3 ) {
684  answer.resize(6);
685  answer.at(1) = 1. - d.at(1, 1);
686  answer.at(2) = 1. - d.at(2, 2);
687  answer.at(3) = d.at(1, 2);
688  answer.at(4) = 0.;
689  answer.at(5) = 0.;
690  answer.at(6) = 0.;
691  } else {
692  answer.resize(6);
693  answer.at(1) = 1. - d.at(1, 1);
694  answer.at(2) = 1. - d.at(2, 2);
695  answer.at(3) = 1. - d.at(3, 3);
696  answer.at(4) = d.at(2, 3);
697  answer.at(5) = d.at(1, 3);
698  answer.at(6) = d.at(1, 2);
699  }
700 
701  return 1;
702  } else if ( type == IST_DamageTensorTemp ) {
703  FloatMatrix d, c;
704  if ( formulation == COMPLIANCE_DAMAGE ) {
705  c.beInverseOf(status->giveTempDamageTensor());
706  } else {
707  c = status->giveTempDamageTensor();
708  }
709 
710  d.beProductOf(c, c);
711  if ( ndc == 3 ) {
712  answer.resize(6);
713  answer.at(1) = 1. - d.at(1, 1);
714  answer.at(2) = 1. - d.at(2, 2);
715  answer.at(3) = d.at(1, 2);
716  answer.at(4) = 0.;
717  answer.at(5) = 0.;
718  answer.at(6) = 0.;
719  } else {
720  answer.resize(6);
721  answer.at(1) = 1. - d.at(1, 1);
722  answer.at(2) = 1. - d.at(2, 2);
723  answer.at(3) = 1. - d.at(3, 3);
724  answer.at(4) = d.at(2, 3);
725  answer.at(5) = d.at(1, 3);
726  answer.at(6) = d.at(1, 2);
727  }
728 
729  return 1;
730  } else if ( type == IST_PrincipalDamageTensor ) {
731  const FloatArray &d = status->giveDamageTensorEigenVals();
732 
733  answer.resize(3);
734  answer.zero();
735  if ( formulation == COMPLIANCE_DAMAGE ) {
736  for ( int i = 1; i <= nsd; i++ ) {
737  answer.at(i) = 1. - 1. / d.at(i) / d.at(i);
738  }
739  } else {
740  for ( int i = 1; i <= nsd; i++ ) {
741  answer.at(i) = 1. - d.at(i) * d.at(i);
742  }
743  }
744 
745  return 1;
746  } else if ( type == IST_PrincipalDamageTempTensor ) {
747  const FloatArray &d = status->giveTempDamageTensorEigenVals();
748 
749  answer.resize(3);
750  answer.zero();
751  if ( formulation == COMPLIANCE_DAMAGE ) {
752  for ( int i = 1; i <= nsd; i++ ) {
753  answer.at(i) = 1. - 1. / d.at(i) / d.at(i);
754  }
755  } else {
756  for ( int i = 1; i <= nsd; i++ ) {
757  answer.at(i) = 1. - d.at(i) * d.at(i);
758  }
759  }
760 
761  return 1;
762  } else if ( type == IST_MicroplaneDamageValues ) {
763  answer = status->giveMicroplaneDamageValues();
764  return 1;
765  } else {
766  return StructuralMaterial :: giveIPValue(answer, gp, type, tStep);
767  }
768 }
769 
770 void
772  GaussPoint *gp, TimeStep *tStep)
773 {
774  answer.resize(6);
775  answer.zero();
776  answer.at(1) = this->tempDillatCoeff;
777  answer.at(2) = this->tempDillatCoeff;
778  answer.at(3) = this->tempDillatCoeff;
779 }
780 
781 
784 //
785 // initializes according to string
786 //
787 {
788  IRResultType result; // Required by IR_GIVE_FIELD macro
789 
791  IR_GIVE_FIELD(ir, this->ParMd, _IFT_MDM_parmd);
793 
794  if ( this->nonlocal ) {
795  IR_GIVE_FIELD(ir, R, _IFT_MDM_r);
796  if ( R < 0.0 ) {
797  R = 0.0;
798  }
799 
800  if ( ( ir->hasField(_IFT_MDM_efp) ) && ( ir->hasField(_IFT_MDM_ep) ) ) {
801  // read raw_params if available
802  IR_GIVE_FIELD(ir, this->mdm_Efp, _IFT_MDM_efp);
803  IR_GIVE_FIELD(ir, this->mdm_Ep, _IFT_MDM_ep);
804  } else if ( ( ir->hasField(_IFT_MDM_gf) ) && ( ir->hasField(_IFT_MDM_ft) ) ) {
805  IR_GIVE_FIELD(ir, this->Gf, _IFT_MDM_gf);
806  IR_GIVE_FIELD(ir, this->Ft, _IFT_MDM_ft);
807  } else {
808  OOFEM_WARNING("unknown set of parameters");
809  return IRRT_BAD_FORMAT;
810  }
811  } else { // local case
812  if ( ( ir->hasField(_IFT_MDM_efp) ) && ( ir->hasField(_IFT_MDM_ep) ) ) {
813  // read raw_params if available
814  IR_GIVE_FIELD(ir, this->mdm_Efp, _IFT_MDM_efp);
815  IR_GIVE_FIELD(ir, this->mdm_Ep, _IFT_MDM_ep);
816  } else if ( ( ir->hasField(_IFT_MDM_gf) ) && ( ir->hasField(_IFT_MDM_ep) ) ) {
817  IR_GIVE_FIELD(ir, this->Gf, _IFT_MDM_gf);
818  IR_GIVE_FIELD(ir, this->mdm_Ep, _IFT_MDM_ep);
819  } else {
820  OOFEM_WARNING("unknown set of parameters");
821  return IRRT_BAD_FORMAT;
822  }
823  }
824 
825  // read formulation
826  int _val = 0;
828  this->formulation = ( MDMFormulatrionType ) _val;
829 
830  IR_GIVE_FIELD(ir, _val, _IFT_MDM_mode);
831  this->mdmMode = ( MDMModeType ) _val;
832 
833  if ( this->mdmMode == mdm_3d ) {
834  this->ndc = 6;
835  this->nsd = 3;
836  } else if ( this->mdmMode == mdm_2d ) {
837  this->ndc = 3;
838  this->nsd = 2;
839  }
840 
841 
842 #ifdef MDM_MAPPING_DEBUG
843  _val = 0;
845  this->mapperType = ( MDMMapperType ) _val;
846  OOFEM_LOG_INFO("MDM: using optional mapper %d\n", mapperType);
847 #endif
848 
850  if ( result != IRRT_OK ) return result;
851 
852  if ( this->nonlocal ) {
854  if ( result != IRRT_OK ) return result;
855  }
856 
859  if ( result != IRRT_OK ) return result;
860 
861 #ifdef MDM_MAPPING_DEBUG
862  result = mapperSFT.initializeFrom(ir);
863  if ( result != IRRT_OK ) return result;
864  result = mapperLST.initializeFrom(ir);
865  if ( result != IRRT_OK ) return result;
866 #else
867  result = mapper.initializeFrom(ir);
868  if ( result != IRRT_OK ) return result;
869 #endif
870  result = mapper2.initializeFrom(ir);
871  if ( result != IRRT_OK ) return result;
872 
873  return IRRT_OK;
874 }
875 
876 
878 {
882 #ifdef MDM_MAPPING_DEBUG
883  mapperSFT.giveInputRecord(input);
884  mapperLST.giveInputRecord(input);
885  input.setField(this->mapperType, _IFT_MDM_mapper);
886 #else
887  mapper.giveInputRecord(input);
888 #endif
889  mapper2.giveInputRecord(input);
890 
892  input.setField(this->ParMd, _IFT_MDM_parmd);
893  input.setField(this->nonlocal, _IFT_MDM_nonloc);
894 
895  if ( this->nonlocal ) {
896  input.setField(R, _IFT_MDM_r);
897 
898  if ( this->mdm_Ep >= 0.0 && this->mdm_Efp >= 0.0 ) {
899  // read raw_params if available
900  input.setField(this->mdm_Efp, _IFT_MDM_efp);
901  input.setField(this->mdm_Ep, _IFT_MDM_ep);
902  } else {
903  input.setField(this->Gf, _IFT_MDM_gf);
904  input.setField(this->Ft, _IFT_MDM_ft);
905  }
906  } else { // local case
907  if ( this->mdm_Ep >= 0.0 && this->mdm_Efp >= 0.0 ) {
908  // read raw_params if available
909  input.setField(this->mdm_Efp, _IFT_MDM_efp);
910  input.setField(this->mdm_Ep, _IFT_MDM_ep);
911  } else {
912  input.setField(this->Gf, _IFT_MDM_gf);
913  input.setField(this->mdm_Ep, _IFT_MDM_ep);
914  }
915  }
916 
918  input.setField(this->mdmMode, _IFT_MDM_mode);
919 }
920 
921 
922 void
924 //
925 // Interpreting "t" as the rotation matrix containing in its
926 // columns the local base vectors, transform a fourth-order tensor
927 // represented by a matrix from local to global coordinates.
928 {
929  FloatMatrix tt, td;
930  this->formTransformationMatrix( tt, t, Dlocal.giveNumberOfRows() );
931  td.beProductOf(tt, Dlocal);
932  Dlocal.beProductTOf(td, tt);
933 }
934 
935 #define FORMT33(i, j, ij) answer.at(ij, 1) = t.at(i, 1) * t.at(j, 1); answer.at(ij, 2) = t.at(i, 2) * t.at(j, 2); answer.at(ij, 3) = t.at(i, 1) * t.at(j, 2) + t.at(i, 2) * t.at(j, 1)
936 
937 #define FORMT44(i, j, ij) answer.at(ij, 1) = t.at(i, 1) * t.at(j, 1); answer.at(ij, 2) = t.at(i, 2) * t.at(j, 2); answer.at(ij, 3) = t.at(i, 3) * t.at(j, 3); answer.at(ij, 4) = t.at(i, 1) * t.at(j, 2) + t.at(i, 2) * t.at(j, 1)
938 
939 #define FORMT66(i, j, ij) answer.at(ij, 1) = t.at(i, 1) * t.at(j, 1); answer.at(ij, 2) = t.at(i, 2) * t.at(j, 2); answer.at(ij, 3) = t.at(i, 3) * t.at(j, 3); answer.at(ij, 4) = t.at(i, 2) * t.at(j, 3) + t.at(i, 3) * t.at(j, 2); answer.at(ij, 5) = t.at(i, 1) * t.at(j, 3) + t.at(i, 3) * t.at(j, 1); answer.at(ij, 6) = t.at(i, 1) * t.at(j, 2) + t.at(i, 2) * t.at(j, 1)
940 
941 
942 void
944 //
945 // Interpreting "t" as the rotation matrix containing in its
946 // columns the local base vectors, form the transformation matrix
947 // for the transformation of a fourth-order tensor represented by
948 // a matrix from local to global coordinates.
949 {
950  switch ( n ) {
951  case 1:
952  answer.resize(1, 1);
953  answer.at(1, 1) = 1.0;
954  return;
955 
956  case 3:
957  answer.resize(3, 3);
958  answer.zero();
959 
960  FORMT33(1, 1, 1);
961  FORMT33(2, 2, 2);
962  FORMT33(1, 2, 3);
963  return;
964 
965  case 4:
966  answer.resize(4, 4);
967  answer.zero();
968 
969  FORMT44(1, 1, 1);
970  FORMT44(2, 2, 2);
971  FORMT44(3, 3, 3);
972  FORMT44(1, 2, 4);
973  return;
974 
975  case 6:
976  answer.resize(6, 6);
977  answer.zero();
978 
979  FORMT66(1, 1, 1);
980  FORMT66(2, 2, 2);
981  FORMT66(3, 3, 3);
982  FORMT66(2, 3, 4);
983  FORMT66(1, 3, 5);
984  FORMT66(1, 2, 6);
985  return;
986 
987  default:
988  //MicroplaneMaterial::_error("Stress transformation matrix format not implemented");
989  OOFEM_ERROR("Stress transformation matrix format not implemented");
990  }
991 }
992 
993 void
994 MDM :: giveRawMDMParameters(double &Efp, double &Ep, const FloatArray &reducedStrain, GaussPoint *gp)
995 {
996  // test if raw parameters are given
997  if ( this->mdm_Efp > 0.0 ) {
998  Efp = this->mdm_Efp;
999  Ep = this->mdm_Ep;
1000  return;
1001  }
1002 
1003  // determine params from macroscopic ones
1004  if ( nonlocal ) {
1005  // formulas derived for 3d case
1006  double EModulus = linearElasticMaterial->give('E', gp);
1007  double gammaf = ( EModulus * this->Gf ) / ( this->R * this->Ft * this->Ft );
1008  double gamma = gammaf / ( 1.47 - 0.0014 * gammaf );
1009  double f = this->Ft / ( 1.56 + 0.006 * gamma ); // microplane tensile strength
1010  Efp = this->mdm_Efp = ( gamma * f ) / EModulus;
1011  //double mdtilda = this->ParMd/f;
1012  Ep = this->mdm_Ep = f / EModulus;
1013  return;
1014  } else { // local model
1015  FloatArray strainVector, principalStrain;
1016  FloatMatrix dirs(3, 3);
1017  double h;
1018 
1019  StructuralMaterial :: giveFullSymVectorForm( strainVector, reducedStrain, gp->giveMaterialMode() );
1020  this->computePrincipalValDir(principalStrain, dirs,
1021  strainVector,
1023 
1024  // find EigenVector With Largest EigenValue
1025  int indx = 1;
1026  double max = principalStrain.at(1);
1027  if ( principalStrain.at(2) > max ) {
1028  indx = 2;
1029  }
1030 
1031  if ( principalStrain.at(3) > max ) {
1032  indx = 3;
1033  }
1034 
1035  FloatArray dir(3);
1036  dir.at(1) = dirs.at(1, indx);
1037  dir.at(2) = dirs.at(2, indx);
1038  dir.at(3) = dirs.at(3, indx);
1039 
1040  h = gp->giveElement()->giveCharacteristicLength(dir);
1041  double E = this->giveLinearElasticMaterial()->give(Ex, gp);
1042  Ep = this->mdm_Ep;
1043  if ( nsd == 2 ) {
1044  Efp = ( Gf / ( h * E * Ep ) + 1.2 * Ep ) / 1.75 - Ep;
1045  } else {
1046  Efp = ( Gf / ( h * E * Ep ) + ( 2.13 + ParMd ) * Ep ) / ( 2.73 - ParMd ) - Ep;
1047  }
1048 
1049  if ( Efp <= 0. ) {
1050  //MicroplaneMaterial::_error("Warning: negative Efp encountered");
1051  OOFEM_ERROR("negative Efp encountered");
1052  }
1053 
1054  return;
1055  }
1056 }
1057 
1058 /*
1059  * double
1060  * MDM::giveParameterEfp(const FloatArray& reducedStrain, GaussPoint* gp)
1061  * {
1062  * if (Efp > 0.)
1063  * return Efp;
1064  *
1065  *
1066  * StructuralCrossSection *crossSection = (StructuralCrossSection*) gp -> giveElement()->giveCrossSection();
1067  * FloatArray strainVector, principalStrain;
1068  * FloatMatrix dirs;
1069  * double h;
1070  *
1071  * if (nonlocal) h = 1.0;
1072  * else {
1073  * crossSection->giveFullCharacteristicVector(strainVector, gp, reducedStrain);
1074  * this->computePrincipalValDir (principalStrain, dirs,
1075  * strainVector,
1076  * principal_strain);
1077  *
1078  * // find EigenVector With Largest EigenValue
1079  * int indx = 1;
1080  * double max = principalStrain.at(1);
1081  * if (principalStrain.at(2) > max) indx = 2;
1082  * if (principalStrain.at(3) > max) indx = 3;
1083  *
1084  * FloatArray dir (3);
1085  * dir.at(1) = dirs.at(1,indx);
1086  * dir.at(2) = dirs.at(2,indx);
1087  * dir.at(3) = dirs.at(3,indx);
1088  *
1089  * h = gp->giveElement()->giveCharacteristicLength (dir);
1090  * }
1091  *
1092  * double E = this -> giveLinearElasticMaterial()->give(Ex);
1093  * if (nsd==2)
1094  * Efp = (Gf/(h*E*Ep)+1.2*Ep)/1.75 - Ep;
1095  * else
1096  * Efp = (Gf/(h*E*Ep)+(2.13+ParMd)*Ep)/(2.73-ParMd) - Ep;
1097  * if (Efp<=0.)
1098  * MicroplaneMaterial::_error("Warning: negative Efp encountered");
1099  *
1100  * return Efp;
1101  * }
1102  */
1103 
1104 void
1106 {
1107  if ( this->mdmMode == mdm_3d ) {
1108  MicroplaneMaterial :: initializeData(numberOfMicroplanes);
1109  } else if ( this->mdmMode == mdm_2d ) {
1110  if ( numberOfMicroplanes > MAX_NUMBER_OF_MICROPLANES ) {
1111  //MicroplaneMaterial::_error("initializeData: required number of microplanes too big");
1112  OOFEM_ERROR("required number of microplanes too big");
1113  }
1114 
1115  int iplane;
1116  int i, ii, jj;
1117  double alpha = M_PI / numberOfMicroplanes;
1118  FloatArray n(3), m(3), l(3);
1119 
1120  int ij [ 6 ] [ 2 ] = { { 1, 1 }, { 2, 2 }, { 3, 3 }, { 2, 3 }, { 3, 1 }, { 1, 2 } };
1121 
1122  for ( iplane = 0; iplane < numberOfMicroplanes; iplane++ ) {
1123  microplaneWeights [ iplane ] = alpha;
1124 
1125  n.at(1) = microplaneNormals [ iplane ] [ 0 ] = cos(iplane * alpha);
1126  n.at(2) = microplaneNormals [ iplane ] [ 1 ] = sin(iplane * alpha);
1127  n.at(3) = microplaneNormals [ iplane ] [ 2 ] = 0.0;
1128 
1129  // compute projection tensors for each microplane
1130  m.at(1) = n.at(2);
1131  m.at(2) = -n.at(1);
1132  m.at(3) = 0.0;
1133 
1134  l.at(1) = 0.0;
1135  l.at(2) = 0.0;
1136  l.at(3) = 1.0;
1137 
1138  for ( i = 0; i < 6; i++ ) {
1139  ii = ij [ i ] [ 0 ];
1140  jj = ij [ i ] [ 1 ];
1141 
1142  N [ iplane ] [ i ] = n.at(ii) * n.at(jj);
1143  M [ iplane ] [ i ] = 0.5 * ( m.at(ii) * n.at(jj) + m.at(jj) * n.at(ii) );
1144  L [ iplane ] [ i ] = 0.5 * ( l.at(ii) * n.at(jj) + l.at(jj) * n.at(ii) );
1145  }
1146  } // end loop over mplanes
1147 
1148  //} else MicroplaneMaterial::_error("initializeData: Unknown MDMModeType ecountered");
1149  } else {
1150  OOFEM_ERROR("Unknown MDMModeType ecountered");
1151  }
1152 }
1153 
1154 
1155 void
1157 {
1158  /* Implements the service updating local variables in given integration points,
1159  * which take part in nonlocal average process.
1160  * The current implementation computes the localDamageTensor and stores it in
1161  * corresponding status variable.
1162  * This service is declared at StructuralNonlocalMaterial level.
1163  */
1164  MDMStatus *status = static_cast< MDMStatus * >( this->giveStatus(gp) );
1165  FloatMatrix tempDamageTensor;
1166 
1167  this->computeLocalDamageTensor(tempDamageTensor, strainVector, gp, tStep);
1168  status->setLocalDamageTensorForAverage(tempDamageTensor);
1169 }
1170 
1171 
1172 double
1174 {
1175  // Bell shaped function decaying with the distance.
1176 
1177  double dist = src.distance(coord);
1178 
1179  if ( ( dist >= 0. ) && ( dist <= this->R ) ) {
1180  double help = ( 1. - dist * dist / ( R * R ) );
1181  return help * help;
1182  }
1183 
1184  return 0.0;
1185 }
1186 
1187 
1188 int
1190 {
1191  int result = 0;
1192  FloatArray intVal;
1193  IntArray toMap(1);
1194  MDMStatus *status = static_cast< MDMStatus * >( this->giveStatus(gp) );
1195 
1196  toMap.at(1) = ( int ) IST_MicroplaneDamageValues;
1197 
1198  // Set up source element set if not set up by user
1199  if ( sourceElemSet == NULL ) {
1200  sourceElemSet = new Set(0, oldd);
1201  IntArray el;
1202  // compile source list to contain all elements on old odmain with the same material id
1203  for ( int i = 1; i <= oldd->giveNumberOfElements(); i++ ) {
1204  if ( oldd->giveElement(i)->giveMaterial()->giveNumber() == this->giveNumber() ) {
1205  // add oldd domain element to source list
1206  el.followedBy(i, 10);
1207  }
1208  }
1210  }
1211 
1212 #ifndef MDM_MAPPING_DEBUG
1213  this->mapper.init(oldd, toMap, gp, * sourceElemSet, tStep);
1214  result = mapper.mapVariable(intVal, gp, IST_MicroplaneDamageValues, tStep);
1215 #else
1216  if ( mapperType == mdm_cpt ) {
1217  this->mapper2.init(oldd, toMap, gp, * sourceElemSet, tStep);
1218  result = mapper2.mapVariable(intVal, gp, IST_MicroplaneDamageValues, tStep);
1219  } else if ( mapperType == mdm_sft ) {
1220  this->mapperSFT.init(oldd, toMap, gp, * sourceElemSet, tStep);
1221  result = mapperSFT.mapVariable(intVal, gp, IST_MicroplaneDamageValues, tStep);
1222  } else if ( mapperType == mdm_lst ) {
1223  this->mapperLST.init(oldd, toMap, gp, * sourceElemSet, tStep);
1224  result = mapperLST.mapVariable(intVal, gp, IST_MicroplaneDamageValues, tStep);
1225  } else {
1226  OOFEM_ERROR("unsupported Mapper id");
1227  }
1228 
1229 #endif
1230 
1231  if ( formulation == COMPLIANCE_DAMAGE ) {
1232  for ( int i = 1; i <= intVal.giveSize(); i++ ) {
1233  if ( intVal.at(i) < 1.0 ) {
1234  intVal.at(i) = 1.0;
1235  }
1236  }
1237  } else {
1238  for ( int i = 1; i <= intVal.giveSize(); i++ ) {
1239  if ( intVal.at(i) < 0.0 ) {
1240  intVal.at(i) = 0.0;
1241  }
1242 
1243  if ( intVal.at(i) > 1.0 ) {
1244  intVal.at(i) = 1.0;
1245  }
1246  }
1247  }
1248 
1249  if ( result ) {
1250  status->setMicroplaneTempDamageValues(intVal);
1251  }
1252 
1253  // map stress, since it is necessary for keeping the
1254  // trace of stress (sv)
1255 
1256  toMap.resize(2);
1257  toMap.at(1) = ( int ) IST_StrainTensor;
1258  toMap.at(2) = ( int ) IST_StressTensor;
1259  this->mapper2.init(oldd, toMap, gp, * sourceElemSet, tStep);
1260 
1261  result = mapper2.mapVariable(intVal, gp, IST_StressTensor, tStep);
1262  if ( result ) {
1263  status->letTempStressVectorBe(intVal);
1264  }
1265 
1266  result = mapper2.mapVariable(intVal, gp, IST_StrainTensor, tStep);
1267  if ( result ) {
1268  status->letTempStrainVectorBe(intVal);
1269  }
1270 
1271  status->updateYourself(tStep);
1272 
1273  return result;
1274 }
1275 
1276 
1277 int
1279 {
1280  int result = 1;
1281  FloatArray intVal, strain;
1282  MDMStatus *status = static_cast< MDMStatus * >( this->giveStatus(gp) );
1283 
1284  // now update all internal vars accordingly
1285  strain = status->giveStrainVector();
1286  this->giveRealStressVector(intVal, gp, strain, tStep);
1287  gp->updateYourself(tStep);
1288  return result;
1289 }
1290 
1291 
1292 int
1294 {
1295 #ifndef MDM_MAPPING_DEBUG
1296  this->mapper.finish(tStep);
1297 #else
1298  this->mapperSFT.finish(tStep);
1299  this->mapperLST.finish(tStep);
1300 #endif
1301  this->mapper2.finish(tStep);
1302  return 1;
1303 }
1304 
1305 
1306 Interface *
1308 {
1310  return static_cast< StructuralNonlocalMaterialExtensionInterface * >(this);
1311  } else if ( type == MaterialModelMapperInterfaceType ) {
1312  return static_cast< MaterialModelMapperInterface * >(this);
1313  } else {
1314  return NULL;
1315  }
1316 }
1317 
1318 int
1320 {
1321  MDMStatus *status = static_cast< MDMStatus * >( this->giveStatus(ip) );
1322 
1323  this->buildNonlocalPointTable(ip);
1324  this->updateDomainBeforeNonlocAverage(tStep);
1325 
1326  return (status->giveLocalDamageTensorForAveragePtr()->storeYourself(buff) == CIO_OK);
1327 }
1328 
1329 int
1331 {
1332  int result;
1333  MDMStatus *status = static_cast< MDMStatus * >( this->giveStatus(ip) );
1334  FloatMatrix _LocalDamageTensorForAverage;
1335 
1336  result = (_LocalDamageTensorForAverage.restoreYourself(buff) == CIO_OK);
1337  status->setLocalDamageTensorForAverage(_LocalDamageTensorForAverage);
1338  return result;
1339 }
1340 
1341 int
1343 {
1344  //
1345  // Note: status localStrainVectorForAverage memeber must be properly sized!
1346  //
1347  if ( nonlocal ) {
1348  FloatMatrix _help(nsd, nsd);
1349  return _help.givePackSize(buff);
1350  } else {
1351  return 0;
1352  }
1353 }
1354 
1355 
1356 double
1358 {
1359  //
1360  // The values returned come from mesurement
1361  // do not change them unless you know what are you doing
1362  //
1363  double cost = 1.5;
1364 
1365  if ( nsd == 2 ) {
1366  cost = 1.5;
1367  } else if ( nsd == 3 ) {
1368  cost = 1.8;
1369  }
1370 
1371  if ( nonlocal ) {
1372  MDMStatus *status = static_cast< MDMStatus * >( this->giveStatus(gp) );
1373  int size = status->giveIntegrationDomainList()->size();
1374  // just a guess (size/10) found optimal
1375  // cost *= (1.0 + (size/10)*0.5);
1376  cost *= ( 1.0 + size / 15.0 );
1377  }
1378 
1379  return cost;
1380 }
1381 
1382 
1383 
1384 
1385 
1386 MDMStatus :: MDMStatus(int n, int nsd, int nmplanes, Domain *d, GaussPoint *g) : StructuralMaterialStatus(n, d, g), StructuralNonlocalMaterialStatusExtensionInterface(), Psi(nmplanes), PsiTemp(nmplanes), DamageTensor(nsd, nsd), DamageTensorTemp(nsd, nsd), tempDamageTensorEigenValues(nsd), damageTensorEigenValues(nsd), tempDamageTensorEigenVectors(nsd, nsd), damageTensorEigenVectors(nsd, nsd)
1387 {
1388  for ( int i = 1; i <= nsd; i++ ) {
1391  }
1392 }
1393 
1394 
1396 
1399 {
1400  contextIOResultType iores;
1401 
1402  // save parent class status
1403  if ( ( iores = StructuralMaterialStatus :: saveContext(stream, mode, obj) ) != CIO_OK ) {
1404  THROW_CIOERR(iores);
1405  }
1406 
1407  if ( ( iores = Psi.storeYourself(stream) ) != CIO_OK ) {
1408  THROW_CIOERR(iores);
1409  }
1410 
1411  if ( ( iores = DamageTensor.storeYourself(stream) ) != CIO_OK ) {
1412  THROW_CIOERR(iores);
1413  }
1414 
1415  if ( ( iores = damageTensorEigenValues.storeYourself(stream) ) != CIO_OK ) {
1416  THROW_CIOERR(iores);
1417  }
1418 
1419  if ( ( iores = damageTensorEigenVectors.storeYourself(stream) ) != CIO_OK ) {
1420  THROW_CIOERR(iores);
1421  }
1422 
1423  return CIO_OK;
1424 }
1425 
1426 
1429 {
1430  contextIOResultType iores;
1431 
1432  // read parent class status
1433  if ( ( iores = StructuralMaterialStatus :: restoreContext(stream, mode, obj) ) != CIO_OK ) {
1434  THROW_CIOERR(iores);
1435  }
1436 
1437  if ( ( iores = Psi.restoreYourself(stream) ) != CIO_OK ) {
1438  THROW_CIOERR(iores);
1439  }
1440 
1441  if ( ( iores = DamageTensor.restoreYourself(stream) ) != CIO_OK ) {
1442  THROW_CIOERR(iores);
1443  }
1444 
1445  if ( ( iores = damageTensorEigenValues.restoreYourself(stream) ) != CIO_OK ) {
1446  THROW_CIOERR(iores);
1447  }
1448 
1449  if ( ( iores = damageTensorEigenVectors.restoreYourself(stream) ) != CIO_OK ) {
1450  THROW_CIOERR(iores);
1451  }
1452 
1453  return CIO_OK;
1454 }
1455 
1456 void
1458 {
1460 
1461  Psi = PsiTemp;
1465 }
1466 
1467 void
1469 {
1471 
1472  PsiTemp = Psi;
1476 }
1477 
1478 void
1480 {
1482  fprintf(file, "status { ");
1483 
1484  fprintf(file, " compliance on microplanes: ");
1485  for ( auto &val : Psi ) {
1486  fprintf( file, " %.4e", val );
1487  }
1488 
1489  fprintf(file, ", complianceTensorEigenVectors ");
1490  for ( int i = 1; i <= damageTensorEigenVectors.giveNumberOfRows(); i++ ) {
1491  fprintf(file, "{");
1492  for ( int j = 1; j <= damageTensorEigenVectors.giveNumberOfColumns(); j++ ) {
1493  fprintf( file, " %.4e", damageTensorEigenVectors.at(j, i) );
1494  }
1495 
1496  fprintf(file, "}");
1497  }
1498 
1499  fprintf(file, "}");
1500 
1501  fprintf(file, ", complianceTensorEigenValues ");
1502  for ( auto &val : damageTensorEigenValues ) {
1503  fprintf( file, " %.4e", val );
1504  }
1505 
1506  fprintf(file, "}\n");
1507 }
1508 
1509 Interface *
1511 {
1513  return this;
1514  } else {
1515  return NULL;
1516  }
1517 }
1518 } // end namespace oofem
1519  //
virtual void finish(TimeStep *tStep)
Finishes the mapping for given time step.
virtual void updateYourself(TimeStep *tStep)
Update equilibrium history variables according to temp-variables.
Definition: structuralms.C:96
InternalStateType
Type representing the physical meaning of element or constitutive model internal variable.
Abstract base class for all nonlocal structural materials.
void setField(int item, InputFieldType id)
MaterialMode giveMaterialMode()
Returns corresponding material mode of receiver.
Definition: gausspoint.h:191
int giveNumberOfColumns() const
Returns number of columns of receiver.
Definition: floatmatrix.h:158
int numberOfMicroplanes
Number of microplanes.
int ndc
Number of damage components.
Definition: mdm.h:168
void letTempStrainVectorBe(const FloatArray &v)
Assigns tempStrainVector to given vector v.
Definition: structuralms.h:137
MDMMapperType mapperType
Definition: mdm.h:206
double mdm_Ep
Parameter controlling the elastic limit.
Definition: mdm.h:174
#define _IFT_MDM_efp
Definition: mdm.h:81
double computeShearMStrainComponent(Microplane *mplane, const FloatArray &macroStrain)
Computes the shear component (in m direction) of macro strain on given microplane.
virtual MaterialStatus * giveStatus(GaussPoint *gp) const
Returns material status of receiver in given integration point.
Definition: material.C:244
double L[MAX_NUMBER_OF_MICROPLANES][6]
Shear projection tensors (l direction) for all microplanes.
void updateDomainBeforeNonlocAverage(TimeStep *tStep)
Updates data in all integration points before nonlocal average takes place.
virtual int hasMaterialModeCapability(MaterialMode mode)
Tests if material supports material mode.
Definition: mdm.C:86
Class and object Domain.
Definition: domain.h:115
#define MAX_NUMBER_OF_MICROPLANES
void endIPNonlocalAverage(GaussPoint *gp)
Notifies the receiver, that the nonlocal averaging has been finished for given ip.
void init(Domain *dold, IntArray &varTypes, GaussPoint *gp, Set &sourceElemSet, TimeStep *tStep, bool iCohesiveZoneGP=false)
Initializes the receiver state before mapping.
virtual int giveIPValue(FloatArray &answer, GaussPoint *gp, InternalStateType type, TimeStep *tStep)
Returns the integration point corresponding value in Reduced form.
Definition: mdm.C:667
MDMFormulatrionType
Definition: mdm.h:164
virtual void givePlaneStressStiffMtrx(FloatMatrix &answer, MatResponseMode mmode, GaussPoint *gp, TimeStep *tStep)
Method for computing plane stress stiffness matrix of receiver.
Definition: mdm.C:650
For computing principal strains from engineering strains.
virtual Interface * giveInterface(InterfaceType it)
Interface requesting service.
Definition: mdm.C:1307
virtual void giveInputRecord(DynamicInputRecord &input)
Setups the input record string of receiver.
Definition: mdm.C:877
virtual int mapVariable(FloatArray &answer, GaussPoint *gp, InternalStateType type, TimeStep *tStep)
Maps and update the unknown of given type from old mesh oldd to new mesh to which gp belongs to...
MDMMapperType
Definition: mdm.h:205
double E
Young&#39;s modulus.
#define FORMT33(i, j, ij)
Definition: mdm.C:935
void computeLocalDamageTensor(FloatMatrix &tempDamageTensor, const FloatArray &totalStrain, GaussPoint *gp, TimeStep *tStep)
Definition: mdm.C:206
double M[MAX_NUMBER_OF_MICROPLANES][6]
Shear projection tensors (m direction) for all microplanes.
virtual void updateBeforeNonlocAverage(const FloatArray &strainVector, GaussPoint *gp, TimeStep *tStep)
Declares the service updating local variables in given integration points, which take part in nonloca...
Definition: mdm.C:1156
#define LARGE_EXPONENT
Definition: mdm.C:273
virtual double predictRelativeComputationalCost(GaussPoint *gp)
Returns the weight representing relative computational cost of receiver The reference material model ...
Definition: mdm.C:1357
double ParMd
(m/E*Ep)
Definition: mdm.h:177
void computeEffectiveStress(FloatArray &stressPDC, const FloatArray &strainPDC, GaussPoint *gp, TimeStep *tStep)
Definition: mdm.C:465
The purpose of DataStream abstract class is to allow to store/restore context to different streams...
Definition: datastream.h:54
contextIOResultType storeYourself(DataStream &stream) const
Definition: floatarray.C:872
virtual int giveIPValue(FloatArray &answer, GaussPoint *gp, InternalStateType type, TimeStep *tStep)
Returns the integration point corresponding value in Reduced form.
double Gf
Fracture energy (necessary to determine Ep and Efp if not given).
Definition: mdm.h:181
virtual ~MDMStatus()
Definition: mdm.C:1395
FloatMatrix damageTensorEigenVectors
Definition: mdm.h:106
void computeDamageTensor(FloatMatrix &tempDamageTensor, const FloatArray &totalStrain, GaussPoint *gp, TimeStep *tStep)
Definition: mdm.C:161
double & at(int i)
Coefficient access function.
Definition: floatarray.h:131
int max(int i, int j)
Returns bigger value form two given decimals.
Definition: mathfem.h:71
void transformStrainToPDC(FloatArray &answer, FloatArray &strain, FloatMatrix &t, GaussPoint *gp)
Definition: mdm.C:371
#define _IFT_MDM_mapper
Definition: mdm.h:87
The class representing the general material model adaptive mapping interface.
This class implements a structural material status information.
Definition: structuralms.h:65
double microplaneNormals[MAX_NUMBER_OF_MICROPLANES][3]
Normals of microplanes.
Microplane * giveMicroplane(int i, GaussPoint *masterGp)
Returns i-th microplane belonging to master-macro-integration point. )-based indexing.
double computeDamageOnPlane(GaussPoint *gp, Microplane *mplane, const FloatArray &strain)
Definition: mdm.C:277
#define Ex
Definition: matconst.h:59
const FloatMatrix & giveTempDamageTensorEigenVec()
Definition: mdm.h:116
void transformStiffnessfromPDC(FloatMatrix &de, const FloatMatrix &t)
Definition: mdm.C:634
virtual bool hasField(InputFieldType id)=0
Returns true if record contains field identified by idString keyword.
virtual IRResultType initializeFrom(InputRecord *ir)
Initializes receiver according to object description stored in input record.
Definition: mdm.C:783
#define FORMT44(i, j, ij)
Definition: mdm.C:937
void buildNonlocalPointTable(GaussPoint *gp)
Builds list of integration points which take part in nonlocal average in given integration point...
virtual int estimatePackSize(DataStream &buff, GaussPoint *ip)
Estimates the necessary pack size to hold all packed data of receiver.
Definition: mdm.C:1342
Element * giveElement()
Returns corresponding element to receiver.
Definition: gausspoint.h:188
void setTempDamageTensor(FloatMatrix src)
Definition: mdm.h:127
#define S(p)
Definition: mdm.C:481
void setMicroplaneTempDamageValues(FloatArray src)
Definition: mdm.h:123
std::vector< localIntegrationRecord > * giveIntegrationDomainList()
Returns integration list of receiver.
int giveNumberOfElements() const
Returns number of elements in domain.
Definition: domain.h:434
virtual double computeWeightFunction(const FloatArray &src, const FloatArray &coord)
Evaluates the basic nonlocal weight function for two points with given coordinates.
Definition: mdm.C:1173
int type_dam
Definition: mdm.h:170
int givePackSize(DataStream &buff) const
Definition: floatmatrix.C:1905
virtual void giveThermalDilatationVector(FloatArray &answer, GaussPoint *gp, TimeStep *tStep)
Returns a vector of coefficients of thermal dilatation in direction of each material principal (local...
Definition: mdm.C:771
Material status class MDMStatus associated to MDM matarial.
Definition: mdm.h:97
void giveStressDependentPartOfStrainVector(FloatArray &answer, GaussPoint *gp, const FloatArray &reducedStrainVector, TimeStep *tStep, ValueModeType mode)
Method for subtracting from reduced space strain vector its stress-independent parts (caused by tempe...
MaterialMode
Type representing material mode of integration point.
Definition: materialmode.h:89
virtual void initTempStatus()
Initializes the temporary internal variables, describing the current state according to previously re...
Definition: mdm.C:1468
virtual void printOutputAt(FILE *file, TimeStep *tStep)
Print receiver&#39;s output to given stream.
Definition: structuralms.C:73
static void computePrincipalValDir(FloatArray &answer, FloatMatrix &dir, const FloatArray &s, stressStrainPrincMode mode)
Computes principal values and directions of stress or strain vector.
Class implementing an array of integers.
Definition: intarray.h:61
int & at(int i)
Coefficient access function.
Definition: intarray.h:103
MatResponseMode
Describes the character of characteristic material matrix.
void rotateTensor4(FloatMatrix &Dlocal, const FloatMatrix &t)
Definition: mdm.C:923
virtual int MMI_update(GaussPoint *gp, TimeStep *tStep, FloatArray *estrain=NULL)
Updates the required internal state variables from previously mapped values.
Definition: mdm.C:1278
void setElementList(IntArray newElements)
Sets list of elements within set.
Definition: set.C:204
void giveMaterialStiffnessMatrix(FloatMatrix &answer, MatResponseMode mode, GaussPoint *gp, TimeStep *tStep)
Definition: mdm.C:525
virtual void initializeData(int numberOfMicroplanes)
Initializes internal data (integration weights, microplane normals and computes projection tensors)...
#define THROW_CIOERR(e)
Definition: contextioerr.h:61
void setLocalDamageTensorForAverage(FloatMatrix src)
Definition: mdm.h:128
contextIOResultType storeYourself(DataStream &stream) const
Definition: floatmatrix.C:1852
FloatMatrix tempDamageTensorEigenVectors
Definition: mdm.h:106
FloatArray tempDamageTensorEigenValues
Principal damage directions.
Definition: mdm.h:105
static void giveFullSymVectorForm(FloatArray &answer, const FloatArray &vec, MaterialMode matMode)
Converts the reduced unsymmetric Voigt vector (2nd order tensor) to full form.
virtual int mapVariable(FloatArray &answer, GaussPoint *gp, InternalStateType type, TimeStep *tStep)
Maps and update the unknown of given type from old mesh oldd to new mesh to which gp belongs to...
const FloatArray & giveDamageTensorEigenVals()
Definition: mdm.h:115
IRResultType initializeFrom(InputRecord *ir)
virtual int MMI_map(GaussPoint *gp, Domain *oldd, TimeStep *tStep)
Maps the required internal state variables from old mesh oldd to given ip.
Definition: mdm.C:1189
StructuralMaterial * giveLinearElasticMaterial()
Returns reference to undamaged (bulk) material.
Definition: mdm.h:311
StructuralMaterial * linearElasticMaterial
Reference to bulk (undamaged) material.
Definition: mdm.h:189
double distance(const FloatArray &x) const
Computes the distance between position represented by receiver and position given as parameter...
Definition: floatarray.C:489
double giveMicroplaneDamage(int m)
Definition: mdm.h:120
bool jaco_(FloatArray &eval, FloatMatrix &v, int nf)
Computes eigenvalues and eigenvectors of receiver (must be symmetric) The receiver is preserved...
Definition: floatmatrix.C:1912
virtual double give(int aProperty, GaussPoint *gp)
Returns the value of material property &#39;aProperty&#39;.
Definition: material.C:52
virtual IRResultType initializeFrom(InputRecord *ir)
Initializes receiver according to object description stored in input record.
virtual void giveStiffnessMatrix(FloatMatrix &answer, MatResponseMode mode, GaussPoint *gp, TimeStep *tStep)
Computes the stiffness matrix for giveRealStressVector of receiver in given integration point...
virtual void updateYourself(TimeStep *tStep)
Updates internal state of receiver after finishing time step.
Definition: gausspoint.C:141
virtual void updateYourself(TimeStep *tStep)
Update equilibrium history variables according to temp-variables.
Definition: mdm.C:1457
MDMModeType mdmMode
Definition: mdm.h:186
#define FORMT66(i, j, ij)
Definition: mdm.C:939
void applyDamageToStiffness(FloatMatrix &d, GaussPoint *gp)
Definition: mdm.C:549
virtual MaterialStatus * CreateStatus(GaussPoint *gp) const
Creates new copy of associated status and inserts it into given integration point.
Definition: mdm.C:75
static void giveReducedSymVectorForm(FloatArray &answer, const FloatArray &vec, MaterialMode matMode)
Converts the full unsymmetric Voigt vector (2nd order tensor) to reduced form.
#define OOFEM_LOG_INFO(...)
Definition: logger.h:127
Element * giveElement(int n)
Service for accessing particular domain fe element.
Definition: domain.C:160
virtual void giveInputRecord(DynamicInputRecord &input)
Setups the input record of receiver.
#define M_PI
Definition: mathfem.h:52
FloatMatrix DamageTensor
Macroscopic damage tensor.
Definition: mdm.h:103
This class implements an isotropic linear elastic material in a finite element problem.
const FloatMatrix & giveDamageTensor()
Definition: mdm.h:126
virtual void initializeData(int numberOfMicroplanes)
Initializes internal data (integration weights, microplane normals and computes projection tensors)...
Definition: mdm.C:1105
#define OOFEM_ERROR(...)
Definition: error.h:61
int giveNumber()
Returns number of receiver.
Definition: gausspoint.h:184
double mdm_Efp
Prescribed value of ef-ep.
Definition: mdm.h:176
virtual void give3dMaterialStiffnessMatrix(FloatMatrix &answer, MatResponseMode mode, GaussPoint *gp, TimeStep *tStep)
Computes full 3d material stiffness matrix at given integration point, time, respecting load history ...
Class representing microplane integration point in finite element program.
Definition: microplane.h:74
double R
Interaction radius, related to the nonlocal characteristic length of material.
Definition: mdm.h:194
void times(double f)
Multiplies receiver by factor f.
Definition: floatmatrix.C:1594
std::vector< localIntegrationRecord > * giveIPIntegrationList(GaussPoint *gp)
Returns integration list corresponding to given integration point.
virtual Interface * giveInterface(InterfaceType it)
Interface requesting service.
Definition: mdm.C:1510
Set of elements, boundaries, edges and/or nodes.
Definition: set.h:66
int nsd
Number of spatial dimensions.
Definition: mdm.h:169
contextIOResultType restoreYourself(DataStream &stream)
Definition: floatarray.C:895
#define _IFT_MDM_talpha
Definition: mdm.h:77
void beProductOf(const FloatMatrix &aMatrix, const FloatArray &anArray)
Receiver becomes the result of the product of aMatrix and anArray.
Definition: floatarray.C:676
virtual int packUnknowns(DataStream &buff, TimeStep *tStep, GaussPoint *ip)
Pack all necessary data of integration point (according to element parallel_mode) into given communic...
Definition: mdm.C:1319
MDMModeType
Definition: mdm.h:165
double at(int i, int j) const
Coefficient access function.
Definition: floatmatrix.h:176
void resize(int n)
Checks size of receiver towards requested bounds.
Definition: intarray.C:124
double computeNormalStrainComponent(Microplane *mplane, const FloatArray &macroStrain)
Computes the length of normal strain vector on given microplane.
FloatArray Psi
Damage values on individual microplanes.
Definition: mdm.h:101
virtual void finish(TimeStep *tStep)
Finishes the mapping for given time step.
virtual contextIOResultType restoreContext(DataStream &stream, ContextMode mode, void *obj=NULL)
Restores the receiver state previously written in stream.
Definition: structuralms.C:157
double Ft
Macroscopic tensile strength (necessary to determine Ep and Efp if not given).
Definition: mdm.h:183
void giveRawMDMParameters(double &Efp, double &Ep, const FloatArray &reducedStrain, GaussPoint *gp)
Definition: mdm.C:994
#define HUGE_RELATIVE_COMPLIANCE
Definition: mdm.C:274
#define _IFT_MDM_ep
Definition: mdm.h:82
contextIOResultType restoreYourself(DataStream &stream)
Definition: floatmatrix.C:1877
const FloatMatrix & giveTempDamageTensor()
Definition: mdm.h:125
Class representing vector of real numbers.
Definition: floatarray.h:82
double N[MAX_NUMBER_OF_MICROPLANES][6]
Normal projection tensors for all microplanes.
virtual int MMI_finish(TimeStep *tStep)
Finishes the mapping for given time step.
Definition: mdm.C:1293
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 contextIOResultType restoreContext(DataStream &stream, ContextMode mode, void *obj=NULL)
Restores the receiver state previously written in stream.
Definition: mdm.C:1428
void transformStressFromPDC(FloatArray &answer, const FloatArray &stressPDC, const FloatMatrix &t, GaussPoint *gp)
Definition: mdm.C:484
void letTempStressVectorBe(const FloatArray &v)
Assigns tempStressVector to given vector v.
Definition: structuralms.h:135
virtual IRResultType initializeFrom(InputRecord *ir)
double microplaneWeights[MAX_NUMBER_OF_MICROPLANES]
Integration weights of microplanes.
#define _IFT_MDM_formulation
Definition: mdm.h:85
FloatArray PsiTemp
Definition: mdm.h:101
virtual void giveInputRecord(DynamicInputRecord &input)
Setups the input record string of receiver.
int type_soft
Definition: mdm.h:171
double tempDillatCoeff
Temperature dilatation coeff.
Definition: mdm.h:178
void resize(int rows, int cols)
Checks size of receiver towards requested bounds.
Definition: floatmatrix.C:1358
MDMStatus(int n, int nsd, int nmplanes, Domain *d, GaussPoint *g)
Definition: mdm.C:1386
Class representing the general Input Record.
Definition: inputrecord.h:101
virtual void giveInputRecord(DynamicInputRecord &input)
Setups the input record of receiver.
FloatMatrix DamageTensorTemp
Definition: mdm.h:103
Base class for all nonlocal structural material statuses.
Class Interface.
Definition: interface.h:82
void followedBy(const IntArray &b, int allocChunk=0)
Appends array b at the end of receiver.
Definition: intarray.C:145
virtual void giveRealStressVector(FloatArray &answer, GaussPoint *gp, const FloatArray &reducedStrain, TimeStep *tStep)
Computes the real stress vector for given total strain and integration point.
Definition: mdm.C:95
#define _IFT_MDM_nonloc
Definition: mdm.h:79
void zero()
Zeroes all coefficients of receiver.
Definition: floatarray.C:658
virtual double giveCharacteristicLength(const FloatArray &normalToCrackPlane)
Returns the size of element in the given direction, in some cases adjusted (e.g.
Definition: element.h:874
MDMFormulatrionType formulation
Definition: mdm.h:185
const FloatArray & giveTempDamageTensorEigenVals()
Definition: mdm.h:114
virtual void givePlaneStrainStiffMtrx(FloatMatrix &answer, MatResponseMode mmode, GaussPoint *gp, TimeStep *tStep)
Method for computing plane strain stiffness matrix of receiver.
Definition: mdm.C:658
Class representing the a dynamic Input Record.
void times(double s)
Multiplies receiver with scalar.
Definition: floatarray.C:818
#define _IFT_MDM_ft
Definition: mdm.h:84
void setTempDamageTensorEigenVals(FloatArray src)
Definition: mdm.h:112
long ContextMode
Context mode (mask), defining the type of information written/read to/from context.
Definition: contextmode.h:43
static void giveInvertedVoigtVectorMask(IntArray &answer, MaterialMode mmode)
Gives the inverted version of giveVoigtVectorMask.
virtual void printOutputAt(FILE *file, TimeStep *tStep)
Print receiver&#39;s output to given stream.
Definition: mdm.C:1479
#define MAX_REL_COMPL_TRESHOLD
Definition: mdm.C:546
virtual IRResultType initializeFrom(InputRecord *ir)
void beProductTOf(const FloatMatrix &a, const FloatMatrix &b)
Assigns to the receiver product of .
Definition: floatmatrix.C:397
void zero()
Zeroes all coefficient of receiver.
Definition: floatmatrix.C:1326
virtual void initTempStatus()
Initializes the temporary internal variables, describing the current state according to previously re...
Definition: structuralms.C:108
Domain * giveDomain() const
Definition: femcmpnn.h:100
InterfaceType
Enumerative type, used to identify interface type.
Definition: interfacetype.h:43
virtual int unpackAndUpdateUnknowns(DataStream &buff, TimeStep *tStep, GaussPoint *ip)
Unpack and updates all necessary data of given integration point (according to element parallel_mode)...
Definition: mdm.C:1330
double giveIntegrationScale()
Returns associated integration scale.
static MMAShapeFunctProjection mapperSFT
Mapper used to map internal variables in adaptivity.
Definition: mdm.h:201
int min(int i, int j)
Returns smaller value from two given decimals.
Definition: mathfem.h:59
void computePDC(FloatMatrix &tempDamageTensor, FloatArray &tempDamageTensorEigenVals, FloatMatrix &tempDamageTensorEigenVec)
Definition: mdm.C:349
virtual void giveInputRecord(DynamicInputRecord &input)
Setups the input record string of receiver.
void setTempDamageTensorEigenVec(FloatMatrix src)
Definition: mdm.h:113
Set * sourceElemSet
cached source element set used to map internal variables (adaptivity), created on demand ...
Definition: mdm.h:197
REGISTER_Material(DummyMaterial)
#define IR_GIVE_OPTIONAL_FIELD(__ir, __value, __id)
Macro facilitating the use of input record reading methods.
Definition: inputrecord.h:78
void beProductOf(const FloatMatrix &a, const FloatMatrix &b)
Assigns to the receiver product of .
Definition: floatmatrix.C:337
FloatArray damageTensorEigenValues
Definition: mdm.h:105
const FloatArray & giveMicroplaneDamageValues()
Definition: mdm.h:122
const FloatMatrix * giveLocalDamageTensorForAveragePtr()
Definition: mdm.h:130
virtual void give3dMaterialStiffnessMatrix(FloatMatrix &answer, MatResponseMode mode, GaussPoint *gp, TimeStep *tStep)
Computes full 3d material stiffness matrix at given integration point, time, respecting load history ...
Definition: mdm.C:641
int giveSize() const
Returns the size of receiver.
Definition: floatarray.h:218
virtual IRResultType initializeFrom(InputRecord *ir)
Initializes receiver according to object description stored in input record.
virtual contextIOResultType saveContext(DataStream &stream, ContextMode mode, void *obj=NULL)
Stores receiver state to output stream.
Definition: structuralms.C:133
void applyDamageTranformation(FloatArray &strainPDC, const FloatArray &tempDamageTensorEigenVals)
Definition: mdm.C:416
#define _IFT_MDM_mode
Definition: mdm.h:86
the oofem namespace is to define a context or scope in which all oofem names are defined.
bool isNotEmpty() const
Returns true if receiver is not empty.
Definition: floatarray.h:220
virtual void finish(TimeStep *tStep)
Finishes the mapping for given time step.
#define IR_GIVE_FIELD(__ir, __value, __id)
Macro facilitating the use of input record reading methods.
Definition: inputrecord.h:69
#define _IFT_MDM_parmd
Definition: mdm.h:78
void setMicroplaneTempDamage(int m, double val)
Definition: mdm.h:121
int giveNumber() const
Definition: femcmpnn.h:107
void beInverseOf(const FloatMatrix &src)
Modifies receiver to become inverse of given parameter.
Definition: floatmatrix.C:835
#define _IFT_MDM_gf
Definition: mdm.h:83
const FloatArray & giveStrainVector() const
Returns the const pointer to receiver&#39;s strain vector.
Definition: structuralms.h:105
int nonlocal
Flag indicating local or nonlocal mode.
Definition: mdm.h:192
int giveNumberOfRows() const
Returns number of rows of receiver.
Definition: floatmatrix.h:156
void symmetrized()
Initializes the lower half of the receiver according to the upper half.
Definition: floatmatrix.C:1576
const FloatMatrix & giveLocalDamageTensorForAverage()
Definition: mdm.h:129
double computeShearLStrainComponent(Microplane *mplane, const FloatArray &macroStrain)
Computes the shear component (in l direction) of macro strain on given microplane.
Class representing integration point in finite element program.
Definition: gausspoint.h:93
#define OOFEM_WARNING(...)
Definition: error.h:62
static MMAClosestIPTransfer mapper2
Mapper used to map stresses in adaptivity.
Definition: mdm.h:224
virtual contextIOResultType saveContext(DataStream &stream, ContextMode mode, void *obj=NULL)
Stores receiver state to output stream.
Definition: mdm.C:1398
#define Nt(p, q)
Definition: mdm.C:480
Class representing solution step.
Definition: timestep.h:80
void formTransformationMatrix(FloatMatrix &answer, const FloatMatrix &t, int n)
Definition: mdm.C:943
static MMALeastSquareProjection mapperLST
Definition: mdm.h:202
#define _IFT_MDM_r
Definition: mdm.h:80
virtual Material * giveMaterial()
Definition: element.C:484
void giveInputRecord(DynamicInputRecord &input)
Stores receiver in an input record.
void resize(int s)
Resizes receiver towards requested size.
Definition: floatarray.C:631

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