OOFEM  2.4
OOFEM.org - Object Oriented Finite Element Solver
tet21ghostsolid.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 - 2014 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 "../sm/Elements/tet21ghostsolid.h"
36 #include "../sm/Elements/nlstructuralelement.h"
37 #include "../sm/CrossSections/structuralcrosssection.h"
38 #include "fei3dtetquad.h"
39 #include "fei3dtetlin.h"
40 #include "classfactory.h"
41 #include "gausspoint.h"
42 #include "gaussintegrationrule.h"
43 #include "load.h"
44 #include "element.h"
45 #include "dofmanager.h"
46 #include "load.h"
47 #include "bodyload.h"
48 #include "boundaryload.h"
49 #include "neumannmomentload.h"
50 #include "dof.h"
51 #include "mathfem.h"
52 
53 #include <iostream>
54 
55 #ifdef __FM_MODULE
56  #include "fluiddynamicmaterial.h"
57  #include "fluidcrosssection.h"
58 #endif
59 
60 namespace oofem {
61 #define FIXEDJ 0
62 #define FIXEDFinvT 0
63 #define FIXEDpressure 0
64 #define USEUNCOUPLED 1
65 #define USENUMTAN 0
66 #define TESTTANGENT 0
67 
68 #define VELOCITYCOEFF 1.0
69 
70 REGISTER_Element(tet21ghostsolid);
71 
74 
79  1, 2, 3, 8, 9, 10, 15, 16, 17, 22, 23, 24, 28, 29, 30, 34, 35, 36
80 };
82  4, 5, 6, 11, 12, 13, 18, 19, 20, 25, 26, 27, 31, 32, 33, 37, 38, 39
83 };
84 
86 {
88  numberOfDofMans = 10;
89  computeItransform = true;
90 
91  double nu = .25, E = 1;
92  Dghost.resize(6, 6);
93  Dghost.zero();
94  Dghost.at(1, 1) = 1 - nu;
95  Dghost.at(1, 2) = Dghost.at(1, 3) = nu;
96  Dghost.at(2, 2) = 1 - nu;
97  Dghost.at(2, 1) = Dghost.at(2, 3) = nu;
98  Dghost.at(3, 3) = 1 - nu;
99  Dghost.at(3, 1) = Dghost.at(3, 2) = nu;
100  Dghost.at(4, 4) = Dghost.at(5, 5) = Dghost.at(6, 6) = .5 * ( 1 - 2 * nu );
101  Dghost.times( E / ( 1 + nu ) / ( 1 - 2 * nu ) );
102 
104  7, 14, 21, 28
105  };
106 
107  for ( int i = 0, j = 1; i < 10; ++i ) {
108  momentum_ordering(i * 3 + 0) = j++;
109  momentum_ordering(i * 3 + 1) = j++;
110  momentum_ordering(i * 3 + 2) = j++;
111  if ( i <= 3 ) {
112  j++;
113  }
114  j = j + 3;
115  }
116 
117  for ( int i = 0, j = 1; i < 10; ++i ) {
118  j = j + 3;
119  ghostdisplacement_ordering(i * 3 + 0) = j++;
120  ghostdisplacement_ordering(i * 3 + 1) = j++;
121  ghostdisplacement_ordering(i * 3 + 2) = j++;
122  if ( i <= 3 ) {
123  j++;
124  }
125  }
126 }
127 
130 {
131  return & interpolation;
132 }
133 
136 {
137  if ( id == P_f ) {
138  return & interpolation_lin;
139  } else {
140  return & interpolation;
141  }
142 }
143 
144 void
146 // Sets up the array containing the four Gauss points of the receiver.
147 {
148  if ( integrationRulesArray.size() == 0 ) {
149  integrationRulesArray.resize(1);
150  integrationRulesArray [ 0 ].reset( new GaussIntegrationRule(1, this, 1, 6) );
152  }
153 }
154 
155 void
157 {
158  FloatArray a, aPert, intF, intFPert, DintF;
159  double eps = 1e-9;
160 
161  answer.resize(64, 64);
162  answer.zero();
163 
164  this->computeVectorOf(VM_Total, tStep, a);
165 
166  giveInternalForcesVectorGivenSolution(intF, tStep, 0, a);
167 
168  for ( int i = 1; i <= answer.giveNumberOfColumns(); i++ ) {
169  aPert = a;
170  aPert.at(i) = aPert.at(i) + eps;
171 
172  giveInternalForcesVectorGivenSolution(intFPert, tStep, 0, aPert);
173 
174  DintF.operator = ( intF - intFPert );
175  DintF.times(-1 / eps);
176  answer.setColumn(DintF, i);
177  }
178 }
179 
180 void
182 {
183  FloatArray a, aPert, intF, intFPert, DintF;
184  double eps = 1e-9;
185 
186  answer.resize(64, 64);
187  answer.zero();
188 
189  this->computeVectorOf(VM_Total, tStep, a);
190 
191  giveInternalForcesVectorGivenSolutionDebug(intF, tStep, 0, a, true);
192 
193  for ( int i = 1; i <= answer.giveNumberOfColumns(); i++ ) {
194  aPert = a;
195  aPert.at(i) = aPert.at(i) + eps;
196 
197  giveInternalForcesVectorGivenSolutionDebug(intFPert, tStep, 0, aPert, false);
198 
199  DintF.operator = ( intF - intFPert );
200  DintF.times(-1 / eps);
201  answer.setColumn(DintF, i);
202  }
203 }
204 
205 
206 void
208 {
209  this->giveStructuralCrossSection()->giveRealStress_3d(answer, gp, strain, tStep);
210 }
211 
212 void
214 {
215  this->giveStructuralCrossSection()->giveStiffnessMatrix_3d(answer, rMode, gp, tStep);
216 }
217 
218 void
220 {
221 #if USENUMTAN == 1
222  computeNumericStiffnessMatrix(answer, rMode, tStep);
223  return;
224 
225 #endif
226 
227 #ifdef __FM_MODULE
228  FluidDynamicMaterial *fluidMaterial = static_cast< FluidCrossSection * >( this->giveCrossSection() )->giveFluidMaterial();
229 #endif
230 
231  FloatMatrix afDu, afDw, bfuDu, bfuDp, bfpDu, bfpDw, cfwDu;
232  FloatMatrix Kf, G, Kx, Ed, EdB, dNx;
233  FloatArray Nlin, dNv, a, a_prev, a_inc;
234  FloatArray aVelocity, aPressure, aGhostDisplacement, aIncGhostDisplacement;
235 
236  afDu.resize(30, 30);
237  afDu.zero();
238  bfuDu.resize(30, 30); // Remove?
239  bfuDu.zero();
240  bfuDp.resize(30, 4);
241  bfuDp.zero();
242  bfpDu.resize(4, 30);
243  bfpDu.zero();
244  bfpDw.resize(4, 30);
245  bfpDw.zero();
246  cfwDu.resize(30, 30);
247  cfwDu.zero();
248 
249  this->computeVectorOf(VM_Total, tStep, a);
250  if ( !tStep->isTheFirstStep() ) {
251  this->computeVectorOf(VM_Total, tStep->givePreviousStep(), a_prev);
252  } else {
253  a_prev.resize( a.giveSize() );
254  a_prev.zero();
255  }
256  a_inc.operator = ( a - a_prev );
257 
258  aVelocity.beSubArrayOf(a, momentum_ordering);
259  aPressure.beSubArrayOf(a, conservation_ordering);
260  aGhostDisplacement.beSubArrayOf(a, ghostdisplacement_ordering);
261  aIncGhostDisplacement.beSubArrayOf(a_inc, ghostdisplacement_ordering);
262 
263  FloatArray aTotal;
264  aTotal.operator = ( aVelocity + aIncGhostDisplacement * VELOCITYCOEFF ); // Assume deltaT=1 gives that the increment is the velocity
265 
266  for ( auto &gp : *this->giveDefaultIntegrationRulePtr() ) {
267  // gp = this->giveDefaultIntegrationRulePtr()->getIntegrationPoint(0);
268  const FloatArray &lcoords = gp->giveNaturalCoordinates();
269  double detJ = fabs( ( this->interpolation.giveTransformationJacobian( lcoords, FEIElementGeometryWrapper(this) ) ) );
270  double weight = gp->giveWeight();
271 
272  this->interpolation.evaldNdx( dNx, lcoords, FEIElementGeometryWrapper(this) );
273  this->interpolation_lin.evalN( Nlin, lcoords, FEIElementGeometryWrapper(this) );
274 
275  // Move to small deformations
276  dNv.resize(30); // dNv = [dN1/dx dN1/dy dN1/dz dN2/dx dN2/dy dN2/dz ... dN10/dz]
277  for ( int k = 0; k < dNx.giveNumberOfRows(); k++ ) {
278  dNv.at(k * 3 + 1) = dNx.at(k + 1, 1);
279  dNv.at(k * 3 + 2) = dNx.at(k + 1, 2);
280  dNv.at(k * 3 + 3) = dNx.at(k + 1, 3);
281  }
282 
283 #ifdef __FM_MODULE
284  gp->setMaterialMode(_3dFlow);
285  fluidMaterial->giveDeviatoricStiffnessMatrix(Ed, TangentStiffness, gp, tStep);
286  gp->setMaterialMode(_3dMat);
287 #else
288  OOFEM_ERROR("Fluid module missing\n");
289 #endif
290 
291  if ( nlGeometry == 0 ) {
292  FloatMatrix B;
293  this->computeBmatrixAt(gp, B);
294 
295  // Fluid part
296  EdB.beProductOf(Ed, B);
297  Kf.plusProductSymmUpper(B, EdB, detJ * weight);
298  Kf.symmetrized();
299 
300  // Ghost solid part
301  Kx.plusProductSymmUpper(B, EdB, detJ * weight);
302 
303  // Incompressibility part
304  G.plusDyadUnsym(dNv, Nlin, -detJ * weight);
305  } else {
306  int Voigt6 [ 3 ] [ 3 ] = { { 1, 6, 5 }, { 6, 2, 4 }, { 5, 4, 3 } };
307  int Voigt9 [ 3 ] [ 3 ] = { { 1, 6, 5 }, { 9, 2, 4 }, { 8, 7, 3 } };
308 
309  // Compute commonly used matrices
310  FloatArray Fa, Finva, FinvTa;
311  FloatMatrix F, Finv, FinvT, BH, B;
312 
313  this->computeBHmatrixAt(gp, BH);
314  this->computeBmatrixAt(gp, B);
315 
316  computeDeformationGradientVectorFromDispl(Fa, gp, tStep, aGhostDisplacement);
317  F.beMatrixForm(Fa);
318  Finv.beInverseOf(F);
319  Finva.beVectorForm(Finv);
320  FinvT.beTranspositionOf(Finv);
321  FinvTa.beVectorForm(FinvT);
322 
323  FloatArray FinvTaB;
324  FinvTaB.beTProductOf(BH, FinvTa);
325 
326  FloatMatrix NlinFinvTaB;
327  NlinFinvTaB.beDyadicProductOf(Nlin, FinvTaB);
328 
329  double J = F.giveDeterminant();
330 #if FIXEDJ == 1
331  J = 1;
332 #endif
333 
334  // Compute Cauchy stress
335  FloatArray fluidCauchyArray, epsf;
336  FloatMatrix fluidCauchyMatrix;
337  double epsvol, pressure;
338 
339  epsf.beProductOf(B, aTotal);
340  pressure = Nlin.dotProduct(aPressure);
341 
342 #if FIXEDpressure == 1
343  pressure = 1.0;
344 #endif
345 
346  gp->setMaterialMode(_3dFlow);
347  fluidMaterial->computeDeviatoricStressVector(fluidCauchyArray, epsvol, gp, epsf, pressure, tStep);
348  gp->setMaterialMode(_3dMat);
349  fluidCauchyMatrix.beMatrixFormOfStress(fluidCauchyArray);
350 
351  // afDu terms ==========
352  // 1st term ------------
353  FloatArray fluidTwoPointStressArray, BTS;
354  FloatMatrix fluidTwoPointStressMatrix, afuT1;
355 
356  fluidTwoPointStressMatrix.beProductOf(fluidCauchyMatrix, FinvT);
357  fluidTwoPointStressArray.beVectorForm(fluidTwoPointStressMatrix);
358 
359  BTS.beTProductOf(BH, fluidTwoPointStressArray);
360 
361  afuT1.beDyadicProductOf(BTS, FinvTaB);
362  afuT1.times(J * weight * detJ);
363 #if FIXEDJ == 1
364  afuT1.times(0.0);
365 #endif
366  afDu.add(afuT1);
367 
368  // 2nd term ------------ // Works
369  FloatMatrix afuT2;
370  FloatMatrix G, BTG;
371 
372  G.resize(9, 9);
373  G.zero();
374 
375  for ( int i = 1; i <= 3; i++ ) {
376  for ( int j = 1; j <= 3; j++ ) {
377  for ( int k = 1; k <= 3; k++ ) {
378  for ( int l = 1; l <= 3; l++ ) {
379  for ( int m = 1; m <= 3; m++ ) {
380  G.at(Voigt9 [ i - 1 ] [ j - 1 ], Voigt9 [ k - 1 ] [ l - 1 ]) +=
381  Ed.at(Voigt6 [ i - 1 ] [ m - 1 ], Voigt6 [ k - 1 ] [ l - 1 ]) * FinvT.at(m, j);
382  }
383  }
384  }
385  }
386  }
387 
388  BTG.beTProductOf(BH, G);
389  afuT2.beProductOf(BTG, BH);
390  afuT2.times(J * weight * detJ);
391 
392  afDu.add(afuT2);
393 
394  // 3rd term ------------
395  FloatMatrix afuT3;
396  FloatMatrix K, BTK;
397 
398  K.resize(9, 9);
399  K.zero();
400 
401  for ( int i = 1; i <= 3; i++ ) {
402  for ( int j = 1; j <= 3; j++ ) {
403  for ( int k = 1; k <= 3; k++ ) {
404  for ( int l = 1; l <= 3; l++ ) {
405  for ( int m = 1; m <= 3; m++ ) {
406  K.at(Voigt9 [ i - 1 ] [ j - 1 ], Voigt9 [ m - 1 ] [ l - 1 ]) +=
407  fluidCauchyArray.at(Voigt6 [ i - 1 ] [ k - 1 ]) * FinvT.at(k, l) * FinvT.at(m, j);
408  }
409  }
410  }
411  }
412  }
413 
414  BTK.beTProductOf(BH, K);
415  afuT3.beProductOf(BTK, BH);
416  afuT3.times(-J * weight * detJ);
417 #if FIXEDFinvT == 1
418  afuT3.times(0.0);
419 #endif
420  afDu.add(afuT3);
421 
422  // afDw terms ========== // Works
423  afDw.add(afuT2);
424 
425  // bfuDu term ==========
426  // 1st term ------------ // Works
427  FloatMatrix bfuT1;
428  bfuT1.beDyadicProductOf(FinvTaB, FinvTaB);
429  bfuT1.times(-J * pressure * weight * detJ);
430 
431  bfuDu.add(bfuT1);
432 
433  // 2nd term ------------ // Works
434  FloatMatrix C, bfuT2, BTC;
435  C.resize(9, 9);
436  C.zero();
437 
438  for ( int i = 1; i <= 3; i++ ) {
439  for ( int j = 1; j <= 3; j++ ) {
440  for ( int k = 1; k <= 3; k++ ) {
441  for ( int l = 1; l <= 3; l++ ) {
442  C.at(Voigt9 [ i - 1 ] [ j - 1 ], Voigt9 [ k - 1 ] [ l - 1 ]) +=
443  FinvT.at(i, l) * FinvT.at(k, j);
444  }
445  }
446  }
447  }
448 
449  BTC.beTProductOf(BH, C);
450  bfuT2.beProductOf(BTC, BH);
451  bfuT2.times(pressure * J * weight * detJ);
452 
453  bfuDu.add(bfuT2);
454 
455  // bfuDp term ========== // Works
456  FloatMatrix bfuT3;
457  bfuT3.beDyadicProductOf(FinvTaB, Nlin);
458  bfuT3.times(-J * detJ * weight);
459 
460  bfuDp.add(bfuT3);
461 
462  // bfpDu term ==========
463  // 1st term ------------
464  FloatMatrix bfpT1, A_IVm, Bvm;
465  FloatArray A_IVa, Bv;
466 
467  Bv.beProductOf(BH, aTotal);
468  Bvm.beMatrixForm(Bv);
469  double FinvTaBv = FinvTa.dotProduct(Bv);
470 
471  A_IVm.resize(3, 3);
472  A_IVm.zero();
473 
474  for ( int k = 1; k <= 3; k++ ) {
475  for ( int l = 1; l <= 3; l++ ) {
476  for ( int i = 1; i <= 3; i++ ) {
477  for ( int j = 1; j <= 3; j++ ) {
478  A_IVm.at(k, l) += Bvm.at(i, j) * FinvT.at(i, l) * FinvT.at(k, j);
479  }
480  }
481  }
482  }
483 
484  A_IVa.beVectorForm(A_IVm);
485 
486  bfpT1 = NlinFinvTaB;
487  bfpT1.times(-J * detJ * weight * FinvTaBv);
488 #if FIXEDJ == 1
489  bfpT1.times(0.0);
490 #endif
491 
492  bfpDu.add(bfpT1);
493 
494  // 2nd term ------------
495  FloatMatrix bfpT2;
496  FloatArray AiiB;
497 
498  AiiB.beTProductOf(BH, A_IVa);
499  bfpT2.beDyadicProductOf(Nlin, AiiB);
500  bfpT2.times(J * detJ * weight);
501 #if FIXEDFinvT == 1
502  bfpT2.times(0.0);
503 #endif
504  bfpDu.add(bfpT2);
505 
506 
507  // 3rd term ------------ // Works
508  FloatMatrix bfpT3;
509  bfpT3 = NlinFinvTaB;
510  bfpT3.times(-J * detJ * weight);
511  bfpDu.add(bfpT3);
512 
513  // bfpDw term ========== // Works
514  // bfpT1 = NlinFinvTaB;
515  // bfpT1.times(-J*detJ*weight);
516  bfpDw.add(bfpT3);
517 
518  // cfwDu term ========== // Works
519  FloatMatrix BTEX, cfwT1;
520  BTEX.beTProductOf(B, Dghost);
521  cfwT1.beProductOf(BTEX, B);
522  cfwT1.times(detJ * weight);
523 
524  cfwDu.add(cfwT1);
525  }
526  }
527 
528  //if (this->globalNumber == 373) { dJda.printYourself("dJda_analytical"); }
529  FloatMatrix GT, temp;
530 
531  GT.beTranspositionOf(G);
532  Kf.symmetrized();
533  Kx.symmetrized();
534 
535  answer.resize(64, 64);
536  answer.zero();
537  temp.resize(64, 64);
538  temp.zero();
539 
547 
548  if ( this->computeItransform ) {
550  }
551 
552  answer.beProductOf(Itransform, temp);
553 
554  // ******************* This is for development purposes only. Compare to numerical stiffness tangent
555 #if TESTTANGENT
556  if ( ( this->globalNumber == 292 ) && ( tStep->giveNumber() > 0 ) ) {
557  double MaxErr = 0.0;
558  FloatMatrix numtan;
559  int imax, jmax;
560 
561  temp.zero();
569 
570  computeNumericStiffnessMatrixDebug(numtan, rMode, tStep);
571  for ( int i = 1; i <= numtan.giveNumberOfRows(); i++ ) {
572  for ( int j = 1; j <= numtan.giveNumberOfRows(); j++ ) {
573  double difference = numtan.at(i, j) - temp.at(i, j);
574  if ( fabs(difference) > fabs(MaxErr) ) {
575  MaxErr = difference;
576  imax = i;
577  jmax = j;
578  }
579  if ( fabs(numtan.at(i, j) < 1e-15) ) {
580  numtan.at(i, j) = 0.0;
581  }
582  if ( fabs(temp.at(i, j) < 1e-15) ) {
583  temp.at(i, j) = 0.0;
584  }
585  }
586  }
587 
588  printf( "globalNumber: %u, i:%u, j:%u, MaxErr: %e, Numtan=%f, Analytic=%f\n", this->globalNumber, imax, jmax, MaxErr, numtan.at(imax, jmax), temp.at(imax, jmax) );
589 
590  numtan.printYourselfToFile("/tmp/numtan.txt", false);
591  temp.printYourselfToFile("/tmp/analytic.txt", false);
592  if ( fabs(MaxErr) > 1e-5 ) {
593  printf("The error is actually quite large..\n");
594  }
595  }
596 #endif
597  // *******************
598  //computeNumericStiffnessMatrix(answer, rMode, tStep);
599 }
600 
601 void
603 {
604  // Compute displacements used to compute J
605 
606  answer.resize(64);
607  answer.zero();
608 
609  if ( type != ExternalForcesVector ) {
610  answer.resize(0);
611  return;
612  }
613 
614 #ifdef __FM_MODULE
615  FluidDynamicMaterial *mat = static_cast< FluidCrossSection * >( this->giveCrossSection() )->giveFluidMaterial();
616 #endif
617  FloatArray N, gVector, temparray(30), dNv, inc, a, a_prev, u, u_prev, vload;
618  FloatMatrix dNx, G;
619 
620  load->computeComponentArrayAt(gVector, tStep, VM_Total);
621  temparray.zero();
622 
623  vload.resize(4);
624  vload.zero();
625 
626  this->giveUnknownData(a_prev, a, inc, tStep);
629 
630  for ( auto &gp : *this->integrationRulesArray [ 0 ] ) {
631  const FloatArray &lcoords = gp->giveNaturalCoordinates();
632 
633  double detJ = fabs( this->interpolation.giveTransformationJacobian( lcoords, FEIElementGeometryWrapper(this) ) );
634  double dA = detJ * gp->giveWeight();
635 
636  // Body load
637  if ( gVector.giveSize() ) {
638 #ifdef __FM_MODULE
639  double rho = mat->give('d', gp);
640 #else
641  OOFEM_ERROR("Missing FM module");
642  double rho = 1.0;
643 #endif
644 
645  if ( this->nlGeometry ) {
646  FloatArray Fa, temp;
647  FloatMatrix F, Finv, FinvT;
649  F.beMatrixForm(Fa);
650  Finv.beInverseOf(F);
651  FinvT.beTranspositionOf(Finv);
652 
653  dA = dA * F.giveDeterminant();
654 
655  temp.beProductOf(Finv, gVector);
656  gVector = temp;
657  }
658 
659  this->interpolation.evalN( N, lcoords, FEIElementGeometryWrapper(this) );
660 
661  for ( int j = 0; j < N.giveSize(); j++ ) {
662  temparray(3 * j + 0) += N(j) * rho * gVector(0) * dA;
663  temparray(3 * j + 1) += N(j) * rho * gVector(1) * dA;
664  temparray(3 * j + 2) += N(j) * rho * gVector(2) * dA;
665  }
666  }
667 
668  // "load" from previous step
669  this->interpolation.evaldNdx( dNx, gp->giveNaturalCoordinates(), FEIElementGeometryWrapper(this) );
670  this->interpolation_lin.evalN( N, gp->giveNaturalCoordinates(), FEIElementGeometryWrapper(this) );
671 
672  dNv.resize(30);
673  for ( int k = 0; k < dNx.giveNumberOfRows(); k++ ) {
674  dNv.at(k * 3 + 1) = dNx.at(k + 1, 1);
675  dNv.at(k * 3 + 2) = dNx.at(k + 1, 2);
676  dNv.at(k * 3 + 3) = dNx.at(k + 1, 3);
677  }
678 
679  G.plusDyadUnsym(N, dNv, dA);
680  FloatMatrix GT;
681  GT.beTranspositionOf(G);
682 
683  vload.plusProduct(GT, u_prev, -0.0);
684  //vload.printYourself();
685  }
686 
687  if ( this->computeItransform ) {
689  }
690 
691  FloatArray temp;
692 
693  temp.resize(64);
694  temp.zero();
695  temp.assemble(temparray, this->ghostdisplacement_ordering);
696  temp.assemble(vload, this->conservation_ordering);
697 
698  answer.beProductOf(Itransform, temp);
699 }
700 
701 void
702 tet21ghostsolid :: giveInternalForcesVector(FloatArray &answer, TimeStep *tStep, int useUpdatedGpRecord)
703 {
704  FloatArray a;
705  this->computeVectorOf(VM_Total, tStep, a);
706  giveInternalForcesVectorGivenSolution(answer, tStep, useUpdatedGpRecord, a);
707 }
708 
709 void
711 {
712 #ifdef __FM_MODULE
713  FluidDynamicMaterial *fluidMaterial = static_cast< FluidCrossSection * >( this->giveCrossSection() )->giveFluidMaterial();
714 #endif
715 
716  FloatMatrix Kf, G, Kx, B, Ed, dNx;
717  FloatArray Strain, Stress, Nlin, dNv, a_inc, a_prev, aVelocity, aPressure, aGhostDisplacement, aIncGhostDisplacement, fluidStress, epsf, dpdivv;
718  FloatArray momentum, conservation, auxstress, divv;
719  double pressure, epsvol = 0.0;
720 
721  if ( !tStep->isTheFirstStep() ) {
722  this->computeVectorOf(VM_Total, tStep->givePreviousStep(), a_prev);
723  } else {
724  a_prev.resize( a.giveSize() );
725  a_prev.zero();
726  }
727  a_inc.operator = ( a - a_prev );
728 
729  aVelocity.beSubArrayOf(a, momentum_ordering);
730  aPressure.beSubArrayOf(a, conservation_ordering);
731  aGhostDisplacement.beSubArrayOf(a, ghostdisplacement_ordering);
732  aIncGhostDisplacement.beSubArrayOf(a_inc, ghostdisplacement_ordering);
733 
734  FloatArray aTotal;
735  aTotal.operator = ( aVelocity + aIncGhostDisplacement * VELOCITYCOEFF ); // Assume deltaT=1 gives that the increment is the velocity
736 
737  for ( auto &gp : *this->giveDefaultIntegrationRulePtr() ) {
738  const FloatArray &lcoords = gp->giveNaturalCoordinates();
739  double detJ = fabs( ( this->interpolation.giveTransformationJacobian( lcoords, FEIElementGeometryWrapper(this) ) ) );
740  double weight = gp->giveWeight();
741 
742  this->interpolation.evaldNdx( dNx, lcoords, FEIElementGeometryWrapper(this) );
743  this->interpolation_lin.evalN( Nlin, lcoords, FEIElementGeometryWrapper(this) );
744 
745  dNv.resize(30);
746  for ( int k = 0; k < dNx.giveNumberOfRows(); k++ ) {
747  dNv.at(k * 3 + 1) = dNx.at(k + 1, 1);
748  dNv.at(k * 3 + 2) = dNx.at(k + 1, 2);
749  dNv.at(k * 3 + 3) = dNx.at(k + 1, 3);
750  }
751 
752  pressure = Nlin.dotProduct(aPressure);
753 
754  if ( nlGeometry == 0 ) {
755  this->computeBmatrixAt(gp, B);
756 
757  epsf.beProductOf(B, aTotal);
758 
759  // Momentum equation
760  gp->setMaterialMode(_3dFlow);
761 #ifdef __FM_MODULE
762  fluidMaterial->computeDeviatoricStressVector(fluidStress, epsvol, gp, epsf, pressure, tStep);
763 #else
764  OOFEM_ERROR("Missing FM module");
765 #endif
766  gp->setMaterialMode(_3dMat);
767 
768  momentum.plusProduct(B, fluidStress, detJ * weight);
769  momentum.add(-pressure * detJ * weight, dNv);
770 
771  // Conservation equation
772  divv.beTProductOf(dNv, aTotal);
773  divv.times(-detJ * weight);
774 
775  conservation.add(divv.at(1), Nlin);
776 
777  // Ghost solid part
778  Strain.beProductOf(B, aGhostDisplacement);
779  Stress.beProductOf(Dghost, Strain);
780  auxstress.plusProduct(B, Stress, detJ * weight);
781  } else {
782  FloatMatrix BH;
783 
784  this->computeBHmatrixAt(gp, BH);
785  this->computeBmatrixAt(gp, B);
786 
787  // Compute deformation gradient etc.
788  FloatArray Fa, FinvTa;
789  FloatMatrix F, Finv, FinvT, fluidStressMatrix;
790 
791  computeDeformationGradientVectorFromDispl(Fa, gp, tStep, aGhostDisplacement);
792  F.beMatrixForm(Fa);
793  double J = F.giveDeterminant();
794 
795  Finv.beInverseOf(F);
796  FinvT.beTranspositionOf(Finv);
797  FinvTa.beVectorForm(FinvT);
798 
799  epsf.beProductOf(B, aTotal);
800 
801  // Momentum equation --------------------------------------------------
802 
803  // Compute fluid cauchy stress
804  FloatArray fluidCauchyArray;
805  FloatMatrix fluidCauchyMatrix;
806 
807  gp->setMaterialMode(_3dFlow);
808 #ifdef __FM_MODULE
809  fluidMaterial->computeDeviatoricStressVector(fluidCauchyArray, epsvol, gp, epsf, pressure, tStep);
810 #else
811  OOFEM_ERROR("Missing FM module");
812 #endif
813  gp->setMaterialMode(_3dMat);
814 
815  // Transform to 1st Piola-Kirshhoff
816  fluidCauchyMatrix.beMatrixFormOfStress(fluidCauchyArray);
817  fluidStressMatrix.beProductOf(fluidCauchyMatrix, FinvT);
818  fluidStress.beVectorForm(fluidStressMatrix);
819 
820  // Add to equation
821  momentum.plusProduct(BH, fluidStress, detJ * J * weight);
822 
823  // Pressure term in momentum equation
824  FloatArray ptemp;
825  ptemp.beTProductOf(BH, FinvTa);
826 
827  momentum.add(-pressure * detJ * weight * J, ptemp);
828 
829  // Conservation equation ---------------------------------------------
830  FloatArray BvaTotal;
831  double FinvTaBvaTotal;
832 
833  BvaTotal.beProductOf(BH, aTotal);
834  FinvTaBvaTotal = FinvTa.dotProduct(BvaTotal);
835  conservation.add(-J * detJ * weight * FinvTaBvaTotal, Nlin);
836 
837  // Ghost solid part --------------------------------------------------
838  Strain.beProductOf(B, aGhostDisplacement);
839  Stress.beProductOf(Dghost, Strain);
840  auxstress.plusProduct(B, Stress, detJ * weight);
841  }
842  }
843  answer.resize(64);
844  answer.zero();
845 
846  FloatArray temp;
847 
848  temp.resize(64);
849  temp.zero();
850 
851  temp.assemble(momentum, ghostdisplacement_ordering);
852  temp.assemble(conservation, conservation_ordering);
853  temp.assemble(auxstress, momentum_ordering);
854 
855  if ( this->computeItransform ) {
857  }
858 
859  answer.beProductOf(Itransform, temp);
860 }
861 
862 void
863 tet21ghostsolid :: giveInternalForcesVectorGivenSolutionDebug(FloatArray &answer, TimeStep *tStep, int useUpdatedGpRecord, FloatArray &a, bool ExtraLogging)
864 {
865 #ifdef __FM_MODULE
866  FluidDynamicMaterial *fluidMaterial = static_cast< FluidCrossSection * >( this->giveCrossSection() )->giveFluidMaterial();
867 #endif
868 
869  FloatMatrix Kf, G, Kx, B, Ed, dNx;
870  FloatArray Strain, Stress, Nlin, dNv, a_inc, a_prev, aVelocity, aPressure, aGhostDisplacement, aIncGhostDisplacement, fluidStress, epsf, dpdivv;
871  FloatArray momentum, conservation, auxstress, divv;
872  double pressure, epsvol = 0.0;
873 
874  if ( !tStep->isTheFirstStep() ) {
875  this->computeVectorOf(VM_Total, tStep->givePreviousStep(), a_prev);
876  } else {
877  a_prev.resize( a.giveSize() );
878  a_prev.zero();
879  }
880  a_inc.operator = ( a - a_prev );
881 
882  aVelocity.beSubArrayOf(a, momentum_ordering);
883  aPressure.beSubArrayOf(a, conservation_ordering);
884  aGhostDisplacement.beSubArrayOf(a, ghostdisplacement_ordering);
885  aIncGhostDisplacement.beSubArrayOf(a_inc, ghostdisplacement_ordering);
886 
887  FloatArray aTotal;
888  aTotal.operator = ( aVelocity + aIncGhostDisplacement * VELOCITYCOEFF ); // Assume deltaT=1 gives that the increment is the velocity
889 
890  for ( auto &gp : *this->giveDefaultIntegrationRulePtr() ) {
891  // gp = this->giveDefaultIntegrationRulePtr()->getIntegrationPoint(0);
892  const FloatArray &lcoords = gp->giveNaturalCoordinates();
893  double detJ = fabs( ( this->interpolation.giveTransformationJacobian( lcoords, FEIElementGeometryWrapper(this) ) ) );
894  double weight = gp->giveWeight();
895 
896  this->interpolation.evaldNdx( dNx, lcoords, FEIElementGeometryWrapper(this) );
897  this->interpolation_lin.evalN( Nlin, lcoords, FEIElementGeometryWrapper(this) );
898 
899  dNv.resize(30);
900  for ( int k = 0; k < dNx.giveNumberOfRows(); k++ ) {
901  dNv.at(k * 3 + 1) = dNx.at(k + 1, 1);
902  dNv.at(k * 3 + 2) = dNx.at(k + 1, 2);
903  dNv.at(k * 3 + 3) = dNx.at(k + 1, 3);
904  }
905 
906  pressure = Nlin.dotProduct(aPressure);
907 #if FIXEDpressure == 1
908  pressure = 1.0;
909 #endif
910 
911  if ( nlGeometry == 0 ) {
912  this->computeBmatrixAt(gp, B);
913 
914  epsf.beProductOf(B, aTotal);
915 
916  // Momentum equation
917  gp->setMaterialMode(_3dFlow);
918 #ifdef __FM_MODULE
919  fluidMaterial->computeDeviatoricStressVector(fluidStress, epsvol, gp, epsf, pressure, tStep);
920 #else
921  OOFEM_ERROR("Missing FM module");
922 #endif
923  gp->setMaterialMode(_3dMat);
924 
925  momentum.plusProduct(B, fluidStress, detJ * weight);
926  momentum.add(-pressure * detJ * weight, dNv);
927 
928  // Conservation equation
929  divv.beTProductOf(dNv, aTotal);
930  divv.times(-detJ * weight);
931 
932  conservation.add(divv.at(1), Nlin);
933 
934  // Ghost solid part
935  Strain.beProductOf(B, aGhostDisplacement);
936  Stress.beProductOf(Dghost, Strain);
937  auxstress.plusProduct(B, Stress, detJ * weight);
938  } else {
939  FloatMatrix BH;
940 
941  this->computeBHmatrixAt(gp, BH);
942  this->computeBmatrixAt(gp, B);
943 
944  // Compute deformation gradient etc.
945  FloatArray Fa, FinvTa;
946  FloatMatrix F, Finv, FinvT, fluidStressMatrix;
947 
948  computeDeformationGradientVectorFromDispl(Fa, gp, tStep, aGhostDisplacement);
949  F.beMatrixForm(Fa);
950  double J = F.giveDeterminant();
951 #if FIXEDJ == 1
952  J = 1;
953 #endif
954 
955 #if FIXEDFinvT == 1
956  FloatArray aTrue, dispTrue;
957  this->computeVectorOf(VM_Total, tStep, aTrue);
958  dispTrue.beSubArrayOf(aTrue, ghostdisplacement_ordering);
959  computeDeformationGradientVectorFromDispl(Fa, gp, tStep, dispTrue);
960  F.beMatrixForm(Fa);
961 #endif
962 
963  Finv.beInverseOf(F);
964  FinvT.beTranspositionOf(Finv);
965  FinvTa.beVectorForm(FinvT);
966 
967  epsf.beProductOf(B, aTotal);
968 
969  // Momentum equation --------------------------------------------------
970 
971  // Compute fluid cauchy stress
972  FloatArray fluidCauchy;
973  FloatMatrix fluidCauchyMatrix;
974 
975  gp->setMaterialMode(_3dFlow);
976 #ifdef __FM_MODULE
977  fluidMaterial->computeDeviatoricStressVector(fluidCauchy, epsvol, gp, epsf, pressure, tStep);
978 #else
979  OOFEM_ERROR("Missing FM module");
980 #endif
981  gp->setMaterialMode(_3dMat);
982 
983  // Transform to 1st Piola-Kirshhoff
984  fluidCauchyMatrix.beMatrixFormOfStress(fluidCauchy);
985  fluidStressMatrix.beProductOf(fluidCauchyMatrix, FinvT);
986  fluidStress.beVectorForm(fluidStressMatrix);
987 
988  /* if ( (this->globalNumber==292) && (ExtraLogging)) {
989  * std :: cout << "gp@" << gp << " ";
990  * F.printYourself("F in NUMERIC");
991  * epsf.printYourself("epsf in NUMERIC");
992  * fluidCauchy.printYourself("fluidCauchy in NUMERIC");
993  * } */
994 
995  // Add to equation
996  momentum.plusProduct(BH, fluidStress, detJ * J * weight);
997 
998  // Pressure term in momentum equation
999  FloatArray ptemp;
1000  ptemp.beTProductOf(BH, FinvTa);
1001  momentum.add(-pressure * detJ * weight * J, ptemp);
1002 
1003  // Conservation equation ---------------------------------------------
1004  FloatArray BvaTotal;
1005  double FinvTaBvaTotal;
1006 
1007  BvaTotal.beProductOf(BH, aTotal);
1008  FinvTaBvaTotal = FinvTa.dotProduct(BvaTotal);
1009  conservation.add(-J * detJ * weight * FinvTaBvaTotal, Nlin);
1010 
1011  // Ghost solid part --------------------------------------------------
1012  Strain.beProductOf(B, aGhostDisplacement);
1013  Stress.beProductOf(Dghost, Strain);
1014  auxstress.plusProduct(B, Stress, detJ * weight);
1015  }
1016  }
1017  answer.resize(64);
1018  answer.zero();
1019 
1020  FloatArray temp;
1021 
1022  temp.resize(64);
1023  temp.zero();
1024 
1025  temp.assemble(momentum, ghostdisplacement_ordering);
1026  temp.assemble(conservation, conservation_ordering);
1027  temp.assemble(auxstress, momentum_ordering);
1028 
1029  if ( this->computeItransform ) {
1031  }
1032 
1033  answer.beProductOf(Itransform, temp);
1034 } // **************** DEBUG
1035 
1036 void
1038 {
1039  // Returns the mask for node number inode of this element.
1040 
1041  if ( inode <= 4 ) {
1042  answer = {
1043  V_u, V_v, V_w, D_u, D_v, D_w, P_f
1044  };
1045  } else {
1046  answer = {
1047  V_u, V_v, V_w, D_u, D_v, D_w
1048  };
1049  }
1050 }
1051 
1052 void
1054 // Returns the [6x30] strain-displacement matrix {B} of the receiver, eva-
1055 // luated at gp.
1056 // B matrix - 6 rows : epsilon-X, epsilon-Y, epsilon-Z, gamma-YZ, gamma-ZX, gamma-XY :
1057 {
1058  FloatMatrix dnx;
1059 
1061 
1062  answer.resize(6, 30);
1063  answer.zero();
1064 
1065  for ( int i = 1; i <= 10; i++ ) {
1066  answer.at(1, 3 * i - 2) = dnx.at(i, 1);
1067  answer.at(2, 3 * i - 1) = dnx.at(i, 2);
1068  answer.at(3, 3 * i - 0) = dnx.at(i, 3);
1069 
1070  answer.at(4, 3 * i - 1) = dnx.at(i, 3);
1071  answer.at(4, 3 * i - 0) = dnx.at(i, 2);
1072 
1073  answer.at(5, 3 * i - 2) = dnx.at(i, 3);
1074  answer.at(5, 3 * i - 0) = dnx.at(i, 1);
1075 
1076  answer.at(6, 3 * i - 2) = dnx.at(i, 2);
1077  answer.at(6, 3 * i - 1) = dnx.at(i, 1);
1078  }
1079 }
1080 
1081 void
1083 {
1084  FloatArray F, u;
1085  FloatMatrix dNdx, BH, Fmatrix, Finv;
1087 
1088  // Fetch displacements
1089  this->computeVectorOf({ 1, 2, 3 }, VM_Total, tStep, u);
1090 
1091  // Compute dNdx in point
1092  interpolation->evaldNdx( dNdx, lcoord, FEIElementGeometryWrapper(this) );
1093 
1094  // Compute displacement gradient BH
1095  BH.resize(9, dNdx.giveNumberOfRows() * 3);
1096  BH.zero();
1097 
1098  for ( int i = 1; i <= dNdx.giveNumberOfRows(); i++ ) {
1099  BH.at(1, 3 * i - 2) = dNdx.at(i, 1); // du/dx
1100  BH.at(2, 3 * i - 1) = dNdx.at(i, 2); // dv/dy
1101  BH.at(3, 3 * i - 0) = dNdx.at(i, 3); // dw/dz
1102  BH.at(4, 3 * i - 1) = dNdx.at(i, 3); // dv/dz
1103  BH.at(7, 3 * i - 0) = dNdx.at(i, 2); // dw/dy
1104  BH.at(5, 3 * i - 2) = dNdx.at(i, 3); // du/dz
1105  BH.at(8, 3 * i - 0) = dNdx.at(i, 1); // dw/dx
1106  BH.at(6, 3 * i - 2) = dNdx.at(i, 2); // du/dy
1107  BH.at(9, 3 * i - 1) = dNdx.at(i, 1); // dv/dx
1108  }
1109 
1110  // Finally, compute deformation gradient F=BH*u+I
1111  F.beProductOf(BH, u);
1112  F.at(1) += 1.0;
1113  F.at(2) += 1.0;
1114  F.at(3) += 1.0;
1115 
1116  answer = F;
1117 }
1118 
1119 void
1121 {
1122  FloatMatrix dnx;
1123 
1125 
1126  answer.resize(9, 30);
1127  answer.zero();
1128 
1129  for ( int i = 1; i <= dnx.giveNumberOfRows(); i++ ) {
1130  answer.at(1, 3 * i - 2) = dnx.at(i, 1); // du/dx
1131  answer.at(2, 3 * i - 1) = dnx.at(i, 2); // dv/dy
1132  answer.at(3, 3 * i - 0) = dnx.at(i, 3); // dw/dz
1133  answer.at(4, 3 * i - 1) = dnx.at(i, 3); // dv/dz
1134  answer.at(7, 3 * i - 0) = dnx.at(i, 2); // dw/dy
1135  answer.at(5, 3 * i - 2) = dnx.at(i, 3); // du/dz
1136  answer.at(8, 3 * i - 0) = dnx.at(i, 1); // dw/dx
1137  answer.at(6, 3 * i - 2) = dnx.at(i, 2); // du/dy
1138  answer.at(9, 3 * i - 1) = dnx.at(i, 1); // dv/dx
1139  }
1140 }
1141 
1142 void
1144 {
1145  this->computeVectorOf(VM_Total, tStep, u);
1146 
1147  if ( !tStep->isTheFirstStep() ) {
1148  this->computeVectorOf(VM_Total, tStep->givePreviousStep(), u_prev);
1149  this->computeVectorOf(VM_Incremental, tStep, inc);
1150  } else {
1151  inc.resize( u.giveSize() );
1152  inc.zero();
1153  u_prev.operator = ( inc );
1154  }
1155 }
1156 
1157 void
1159 {
1160  // Computes the deformation gradient in the Voigt format at the Gauss point gp of
1161  // the receiver at time step tStep.
1162  // Order of components: 11, 22, 33, 23, 13, 12, 32, 31, 21 in the 3D.
1163 
1164  // Obtain the current displacement vector of the element and subtract initial displacements (if present)
1165  if ( initialDisplacements ) {
1167  }
1168 
1169  // Displacement gradient H = du/dX
1170  FloatMatrix BH;
1171  this->computeBHmatrixAt(gp, BH);
1172  answer.beProductOf(BH, u);
1173 
1174  // Deformation gradient F = H + I
1175  MaterialMode matMode = gp->giveMaterialMode();
1176  if ( matMode == _3dMat || matMode == _PlaneStrain ) {
1177  answer.at(1) += 1.0;
1178  answer.at(2) += 1.0;
1179  answer.at(3) += 1.0;
1180  } else if ( matMode == _PlaneStress ) {
1181  answer.at(1) += 1.0;
1182  answer.at(2) += 1.0;
1183  } else if ( matMode == _1dMat ) {
1184  answer.at(1) += 1.0;
1185  } else {
1186  OOFEM_ERROR( "MaterialMode is not supported yet (%s)", __MaterialModeToString(matMode) );
1187  }
1188 }
1189 
1190 void
1192 {
1193  FloatArray u;
1194  this->computeVectorOf({ 1, 2, 3 }, VM_Total, tStep, u);
1195  computeDeformationGradientVectorFromDispl(answer, gp, tStep, u);
1196 }
1197 
1198 double
1200 // Returns the portion of the receiver which is attached to gp.
1201 {
1202  double determinant = fabs( this->interpolation.giveTransformationJacobian( gp->giveNaturalCoordinates(), FEIElementGeometryWrapper(this) ) );
1203  double weight = gp->giveWeight();
1204  return ( this->computeVolume() );
1205 
1206  return ( determinant * weight );
1207 }
1208 
1209 
1210 int
1212 {
1213  if ( type == IST_Velocity ) {
1214  FloatArray N, a;
1215  FloatMatrix Nmat;
1216 
1217  this->computeVectorOf({ V_u, V_v, V_w }, VM_Total, tStep, a);
1219 
1220  Nmat.resize(3, N.giveSize() * 3);
1221  for ( int i = 1; i <= N.giveSize(); i++ ) {
1222  Nmat.at(1, 3 * i - 2) = N.at(i);
1223  Nmat.at(2, 3 * i - 1) = N.at(i);
1224  Nmat.at(3, 3 * i - 0) = N.at(i);
1225  }
1226 
1227  answer.beProductOf(Nmat, a);
1228  return 1;
1229  } else if ( type == IST_Pressure ) {
1230  FloatArray N, a;
1231 
1232  this->computeVectorOf({ P_f }, VM_Total, tStep, a);
1234 
1235  answer.resize(1);
1236  answer.at(1) = N.dotProduct(a);
1237  return 1;
1238  } else {
1239  MaterialMode matmode = gp->giveMaterialMode();
1240  gp->setMaterialMode(_3dFlow);
1241  int r = StructuralElement :: giveIPValue(answer, gp, type, tStep);
1242  gp->setMaterialMode(matmode);
1243  return r;
1244  }
1245 }
1246 
1247 bool
1249 {
1250  // Create a transformation matrix that switch all rows/equations located in OmegaF but not on GammaInt, i.e where we do not have a no slip condition
1251 
1252  Itransform.resize(64, 64);
1253  Itransform.zero();
1254 
1255 #if USEUNCOUPLED == 0
1257  return 0;
1258 
1259 #endif
1260 
1261  int m = 1;
1262 
1263  int row1, row2;
1264  IntArray row1List, row2List;
1265 
1266  for ( int i = 1; i <= this->giveNumberOfDofManagers(); i++ ) {
1267  IntArray DofIDs;
1268  int firstIndex = m;
1269  this->giveDofManDofIDMask(i, DofIDs);
1270  // DofIDs.printYourself();
1271 
1272  for ( int j = 1; j <= DofIDs.giveSize(); j++ ) {
1273  row1 = m;
1274  row2 = m;
1275 
1276  if ( DofIDs.at(j) == V_u || DofIDs.at(j) == V_v || DofIDs.at(j) == V_w ) {
1277  bool doSwitch = !this->giveDofManager(i)->giveDofWithID( DofIDs.at(j) )->hasBc(tStep);
1278 
1279  if ( doSwitch ) { // Boundary condition not set, make switch
1280  row1 = m;
1281 
1282  for ( int n = 1; n <= DofIDs.giveSize(); n++ ) {
1283  if ( ( DofIDs.at(j) == V_u && DofIDs.at(n) == D_u ) ||
1284  ( DofIDs.at(j) == V_v && DofIDs.at(n) == D_v ) ||
1285  ( DofIDs.at(j) == V_w && DofIDs.at(n) == D_w ) ) {
1286  row2 = firstIndex + n - 1;
1287  }
1288  }
1289  row1List.resizeWithValues(row1List.giveSize() + 1);
1290  row1List.at( row1List.giveSize() ) = row1;
1291  row2List.resizeWithValues(row2List.giveSize() + 1);
1292  row2List.at( row2List.giveSize() ) = row2;
1293  }
1294  }
1295  m++;
1296  }
1297  }
1298 
1299  // Create identity matrix
1301 
1302  // Create tranformation matrix by switching rows
1303  for ( int i = 1; i <= row1List.giveSize(); i++ ) {
1304  Itransform.at( row1List.at(i), row1List.at(i) ) = 0;
1305  Itransform.at( row2List.at(i), row2List.at(i) ) = 0;
1306 
1307  Itransform.at( row1List.at(i), row2List.at(i) ) = 1;
1308  Itransform.at( row2List.at(i), row1List.at(i) ) = 1;
1309  }
1310 
1311  computeItransform = false;
1312 
1313  return 0;
1314 }
1315 
1316 // Some extension Interfaces to follow:
1317 
1319 {
1320  switch ( it ) {
1322  return static_cast< NodalAveragingRecoveryModelInterface * >(this);
1323 
1325  return static_cast< SpatialLocalizerInterface * >(this);
1326 
1328  return static_cast< EIPrimaryUnknownMapperInterface * >(this);
1329 
1330  default:
1332  //return FMElement :: giveInterface(it);
1333  }
1334 }
1335 
1337  TimeStep *tStep, const FloatArray &lcoords, FloatArray &answer)
1338 {
1339  FloatArray n, n_lin;
1340  this->interpolation.evalN( n, lcoords, FEIElementGeometryWrapper(this) );
1341  this->interpolation_lin.evalN( n_lin, lcoords, FEIElementGeometryWrapper(this) );
1342  answer.resize(4);
1343  answer.zero();
1344  for ( int i = 1; i <= n.giveSize(); i++ ) {
1345  answer(0) += n.at(i) * this->giveNode(i)->giveDofWithID(V_u)->giveUnknown(mode, tStep);
1346  answer(1) += n.at(i) * this->giveNode(i)->giveDofWithID(V_v)->giveUnknown(mode, tStep);
1347  answer(2) += n.at(i) * this->giveNode(i)->giveDofWithID(V_w)->giveUnknown(mode, tStep);
1348  }
1349 
1350  for ( int i = 1; i <= n_lin.giveSize(); i++ ) {
1351  answer(3) += n_lin.at(i) * this->giveNode(i)->giveDofWithID(P_f)->giveUnknown(mode, tStep);
1352  }
1353 }
1354 
1355 void
1357 {
1358  if ( type == IST_Pressure ) {
1359  answer.resize(1);
1360  if ( node <= 4 ) {
1361  answer.at(1) = this->giveNode(node)->giveDofWithID(P_f)->giveUnknown(VM_Total, tStep);
1362  } else {
1363  IntArray eNodes;
1364  this->interpolation.computeLocalEdgeMapping(eNodes, node - 4);
1365  answer.at(1) = 0.5 * (
1366  this->giveNode( eNodes.at(1) )->giveDofWithID(P_f)->giveUnknown(VM_Total, tStep) +
1367  this->giveNode( eNodes.at(2) )->giveDofWithID(P_f)->giveUnknown(VM_Total, tStep) );
1368  }
1369  } else {
1370  answer.clear();
1371  }
1372 }
1373 
1374 void
1376 {
1377  answer.clear();
1378  if ( type != ExternalForcesVector ) {
1379  return;
1380  }
1381 
1382  FEInterpolation *fei = this->giveInterpolation();
1383  if ( !fei ) {
1384  OOFEM_ERROR("No interpolator available");
1385  }
1386 
1387  FloatArray n_vec, f(18);
1388  FloatMatrix n, T;
1389  FloatArray force;
1390  int nsd = fei->giveNsd();
1391 
1392  f.zero();
1393  IntegrationRule *iRule = fei->giveBoundaryIntegrationRule(load->giveApproxOrder(), boundary);
1394 
1395  for ( GaussPoint *gp : *iRule ) {
1396  FloatArray lcoords = gp->giveNaturalCoordinates();
1397  if ( load->giveFormulationType() == Load :: FT_Entity ) {
1398  load->computeValueAt(force, tStep, lcoords, mode);
1399  } else {
1400  FloatArray gcoords, elcoords;
1401  this->interpolation.surfaceLocal2global( gcoords, boundary, lcoords, FEIElementGeometryWrapper(this) );
1402  this->interpolation.global2local( elcoords, gcoords, FEIElementGeometryWrapper(this) );
1403  NeumannMomentLoad *thisLoad = dynamic_cast< NeumannMomentLoad * >(load);
1404  if ( thisLoad != NULL ) {
1405  FloatArray temp;
1406  thisLoad->computeValueAtBoundary(temp, tStep, gcoords, VM_Total, this, boundary);
1407 
1408  FloatArray F;
1409  FloatMatrix Fm, Finv, FinvT;
1410  this->computeDeformationGradientVectorAt(F, elcoords, tStep);
1411  Fm.beMatrixForm(F);
1412  double J = Fm.giveDeterminant();
1413  Finv.beInverseOf(Fm);
1414  FinvT.beTranspositionOf(Finv);
1415  force.beTProductOf(Finv, temp);
1416  force.times(J);
1417  } else {
1418  load->computeValueAt(force, tStep, gcoords, VM_Total);
1419  }
1420  }
1421 
1423  // We always want the global values in the end, so we might as well compute them here directly:
1424  // transform force
1425  if ( load->giveCoordSystMode() == Load :: CST_Global ) {
1426  // then just keep it in global c.s
1427  } else {
1429  // transform from local boundary to element local c.s
1430  /*if ( this->computeLoadLSToLRotationMatrix(T, boundary, gp) ) {
1431  * force.rotatedWith(T, 'n');
1432  * }*/
1433  // then to global c.s
1434  if ( this->computeLoadGToLRotationMtrx(T) ) {
1435  force.rotatedWith(T, 't');
1436  }
1437  }
1438 
1439  // Construct n-matrix
1440  fei->boundaryEvalN( n_vec, boundary, lcoords, FEIElementGeometryWrapper(this) );
1441  n.beNMatrixOf(n_vec, nsd);
1442 
1444  double thickness = 1.0; // Should be the circumference for axisymm-elements.
1445  double dV = thickness * gp->giveWeight() * fei->boundaryGiveTransformationJacobian( boundary, lcoords, FEIElementGeometryWrapper(this) );
1446  f.plusProduct(n, force, dV);
1447  }
1448 
1449  FloatArray temp;
1450  FloatMatrix Itrans;
1451 
1452  answer.resize(39);
1453  answer.zero();
1454  answer.assemble(f, this->velocitydofsonside);
1455 
1456  delete iRule;
1457 }
1458 }
double giveDeterminant() const
Returns the trace (sum of diagonal components) of the receiver.
Definition: floatmatrix.C:1408
CrossSection * giveCrossSection()
Definition: element.C:495
virtual void computeDeformationGradientVector(FloatArray &answer, GaussPoint *gp, TimeStep *tStep)
Computes the deformation gradient in Voigt form at integration point ip and at time step tStep...
InternalStateType
Type representing the physical meaning of element or constitutive model internal variable.
The element interface required by NodalAvergagingRecoveryModel.
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
void subtract(const FloatArray &src)
Subtracts array src to receiver.
Definition: floatarray.C:258
virtual int giveIPValue(FloatArray &answer, GaussPoint *gp, InternalStateType type, TimeStep *tStep)
Returns the integration point corresponding value in full form.
int nlGeometry
Flag indicating if geometrical nonlinearities apply.
Class and object Domain.
Definition: domain.h:115
void computeVectorOf(ValueModeType u, TimeStep *tStep, FloatArray &answer)
Returns local vector of unknowns.
Definition: element.C:86
virtual IntegrationRule * giveDefaultIntegrationRulePtr()
Access method for default integration rule.
Definition: element.h:822
Fluid cross-section.
virtual double giveTransformationJacobian(const FloatArray &lcoords, const FEICellGeometry &cellgeo)
Evaluates the determinant of the transformation.
Definition: feinterpol.C:43
Abstract base class for all fluid materials.
virtual double computeVolume()
Computes the volume.
Definition: element.C:1101
virtual void giveInternalForcesVectorGivenSolutionDebug(FloatArray &answer, TimeStep *tStep, int useUpdatedGpRecord, FloatArray &SolutionVector, bool ExtraLogging)
Abstract base class for "structural" finite elements with geometrical nonlinearities.
virtual bool giveRowTransformationMatrix(TimeStep *tStep)
Load is specified in global c.s.
Definition: load.h:70
std::unique_ptr< FloatArray > initialDisplacements
Initial displacement vector, describes the initial nodal displacements when element has been casted...
virtual void computeStressVector(FloatArray &answer, const FloatArray &strain, GaussPoint *gp, TimeStep *tStep)
Computes the stress vector of receiver at given integration point, at time step tStep.
double & at(int i)
Coefficient access function.
Definition: floatarray.h:131
ValueModeType
Type representing the mode of UnknownType or CharType, or similar types.
Definition: valuemodetype.h:78
Class implementing element body load, acting over whole element volume (e.g., the dead weight)...
Definition: bodyload.h:49
void clear()
Clears receiver (zero size).
Definition: floatarray.h:206
virtual int global2local(FloatArray &answer, const FloatArray &lcoords, const FEICellGeometry &cellgeo)
Evaluates local coordinates from given global ones.
Definition: fei3dtetquad.C:224
virtual double evaldNdx(FloatMatrix &answer, const FloatArray &lcoords, const FEICellGeometry &cellgeo)
Evaluates the matrix of derivatives of interpolation functions (shape functions) at given point...
Definition: fei3dtetquad.C:147
virtual double giveUnknown(ValueModeType mode, TimeStep *tStep)=0
The key method of class Dof.
virtual void computeStiffnessMatrix(FloatMatrix &answer, MatResponseMode rMode, TimeStep *tStep)
Computes the stiffness matrix of receiver.
static IntArray momentum_ordering
Ordering of momentum balance equations in element. Used to assemble the element stiffness.
virtual CoordSystType giveCoordSystMode()
Returns receiver&#39;s coordinate system.
Definition: boundaryload.h:151
void beVectorForm(const FloatMatrix &aMatrix)
Reciever will be a vector with 9 components formed from a 3x3 matrix.
Definition: floatarray.C:992
virtual void computeBmatrixAt(GaussPoint *, FloatMatrix &, int=1, int=ALL_STRAINS)
Computes the geometrical matrix of receiver in given integration point.
virtual void evalN(FloatArray &answer, const FloatArray &lcoords, const FEICellGeometry &cellgeo)
Evaluates the array of interpolation functions (shape functions) at given point.
Definition: fei3dtetlin.C:43
#define VELOCITYCOEFF
virtual void computeComponentArrayAt(FloatArray &answer, TimeStep *tStep, ValueModeType mode)
Computes boundary condition value - its components values at given time.
Definition: load.C:82
virtual void computeDeformationGradientVectorFromDispl(FloatArray &answer, GaussPoint *gp, TimeStep *tStep, FloatArray &u)
void plusDyadUnsym(const FloatArray &a, const FloatArray &b, double dV)
Adds to the receiver the product .
Definition: floatmatrix.C:811
MaterialMode
Type representing material mode of integration point.
Definition: materialmode.h:89
virtual void NodalAveragingRecoveryMI_computeNodalValue(FloatArray &answer, int node, InternalStateType type, TimeStep *tStep)
Computes the element value in given node.
void printYourselfToFile(const std::string filename, const bool showDimensions=true) const
Print matrix to file.
Definition: floatmatrix.C:1477
virtual void computeLocalEdgeMapping(IntArray &edgeNodes, int iedge)
Definition: fei3dtetquad.C:354
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.
virtual int giveNumberOfDofManagers() const
Definition: element.h:656
void rotatedWith(FloatMatrix &r, char mode)
Returns the receiver a rotated according the change-of-base matrix r.
Definition: floatarray.C:799
virtual void computeDeformationGradientVectorAt(FloatArray &answer, FloatArray lcoord, TimeStep *tStep)
Abstract base class representing integration rule.
virtual int giveIPValue(FloatArray &answer, GaussPoint *gp, InternalStateType type, TimeStep *tStep)
Returns the integration point corresponding value in full form.
virtual void computeBHmatrixAt(GaussPoint *, FloatMatrix &)
Computes a matrix which, multiplied by the column matrix of nodal displacements, gives the displaceme...
bool isTheFirstStep()
Check if receiver is first step.
Definition: timestep.C:134
void beMatrixForm(const FloatArray &aArray)
Definition: floatmatrix.C:1657
Class representing a general abstraction for finite element interpolation class.
Definition: feinterpol.h:132
const char * __MaterialModeToString(MaterialMode _value)
Definition: cltypes.C:314
virtual double give(int aProperty, GaussPoint *gp)
Returns the value of material property &#39;aProperty&#39;.
Definition: material.C:52
virtual void computeLoadVector(FloatArray &answer, BodyLoad *load, CharType type, ValueModeType mode, TimeStep *tStep)
Computes the contribution of the given body load (volumetric).
virtual void computeDeviatoricStressVector(FloatArray &stress_dev, double &epsp_vol, GaussPoint *gp, const FloatArray &eps, double pressure, TimeStep *tStep)
Computes the deviatoric stress vector and volumetric strain rate from given deviatoric strain and pre...
Abstract base class representing a boundary load (force, momentum, ...) that acts directly on a bound...
Definition: boundaryload.h:110
#define E(p)
Definition: mdm.C:368
int giveNumber()
Returns receiver&#39;s number.
Definition: timestep.h:129
int globalNumber
In parallel mode, globalNumber contains globally unique DoFManager number.
Definition: element.h:183
double dotProduct(const FloatArray &x) const
Computes the dot product (or inner product) of receiver and argument.
Definition: floatarray.C:463
#define OOFEM_ERROR(...)
Definition: error.h:61
virtual void evalN(FloatArray &answer, const FloatArray &lcoords, const FEICellGeometry &cellgeo)
Evaluates the array of interpolation functions (shape functions) at given point.
Definition: fei3dtetquad.C:125
REGISTER_Element(LSpace)
virtual double computeVolumeAround(GaussPoint *gp)
Returns volume related to given integration point.
DofIDItem
Type representing particular dof type.
Definition: dofiditem.h:86
static IntArray displacementdofsonside
virtual int computeLoadGToLRotationMtrx(FloatMatrix &answer)
Returns transformation matrix from global coordinate system to local element coordinate system for el...
virtual void giveDofManDofIDMask(int inode, IntArray &answer) const
Returns dofmanager dof mask for node.
virtual double giveWeight()
Returns integration weight of receiver.
Definition: gausspoint.h:181
virtual FormulationType giveFormulationType()
Specifies is load should take local or global coordinates.
Definition: load.h:155
StructuralCrossSection * giveStructuralCrossSection()
Helper function which returns the structural cross-section for the element.
void times(double f)
Multiplies receiver by factor f.
Definition: floatmatrix.C:1594
virtual void giveInternalForcesVector(FloatArray &answer, TimeStep *tStep, int useUpdatedGpRecord=0)
Evaluates nodal representation of real internal forces.
Wrapper around element definition to provide FEICellGeometry interface.
Definition: feinterpol.h:95
virtual void computeValueAtBoundary(FloatArray &answer, TimeStep *tStep, const FloatArray &coords, ValueModeType mode, Element *e, int boundary)
void resizeWithValues(int n, int allocChunk=0)
Checks size of receiver towards requested bounds.
Definition: intarray.C:115
void beProductOf(const FloatMatrix &aMatrix, const FloatArray &anArray)
Receiver becomes the result of the product of aMatrix and anArray.
Definition: floatarray.C:676
virtual double boundaryGiveTransformationJacobian(int boundary, const FloatArray &lcoords, const FEICellGeometry &cellgeo)=0
Evaluates the determinant of the transformation Jacobian on the requested boundary.
#define N(p, q)
Definition: mdm.C:367
void plusProductSymmUpper(const FloatMatrix &a, const FloatMatrix &b, double dV)
Adds to the receiver the product .
Definition: floatmatrix.C:698
virtual int giveApproxOrder()=0
TimeStep * givePreviousStep()
Returns pointer to previous solution step.
Definition: timestep.C:114
virtual void EIPrimaryUnknownMI_computePrimaryUnknownVectorAtLocal(ValueModeType u, TimeStep *tStep, const FloatArray &coords, FloatArray &answer)
Computes the element vector of primary unknowns at given point in the local coordinate system...
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
virtual void computeNumericStiffnessMatrix(FloatMatrix &answer, MatResponseMode rMode, TimeStep *tStep)
void giveUnknownData(FloatArray &u_prev, FloatArray &u, FloatArray &inc, TimeStep *tStep)
static IntArray conservation_ordering
Ordering of conservation equations in element. Used to assemble the element stiffness.
virtual int setupIntegrationPoints(IntegrationRule &irule, int npoints, Element *element)
Sets up integration rule for the given element.
Definition: crosssection.C:54
void setMaterialMode(MaterialMode newMode)
Sets material mode of receiver.
Definition: gausspoint.h:193
int numberOfGaussPoints
Number of integration points as specified by nip.
Definition: element.h:188
void beNMatrixOf(const FloatArray &n, int nsd)
Assigns the receiver to be a repeated diagonal matrix.
Definition: floatmatrix.C:505
virtual void giveRealStress_3d(FloatArray &answer, GaussPoint *gp, const FloatArray &reducedStrain, TimeStep *tStep)=0
Class representing vector of real numbers.
Definition: floatarray.h:82
virtual FEInterpolation * giveInterpolation() const
Implementation of matrix containing floating point numbers.
Definition: floatmatrix.h:94
void beMatrixFormOfStress(const FloatArray &aArray)
Reciever will be a 3x3 matrix formed from a vector with either 9 or 6 components. ...
Definition: floatmatrix.C:1774
static IntArray velocitydofsonside
void beSubArrayOf(const FloatArray &src, const IntArray &indx)
Extract sub vector form src array and stores the result into receiver.
Definition: floatarray.C:379
void assemble(const FloatArray &fe, const IntArray &loc)
Assembles the array fe (typically, the load vector of a finite element) into the receiver, using loc as location array.
Definition: floatarray.C:551
CharType
Definition: chartype.h:87
void resize(int rows, int cols)
Checks size of receiver towards requested bounds.
Definition: floatmatrix.C:1358
virtual IntegrationRule * giveBoundaryIntegrationRule(int order, int boundary)
Sets up a suitable integration rule for integrating over the requested boundary.
Definition: feinterpol.C:63
void add(const FloatMatrix &a)
Adds matrix to the receiver.
Definition: floatmatrix.C:1023
Class Interface.
Definition: interface.h:82
Dof * giveDofWithID(int dofID) const
Returns DOF with given dofID; issues error if not present.
Definition: dofmanager.C:119
void zero()
Zeroes all coefficients of receiver.
Definition: floatarray.C:658
void beDyadicProductOf(const FloatArray &vec1, const FloatArray &vec2)
Assigns to the receiver the dyadic product .
Definition: floatmatrix.C:492
void beTProductOf(const FloatMatrix &a, const FloatMatrix &b)
Assigns to the receiver product of .
Definition: floatmatrix.C:367
void setColumn(const FloatArray &src, int c)
Sets the values of the matrix in specified column.
Definition: floatmatrix.C:648
virtual Interface * giveInterface(InterfaceType t)
Interface requesting service.
Definition: femcmpnn.h:179
void times(double s)
Multiplies receiver with scalar.
Definition: floatarray.C:818
static FEI3dTetLin interpolation_lin
void beTranspositionOf(const FloatMatrix &src)
Assigns to the receiver the transposition of parameter.
Definition: floatmatrix.C:323
The spatial localizer element interface associated to spatial localizer.
virtual void surfaceLocal2global(FloatArray &answer, int isurf, const FloatArray &lcoords, const FEICellGeometry &cellgeo)
Evaluates edge global coordinates from given local ones.
Definition: fei3dtetquad.C:413
std::vector< std::unique_ptr< IntegrationRule > > integrationRulesArray
List of integration rules of receiver (each integration rule contains associated integration points a...
Definition: element.h:170
virtual void computeNumericStiffnessMatrixDebug(FloatMatrix &answer, MatResponseMode rMode, TimeStep *tStep)
The element interface class related to Element Interpolation Mappers.
void zero()
Zeroes all coefficient of receiver.
Definition: floatmatrix.C:1326
InterfaceType
Enumerative type, used to identify interface type.
Definition: interfacetype.h:43
void beUnitMatrix()
Sets receiver to unity matrix.
Definition: floatmatrix.C:1332
virtual Interface * giveInterface(InterfaceType it)
Interface requesting service.
void beProductOf(const FloatMatrix &a, const FloatMatrix &b)
Assigns to the receiver product of .
Definition: floatmatrix.C:337
int giveSize() const
Definition: intarray.h:203
int giveSize() const
Returns the size of receiver.
Definition: floatarray.h:218
virtual void giveStiffnessMatrix_3d(FloatMatrix &answer, MatResponseMode mode, GaussPoint *gp, TimeStep *tStep)=0
Method for computing the stiffness matrix.
the oofem namespace is to define a context or scope in which all oofem names are defined.
DofManager * giveDofManager(int i) const
Definition: element.C:514
void assemble(const FloatMatrix &src, const IntArray &loc)
Assembles the contribution using localization array into receiver.
Definition: floatmatrix.C:251
void beInverseOf(const FloatMatrix &src)
Modifies receiver to become inverse of given parameter.
Definition: floatmatrix.C:835
Node * giveNode(int i) const
Returns reference to the i-th node of element.
Definition: element.h:610
virtual void giveInternalForcesVectorGivenSolution(FloatArray &answer, TimeStep *tStep, int useUpdatedGpRecord, FloatArray &SolutionVector)
virtual void computeValueAt(FloatArray &answer, TimeStep *tStep, const FloatArray &coords, ValueModeType mode)
Computes components values of load at given point - global coordinates (coordinates given)...
Definition: boundaryload.C:58
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
static FEI3dTetQuad interpolation
virtual void boundaryEvalN(FloatArray &answer, int boundary, const FloatArray &lcoords, const FEICellGeometry &cellgeo)=0
Evaluates the basis functions on the requested boundary.
Class representing integration point in finite element program.
Definition: gausspoint.h:93
Class representing solution step.
Definition: timestep.h:80
virtual void computeGaussPoints()
Initializes the array of integration rules member variable.
tet21ghostsolid(int n, Domain *d)
virtual int giveNsd()=0
Returns number of spatial dimensions.
int numberOfDofMans
Number of dofmanagers.
Definition: element.h:149
void add(const FloatArray &src)
Adds array src to receiver.
Definition: floatarray.C:156
virtual double evaldNdx(FloatMatrix &answer, const FloatArray &lcoords, const FEICellGeometry &cellgeo)=0
Evaluates the matrix of derivatives of interpolation functions (shape functions) at given point...
const FloatArray & giveNaturalCoordinates()
Returns coordinate array of receiver.
Definition: gausspoint.h:138
Class representing Gaussian-quadrature integration rule.
virtual void computeBoundarySurfaceLoadVector(FloatArray &answer, BoundaryLoad *load, int boundary, CharType type, ValueModeType mode, TimeStep *tStep, bool global=true)
Computes the contribution of the given load at the given boundary surface in global coordinate system...
static IntArray ghostdisplacement_ordering
Ordering of ghost displacements equations.
void resize(int s)
Resizes receiver towards requested size.
Definition: floatarray.C:631
virtual void computeConstitutiveMatrixAt(FloatMatrix &answer, MatResponseMode rMode, GaussPoint *gp, TimeStep *tStep)
Computes constitutive matrix of receiver.
void plusProduct(const FloatMatrix &b, const FloatArray &s, double dV)
Adds the product .
Definition: floatarray.C:226
virtual void giveDeviatoricStiffnessMatrix(FloatMatrix &answer, MatResponseMode mode, GaussPoint *gp, TimeStep *tStep)=0
Computes the deviatoric stiffness; .

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:31 for OOFEM by doxygen 1.8.11 written by Dimitri van Heesch, © 1997-2011