Memosa-FVM  0.2
StructurePlasticDiscretization.h
Go to the documentation of this file.
1 // This file os part of FVM
2 // Copyright (c) 2012 FVM Authors
3 // See LICENSE file for terms.
4 
5 #ifndef _STRUCTUREPLASTICDISCRETIZATION_H_
6 #define _STRUCTUREPLASTICDISCRETIZATION_H_
7 
8 #include "Field.h"
9 #include "MultiField.h"
10 #include "MultiFieldMatrix.h"
11 #include "Mesh.h"
12 #include "Discretization.h"
13 #include "StorageSite.h"
14 #include "GeomFields.h"
15 #include "CRConnectivity.h"
16 #include "CRMatrixRect.h"
17 #include "Vector.h"
18 #include "GradientModel.h"
19 
20 template<class T, class Diag, class OffDiag>
22 {
23 public:
24 
25  typedef Array<T> TArray;
30 
32  typedef typename CCMatrix::DiagArray DiagArray;
34 
37 
39  const GeomFields& geomFields,
40  Field& varField,
41  const Field& muField,
42  const Field& lambdaField,
43  const Field& alphaField,
44  const Field& varGradientField,
45  const Field& temperatureField,
46  const T& referenceTemperature,
47  const T& residualXXStress,
48  const T& residualYYStress,
49  const T& residualZZStress,
50  const bool& thermo,
51  const bool& residualStress,
52  const Field& devStressField,
53  const Field& VMStressField,
54  Field& plasticStrainField,
55  Field& creepConstant,
56  T& A,
57  const T& B,
58  const T& mm,
59  const T& nn,
60  const T& Sy0,
61  const T& timeStep,
62  const int& creepModel,
63  bool fullLinearization=true) :
64  Discretization(meshes),
65  _geomFields(geomFields),
66  _varField(varField),
67  _muField(muField),
68  _lambdaField(lambdaField),
69  _alphaField(alphaField),
70  _varGradientField(varGradientField),
71  _temperatureField(temperatureField),
72  _referenceTemperature(referenceTemperature),
73  _residualXXStress(residualXXStress),
74  _residualYYStress(residualYYStress),
75  _residualZZStress(residualZZStress),
76  _thermo(thermo),
77  _residualStress(residualStress),
78  _devStressField(devStressField),
79  _VMStressField(VMStressField),
80  _plasticStrainField(plasticStrainField),
81  _creepConstant(creepConstant),
82  _A(A),
83  _B(B),
84  _m(mm),
85  _n(nn),
86  _Sy0(Sy0),
87  _timeStep(timeStep),
88  _creepModel(creepModel),
89  _fullLinearization(fullLinearization)
90  {}
91 
92  void discretize(const Mesh& mesh, MultiFieldMatrix& mfmatrix,
93  MultiField& xField, MultiField& rField)
94  {
95  const StorageSite& iFaces = mesh.getInteriorFaceGroup().site;
96 
97  const StorageSite& cells = mesh.getCells();
98  const VGradArray& devStress =
99  dynamic_cast<const VGradArray&>(_devStressField[cells]);
100  const TArray& VMStress =
101  dynamic_cast<const TArray&>(_VMStressField[cells]);
102  VGradArray& plasticStrain =
103  dynamic_cast<VGradArray&>(_plasticStrainField[cells]);
104  const TArray& creepConstant =
105  dynamic_cast<const TArray&> (_creepConstant[cells]);
106  const int nCells = cells.getCount();
107  const T zero(0.0);
108  const T onethird(1.0/3.0);
109  const T half(0.5);
110  const T twothirds(2.0/3.0);
111  const T one(1.0);
112  const T onepointfive(1.5);
113  const T two(2.0);
114  const T three(3.0);
115  const T six(6.0);
116 
117  if (_creepModel==1)
118  {
119  for(int n=0; n<nCells; n++)
120  {
121  _A = creepConstant[n];
122  T VMPlasticStrain = sqrt(half*
123  (pow(((plasticStrain[n])[0][0]-(plasticStrain[n])[1][1]),2.0) +
124  pow(((plasticStrain[n])[1][1]-(plasticStrain[n])[2][2]),2.0) +
125  pow(((plasticStrain[n])[2][2]-(plasticStrain[n])[0][0]),2.0) +
126  six*(pow(((plasticStrain[n])[0][1]),2.0) +
127  pow(((plasticStrain[n])[1][2]),2.0) +
128  pow(((plasticStrain[n])[2][0]),2.0))));
129  //VMPlasticStrain = sqrt(pow(plasticStrain[n][0][0],two));
130  //VMPlasticStrain = zero;
131  T Sy = _Sy0*(one + _B*pow(VMPlasticStrain,_n));
132  T mult = _A*(pow((VMStress[n]/Sy),_m))/VMStress[n];
133  if (isnan(mult)) mult = 0.0;
134  for(int i=0;i<3;i++)
135  for(int j=0;j<3;j++)
136  (plasticStrain[n])[i][j] += mult*((devStress[n])[i][j])*_timeStep;
137  }
138  }
139  else if(_creepModel==2)
140  {
141  for(int n=0; n<nCells; n++)
142  {
143  _A = creepConstant[n];
144  if (n==0)
145  cout<<"creep initiated"<<endl;
146  T mult = (VMStress[n]/_B)-1.;
147  if (mult<=zero)
148  mult = zero;
149  if (mult!=zero)
150  cout<<"yielding has begun"<<endl;
151 
152  mult = _A*pow(mult,_n)*onepointfive/VMStress[n];
153 
154  for(int i=0;i<3;i++)
155  for(int j=0;j<3;j++)
156  (plasticStrain[n])[i][j] += mult*((devStress[n])[i][j])*_timeStep;
157  }
158  }
159 
160 
161  discretizeFaces(mesh, iFaces, mfmatrix, xField, rField, false, false);
162 
163  /*
164  foreach(const FaceGroupPtr fgPtr, mesh.getInterfaceGroups())
165  {
166  const FaceGroup& fg = *fgPtr;
167  const StorageSite& faces = fg.site;
168  discretizeFaces(mesh, faces, mfmatrix, xField, rField, false, false);
169  }
170  */
171 
172  // boundaries and interfaces
173  foreach(const FaceGroupPtr fgPtr, mesh.getAllFaceGroups())
174  {
175  const FaceGroup& fg = *fgPtr;
176  const StorageSite& faces = fg.site;
177  if (fg.groupType!="interior")
178  {
179  discretizeFaces(mesh, faces, mfmatrix, xField, rField,
180  fg.groupType!="interface",
181  fg.groupType=="symmetry");
182  }
183  }
184  }
185 
186 
187  void discretizeFaces(const Mesh& mesh, const StorageSite& faces,
188  MultiFieldMatrix& mfmatrix,
189  MultiField& xField, MultiField& rField,
190  const bool isBoundary, const bool isSymmetry)
191  {
192  const StorageSite& cells = mesh.getCells();
193 
194  const MultiField::ArrayIndex cVarIndex(&_varField,&cells);
195 
196  const VectorT3Array& faceArea =
197  dynamic_cast<const VectorT3Array&>(_geomFields.area[faces]);
198 
199  const TArray& faceAreaMag =
200  dynamic_cast<const TArray&>(_geomFields.areaMag[faces]);
201 
202  const VectorT3Array& cellCentroid =
203  dynamic_cast<const VectorT3Array&>(_geomFields.coordinate[cells]);
204 
205  const VectorT3Array& faceCentroid =
206  dynamic_cast<const VectorT3Array&>(_geomFields.coordinate[faces]);
207 
208 
209  const TArray& cellVolume =
210  dynamic_cast<const TArray&>(_geomFields.volume[cells]);
211 
212  const CRConnectivity& faceCells = mesh.getFaceCells(faces);
213 
214  VectorT3Array& rCell = dynamic_cast<VectorT3Array&>(rField[cVarIndex]);
215  const VectorT3Array& xCell = dynamic_cast<const VectorT3Array&>(xField[cVarIndex]);
216 
217  const VGradArray& vGradCell =
218  dynamic_cast<const VGradArray&>(_varGradientField[cells]);
219 
220  VGradArray& plasticStrain =
221  dynamic_cast<VGradArray&>(_plasticStrainField[cells]);
222 
223  const TArray& muCell =
224  dynamic_cast<const TArray&>(_muField[cells]);
225 
226  const TArray& lambdaCell =
227  dynamic_cast<const TArray&>(_lambdaField[cells]);
228 
229  const TArray& alphaCell =
230  dynamic_cast<const TArray&>(_alphaField[cells]);
231 
232  const TArray& temperatureCell =
233  dynamic_cast<const TArray&>(_temperatureField[cells]);
234 
235  CCMatrix& matrix = dynamic_cast<CCMatrix&>(mfmatrix.getMatrix(cVarIndex,
236  cVarIndex));
237  CCAssembler& assembler = matrix.getPairWiseAssembler(faceCells);
238  DiagArray& diag = matrix.getDiag();
239 
240 
241  const int nFaces = faces.getCount();
242 
244  const CRConnectivity& cellCells = vgMatrix.getConnectivity();
245  const Array<int>& ccRow = cellCells.getRow();
246  const Array<int>& ccCol = cellCells.getCol();
247 
248  const int nInteriorCells = cells.getSelfCount();
249 
250  const T two(2.0);
251  const T three(3.0);
252 
253  for(int f=0; f<nFaces; f++)
254  {
255  const int c0 = faceCells(f,0);
256  const int c1 = faceCells(f,1);
257 
258  const VectorT3& Af = faceArea[f];
259  const VectorT3 en = Af/faceAreaMag[f];
260 
261  VectorT3 ds=cellCentroid[c1]-cellCentroid[c0];
262 
263  T vol0 = cellVolume[c0];
264  T vol1 = cellVolume[c1];
265 
266  T wt0 = vol0/(vol0+vol1);
267  T wt1 = vol1/(vol0+vol1);
268 
269  if (isBoundary && !isSymmetry)
270  {
271  wt0 = T(1.0);
272  wt1 = T(0.);
273  }
274 
275  T faceMu(1.0);
276  T faceLambda(1.0);
277  T faceAlpha(1.0);
278  T faceTemperature(1.0);
279 
280  Diag& a00 = diag[c0];
281  Diag& a11 = diag[c1];
282  OffDiag& a01 = assembler.getCoeff01(f);
283  OffDiag& a10 = assembler.getCoeff10(f);
284 
285  if (vol0 == 0.)
286  {
287  faceMu = muCell[c1];
288  faceLambda = lambdaCell[c1];
289  faceAlpha = alphaCell[c1];
290  faceTemperature = temperatureCell[c1];
291  }
292  else if (vol1 == 0.)
293  {
294  faceMu = muCell[c0];
295  faceLambda = lambdaCell[c0];
296  faceAlpha = alphaCell[c0];
297  faceTemperature = temperatureCell[c0];
298  }
299  else
300  {
301  faceMu = harmonicAverage(muCell[c0],muCell[c1]);
302  faceLambda = harmonicAverage(lambdaCell[c0],lambdaCell[c1]);
303  faceAlpha = harmonicAverage(alphaCell[c0],alphaCell[c1]);
304  faceTemperature = harmonicAverage(temperatureCell[c0],temperatureCell[c1]);
305  }
306 
307  faceMu = muCell[c0]*wt0 + muCell[c1]*wt1;
308  faceLambda = lambdaCell[c0]*wt0 + lambdaCell[c1]*wt1;
309  faceAlpha = alphaCell[c0]*wt0 + alphaCell[c1]*wt1;
310  faceTemperature = temperatureCell[c0]*wt0 + temperatureCell[c1]*wt1;
311 
312  const VGradType gradF = (vGradCell[c0]*wt0 + vGradCell[c1]*wt1);
313  const VGradType plasticStrainF = (plasticStrain[c0]*wt0 + plasticStrain[c1]*wt1);
314 
317  VectorT3 residualSource(NumTypeTraits<VectorT3>::getZero());
318  const T divU = (gradF[0][0] + gradF[1][1] + gradF[2][2]);
319 
320  const T diffMetric = faceAreaMag[f]*faceAreaMag[f]/dot(faceArea[f],ds);
321  const VectorT3 secondaryCoeff = faceMu*(faceArea[f]-ds*diffMetric);
322 
323  // mu*grad U ^ T + lambda * div U I
324  source[0] = faceMu*(gradF[0][0]*Af[0] + gradF[0][1]*Af[1] + gradF[0][2]*Af[2])
325  + faceLambda*divU*Af[0];
326 
327  source[1] = faceMu*(gradF[1][0]*Af[0] + gradF[1][1]*Af[1] + gradF[1][2]*Af[2])
328  + faceLambda*divU*Af[1];
329 
330  source[2] = faceMu*(gradF[2][0]*Af[0] + gradF[2][1]*Af[1] + gradF[2][2]*Af[2])
331  + faceLambda*divU*Af[2];
332 
333  if(_thermo)
334  {
335  if(mesh.getDimension()==2)
336  thermalSource -= (two*faceLambda+two*faceMu)*faceAlpha*(faceTemperature-_referenceTemperature)*Af;
337  else
338  thermalSource -= (three*faceLambda+two*faceMu)*faceAlpha*(faceTemperature-_referenceTemperature)*Af;
339  }
340 
341  if(_residualStress)
342  {
343  residualSource[0] = _residualXXStress*Af[0];
344  residualSource[1] = _residualYYStress*Af[1];
345  residualSource[2] = _residualZZStress*Af[2];
346  }
347 
349  T divEP = (plasticStrainF[0][0] + plasticStrainF[1][1] + plasticStrainF[2][2]);
350  if (mesh.getDimension() == 2)
351  {
352  divEP = plasticStrainF[0][0] + plasticStrainF[1][1];
353  }
354 
355  creepSource[0] -= (two*faceMu*(plasticStrainF[0][0]*Af[0] + plasticStrainF[1][0]*Af[1] +
356  plasticStrainF[2][0]*Af[2]) + faceLambda*divEP*Af[0]);
357  creepSource[1] -= (two*faceMu*(plasticStrainF[0][1]*Af[0] + plasticStrainF[1][1]*Af[1] +
358  plasticStrainF[2][1]*Af[2]) + faceLambda*divEP*Af[1]);
359  creepSource[2] -= (two*faceMu*(plasticStrainF[0][2]*Af[0] + plasticStrainF[1][2]*Af[1] +
360  plasticStrainF[2][2]*Af[2]) + faceLambda*divEP*Af[2]);
363  if (_fullLinearization)
364  {
365  // loop over level 0 neighbors
366  for(int nnb = ccRow[c0]; nnb<ccRow[c0+1]; nnb++)
367  {
368  const int nb = ccCol[nnb];
369 
370  // get the coefficient from the gradient matrix that uses modified cellCells
371  // getting a copy rather than reference since we might modify it
372  VectorT3 g_nb = vgMatrix.getCoeff(c0,nb);
373 #if 1
374  if (isSymmetry)
375  {
376  const T gnb_dot_nx2 = T(2.0)*dot(en,g_nb);
377  g_nb = gnb_dot_nx2*en;
378  }
379 #endif
380  Diag coeff;
381 
382  for(int i=0; i<3; i++)
383  {
384  for(int j=0; j<3; j++)
385  {
386  coeff(i,j) = wt0*(faceMu*Af[j]*g_nb[i]
387  + faceLambda*Af[i]*g_nb[j]
388  );
389  }
390 
391  for(int k=0; k<3; k++)
392  coeff(i,i) += wt0*secondaryCoeff[k]*g_nb[k];
393  }
394 #if 0
395  if (isSymmetry)
396  {
398 
399  for(int i=0;i<3;i++)
400  for(int j=0; j<3; j++)
401  {
402  if (i==j)
403  R(i,j) = 1.0 - 2*en[i]*en[j];
404  else
405  R(i,j) = - 2*en[i]*en[j];
406  }
407 
408  Diag coeff1(R*coeff*R);
409  coeff += coeff1;
410 
411  }
412 #endif
413  OffDiag& a0_nb = matrix.getCoeff(c0,nb);
414 
415  a0_nb += coeff;
416  a00 -= coeff;
417  a10 += coeff;
418 
419  if (c1 != nb)
420  {
421  // if the coefficient does not exist we assume c1
422  // is a ghost cell for which we don't want an
423  // equation in this matrix
424  if (matrix.hasCoeff(c1,nb))
425  {
426  OffDiag& a1_nb = matrix.getCoeff(c1,nb);
427  a1_nb -= coeff;
428  }
429  }
430  else
431  a11 -= coeff;
432  }
433 
434 
435  if (!isBoundary)
436  {
437  for(int nnb = ccRow[c1]; nnb<ccRow[c1+1]; nnb++)
438  {
439  const int nb = ccCol[nnb];
440  const VectorT3& g_nb = vgMatrix.getCoeff(c1,nb);
441 
442  Diag coeff;
443 
444  for(int i=0; i<3; i++)
445  {
446  for(int j=0; j<3; j++)
447  {
448  coeff(i,j) = wt1*(faceMu*Af[j]*g_nb[i]
449  + faceLambda*Af[i]*g_nb[j]
450  );
451  }
452 
453  for(int k=0; k<3; k++)
454  coeff(i,i) += wt1*secondaryCoeff[k]*g_nb[k];
455  }
456 
457 
458  if (matrix.hasCoeff(c1,nb))
459  {
460  OffDiag& a1_nb = matrix.getCoeff(c1,nb);
461  a1_nb -= coeff;
462  a11 += coeff;
463  }
464  a01 -= coeff;
465 
466 
467  if (c0 != nb)
468  {
469  OffDiag& a0_nb = matrix.getCoeff(c0,nb);
470 
471  a0_nb += coeff;
472  }
473  else
474  a00 += coeff;
475 
476  }
477  }
478  }
479 
480  // mu*gradU, primary part
481 
482 
483  source += faceMu*diffMetric*(xCell[c1]-xCell[c0]);
484 
485  // mu*gradU, secondart part
486 
487 
488  source += gradF*secondaryCoeff;
489 
490  // add flux to the residual of c0 and c1
491  rCell[c0] += source;
492  rCell[c1] -= source;
493 
494  // add flux due to thermal Stress to the residual of c0 and c1
495  rCell[c0] += thermalSource;
496  rCell[c1] -= thermalSource;
497 
498  // add flux due to residual Stress to the residual of c0 and c1
499  rCell[c0] += residualSource;
500  rCell[c1] -= residualSource;
501 
502  // add flux due to creep to the residual of c0 and c1
503  rCell[c0] += creepSource;
504  rCell[c1] -= creepSource;
505 
506  // for Jacobian, use 2*mu + lambda as the diffusivity
507  const T faceDiffusivity = faceMu;
508  const T diffCoeff = faceDiffusivity*diffMetric;
509 
510 
511  a01 +=diffCoeff;
512  a10 +=diffCoeff;
513 
514 
515  a00 -= diffCoeff;
516  a11 -= diffCoeff;
517 
518  }
519  }
520 
521 
522 private:
525  const Field& _muField;
534  const bool _thermo;
535  const bool _residualStress;
540  T _A;
541  const T _B;
542  const T _m;
543  const T _n;
544  const T _Sy0;
545  const T _timeStep;
546  const int _creepModel;
547  const bool _fullLinearization;
548 };
549 
550 #endif
const Array< int > & getCol() const
const Array< int > & getRow() const
const FaceGroup & getInteriorFaceGroup() const
Definition: Mesh.h:181
Matrix & getMatrix(const Index &rowIndex, const Index &colIndex)
shared_ptr< FaceGroup > FaceGroupPtr
Definition: Mesh.h:46
int getSelfCount() const
Definition: StorageSite.h:40
Field coordinate
Definition: GeomFields.h:19
T harmonicAverage(const T &x0, const T &x1)
VGradModelType::GradMatrixType VGradMatrix
Definition: Mesh.h:28
const FaceGroupList & getAllFaceGroups() const
Definition: Mesh.h:193
Definition: Field.h:14
OffDiag & getCoeff(const int i, const int j)
Definition: CRMatrix.h:836
bool hasCoeff(const int i, const int j)
Definition: CRMatrix.h:846
Definition: Mesh.h:49
OffDiag & getCoeff10(const int np)
Definition: CRMatrix.h:131
Coord & getCoeff(const int i, const int j)
Array< Diag > & getDiag()
Definition: CRMatrix.h:856
string groupType
Definition: Mesh.h:42
CRMatrix< Diag, OffDiag, VectorT3 > CCMatrix
Tangent sqrt(const Tangent &a)
Definition: Tangent.h:317
void discretize(const Mesh &mesh, MultiFieldMatrix &mfmatrix, MultiField &xField, MultiField &rField)
const CRConnectivity & getConnectivity() const
pair< const Field *, const StorageSite * > ArrayIndex
Definition: MultiField.h:21
Array< Gradient< VectorT3 > > VGradArray
StructurePlasticDiscretization(const MeshList &meshes, const GeomFields &geomFields, Field &varField, const Field &muField, const Field &lambdaField, const Field &alphaField, const Field &varGradientField, const Field &temperatureField, const T &referenceTemperature, const T &residualXXStress, const T &residualYYStress, const T &residualZZStress, const bool &thermo, const bool &residualStress, const Field &devStressField, const Field &VMStressField, Field &plasticStrainField, Field &creepConstant, T &A, const T &B, const T &mm, const T &nn, const T &Sy0, const T &timeStep, const int &creepModel, bool fullLinearization=true)
const StorageSite & getCells() const
Definition: Mesh.h:109
Field volume
Definition: GeomFields.h:26
OffDiag & getCoeff01(const int np)
Definition: CRMatrix.h:126
const CRConnectivity & getFaceCells(const StorageSite &site) const
Definition: Mesh.cpp:388
static GradMatrixType & getGradientMatrix(const Mesh &mesh, const GeomFields &geomFields)
Definition: Array.h:14
void discretizeFaces(const Mesh &mesh, const StorageSite &faces, MultiFieldMatrix &mfmatrix, MultiField &xField, MultiField &rField, const bool isBoundary, const bool isSymmetry)
int getCount() const
Definition: StorageSite.h:39
Field area
Definition: GeomFields.h:23
PairWiseAssembler & getPairWiseAssembler(const CRConnectivity &pairs)
Definition: CRMatrix.h:867
int getDimension() const
Definition: Mesh.h:105
Field areaMag
Definition: GeomFields.h:25
T dot(const Vector< T, 3 > &a, const Vector< T, 3 > &b)
Definition: Vector.h:253
vector< Mesh * > MeshList
Definition: Mesh.h:439
StorageSite site
Definition: Mesh.h:40