OOFEM  2.4
OOFEM.org - Object Oriented Finite Element Solver
shell7basexfem.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 
38 #include "constantsurfaceload.h"
43 #include "feinterpol3d.h"
44 #include "xfem/enrichmentitem.h"
45 #include "xfem/xfemmanager.h"
46 #include "dofmanager.h"
47 #include "connectivitytable.h"
48 #include "mathfem.h"
49 #include "gausspoint.h"
50 #include "spatiallocalizer.h"
51 
52 namespace oofem {
53 
54 /* Scale factor fo the discontinuous dofs. Implies that the corresponding
55  must be scaled with 1/factor in the input file
56 */
57 const double DISC_DOF_SCALE_FAC = 1.0;
58 
60 {
61 }
62 
64 {
65 
66 }
67 
68 int
70 {
72  return 1;
73 }
74 
75 void
77 {
79  this->xMan = this->giveDomain()->giveXfemManager();
80 
81  // Set up ordering arrays and arrays with the actived dofs
82  int numEI = xMan->giveNumberOfEnrichmentItems();
83  this->orderingArrays.resize(numEI);
84  this->activeDofsArrays.resize(numEI);
85  for ( int i = 1; i <= numEI; i++ ) {
86  EnrichmentItem *ei = this->xMan->giveEnrichmentItem(i);
87  if ( ei->isElementEnriched(this) ) {
88  this->computeOrderingArray( this->orderingArrays[i-1], activeDofsArrays[i-1], ei);
89  }
90  }
91 
92 }
93 
94 
95 
96 void
98 {
99 
100  // Compute necessary quantities for evaluation of failure criterias
102 
103  if ( DamagedNeighborLayeredStatus * status = dynamic_cast< DamagedNeighborLayeredStatus * >(fcStatus) ) {
104  /*
105  Go through the neighbors of the element and check for each layer if the
106  corresponding cz is damaged (if applicable)
107  */
108  IntArray neighbors;
109  IntArray elements(1);
110  ConnectivityTable *conTable = this->giveDomain()->giveConnectivityTable();
111  elements.at(1) = fcStatus->el->giveNumber();
112  conTable->giveElementNeighbourList(neighbors, elements);
113  FloatArray damageArray(this->layeredCS->giveNumberOfLayers() - 1), damageArrayNeigh;
114  fcStatus->quantities.resize( neighbors.giveSize() );
115 
116  for ( int i = 1; i <= neighbors.giveSize(); i++ ) {
117 
118  Shell7BaseXFEM *neighbor =
119  dynamic_cast< Shell7BaseXFEM * > (this->giveDomain()->giveElement( neighbors.at(i) ));
120  if ( neighbor ) {
121  neighbor->giveMaxCZDamages(damageArrayNeigh, tStep); // damage parameter for each interface
122 
123  // store maximum damage from neighbors
124  for ( int j = 1; j <= damageArray.giveSize(); j++ ) {
125  if (damageArrayNeigh.at(j) > damageArray.at(j) ) {
126  damageArray.at(j) = damageArrayNeigh.at(j);
127  }
128  }
129  }
130 
131  }
132 
133 
134  // debugging
135  for ( int j = 1; j <= damageArray.giveSize(); j++ ) {
136  damageArray.at(j) = 1.0;
137  }
138 
139  status->layerDamageValues = damageArray;
140  }
141  //case FC_DamagedNeighborCZ:
142  //std::vector < FloatArray > interLamStresses;
143  //int numInterfaces = this->layeredCS->giveNumberOfLayers() - 1;
144  //IntArray delaminatedInterfaceList;
145  //switch ( fc->giveType() ) {
146  //case FC_MaxShearStress:
147  //
148  // this->computeDelaminatedInterfaceList(delaminatedInterfaceList); ///@todo remove the need for this method - JB
149  //
150  // fc->quantities.resize(numInterfaces); // will overwrite this every time
151  // //fc->elQuantities[ this->giveNumber() - 1 ].
152  // for (int intface = 1; intface <= numInterfaces; intface++ ) {
153  //
154  // if ( ! delaminatedInterfaceList.contains(intface) ) { // interface is whole
155  // this->computeInterLaminarStressesAt(intface, tStep, interLamStresses); // all 6 components in each evaluation point (ip)
156  // int numEvalPoints = interLamStresses.size();
157  // fc->quantities[intface-1].resize(numEvalPoints); // most often = numIP
158  //
159  // for ( int evalPoint = 1; evalPoint <= numEvalPoints; evalPoint++) {
160  // FloatArray &values = fc->quantities[intface-1][evalPoint-1]; // one resulting shear stress
161  // FloatArray &vS = interLamStresses[evalPoint-1]; // Stress in eval point
162  // values.resize(1); // scalar measure in this case
163  // values.at(1) = sqrt( vS.at(2)*vS.at(2) + vS.at(3)*vS.at(3) ); // components can't be right here? shouldn't it be a traction vector?
164  // }
165  // }
166  // }
167  // break;
168 
169 }
170 
171 
172 
173 
174 
176 {
178  OOFEM_ERROR("'czmaterial' this keyword is not in use anymore! Instead define cz material for each interface in the cross secton, ex: interfacematerials 3 x x x ");
179  }
180 
181  return Shell7Base :: initializeFrom(ir);
182 }
183 
184 bool
186 {
187  if ( interfaceNum <= this->layeredCS->giveNumberOfLayers()-1 ) {
188  return this->layeredCS->giveInterfaceMaterialNum(interfaceNum) > 0;
189  } else {
190  return 0;
191  }
192 }
193 
194 Interface
196 {
197  if ( it != XfemElementInterfaceType ) {
198  return Shell7Base :: giveInterface(it);
199  } else if ( it == XfemElementInterfaceType ) {
200  return static_cast< XfemElementInterface * >(this);
201  } else {
202  return Shell7Base :: giveInterface(it);
203  }
204 }
205 
206 
207 void
209 {
210  // Returns the total id mask of the dof manager - regular id's + enriched id's
211 
212  // Continuous part
213  Shell7Base :: giveDofManDofIDMask(inode, answer);
214  XfemManager *xMan = this->giveDomain()->giveXfemManager(); // xman not initialized on el. level when this is first called
215 
216  // Discontinuous part
217  DofManager *dMan = this->giveDofManager(inode);
218  for ( int i = 1; i <= xMan->giveNumberOfEnrichmentItems(); i++ ) {
219  EnrichmentItem *ei = xMan->giveEnrichmentItem(i);
220  if ( ei->isDofManEnriched(*dMan) ) {
221  IntArray eiDofIdArray;
222  ei->giveEIDofIdArray(eiDofIdArray);
223  answer.followedBy(eiDofIdArray);
224  }
225  }
226 }
227 
228 
229 void
231 {
232  // Continuous part g_c
233  Shell7Base :: evalCovarBaseVectorsAt(lCoords, gcov, genEpsC, tStep);
234 
235  // Discontinuous part g_d
236  FloatArray dGenEps;
237  FloatMatrix gcovd;
238  std :: vector< double > ef;
239  for ( int i = 1; i <= this->xMan->giveNumberOfEnrichmentItems(); i++ ) {
240  EnrichmentItem *ei = this->xMan->giveEnrichmentItem(i);
241 
242  if ( ei->isElementEnriched(this) ) {
243  computeDiscGeneralizedStrainVector(dGenEps, lCoords, ei, tStep);
244  Shell7Base :: evalCovarBaseVectorsAt(lCoords, gcovd, dGenEps, tStep);
245  gcov.add(gcovd);
246  }
247  }
248 }
249 
250 
251 void
253 {
254  FloatArray solVecD;
255  IntArray eiDofIdArray;
256  ei->giveEIDofIdArray(eiDofIdArray);
257  this->computeDiscSolutionVector(eiDofIdArray, tStep, solVecD);
258  FloatMatrix B;
259  this->computeEnrichedBmatrixAt(lCoords, B, ei);
260  answer.beProductOf(B, solVecD);
261 }
262 
263 
264 void
266 {
267  FloatArray temp;
268  IntArray newIdArray = dofIdArray;
269  newIdArray.followedBy(0); // Extend it by one such that the length is 7 -> answer = size 42 for 6 noded triangle
270  this->computeVectorOf(newIdArray, VM_Total, tStep, temp, true);
271  answer.resize(temp.giveSize());
272  answer.zero();
273  answer.assemble( temp, this->giveOrderingNodes() );
274 
275 }
276 
277 void
279 {
280 
281  FloatArray temp;
282  lCoords.at(3) += 1.0e-9; // bottom position for plus side + num. perturbation
283  this->vtkEvalUpdatedGlobalCoordinateAt(lCoords, interf + 1, answer, tStep); // position vector at + side
284  lCoords.at(3) -= 2.0e-9; // top position for minus side - num. perturbation
285  this->vtkEvalUpdatedGlobalCoordinateAt(lCoords, interf, temp, tStep); // position vector at - side
286  answer.subtract(temp); // jump = x(+) - x(-)
287 
288 }
289 
290 int
292 {
293  // Continuous part
294  int nDofs = Shell7Base :: giveNumberOfDofs();
295 
296  // Discontinuous part
297  for ( int i = 1; i <= this->giveNumberOfDofManagers(); i++ ) {
298  DofManager *dMan = this->giveDofManager(i);
299  for ( int j = 1; j <= this->xMan->giveNumberOfEnrichmentItems(); j++ ) {
300  EnrichmentItem *ei = this->xMan->giveEnrichmentItem(j);
301  if ( ei->isDofManEnriched(*dMan) ) {
302  IntArray eiDofIdArray;
303  ei->giveEIDofIdArray(eiDofIdArray);
304  nDofs += eiDofIdArray.giveSize();
305  }
306  }
307  }
308  return nDofs;
309 }
310 
311 
312 void
314 {
315  Shell7Base :: edgeGiveUpdatedSolutionVector(answer, iedge, tStep);
316  answer.times(DISC_DOF_SCALE_FAC);
317 }
318 
319 
320 void
322 {
323  // Routine to extract vector given an array of dofid items
324  // If a certain dofId does not exist a zero is used as value
325 
326  const IntArray &ordering_cont = this->giveOrderingDofTypes();
327  IntArray fieldDofId;
328  Shell7Base :: giveDofManDofIDMask(0, fieldDofId);
329 
330 
331  IntArray ordering_temp, activeDofsArrayTemp;
332  ordering_temp.resize(ordering_cont.giveSize());
333  activeDofsArrayTemp.resize(ordering_cont.giveSize());
334 
335 
336  int activeDofPos = 0, activeDofIndex = 0, orderingDofIndex = 0;
337 
338  IntArray dofManDofIdMask, dofManDofIdMaskAll;
339  for ( int i = 1; i <= numberOfDofMans; i++ ) {
340  DofManager *dMan = this->giveDofManager(i);
341 
342 
343  if ( ei == NULL) { // return mask corresponding to the regular id's
344  Shell7Base :: giveDofManDofIDMask(i, dofManDofIdMask);
345  } else {
346  if ( ei->isDofManEnriched(*dMan) ) {
347  ei->giveEIDofIdArray(dofManDofIdMask);
348  }
349  }
350 
351  for (int j = 1; j <= dofManDofIdMask.giveSize(); j++ ) {
352  int pos = dMan->findDofWithDofId( ( DofIDItem ) dofManDofIdMask.at(j) ) - dMan->begin() + 1;
353  activeDofPos++;
354  ordering_temp .at(activeDofPos) = orderingDofIndex + pos;
355  activeDofsArrayTemp.at(activeDofPos) = activeDofIndex + j;
356  }
357  this->giveDofManDofIDMask(i, dofManDofIdMaskAll);
358  orderingDofIndex += dofManDofIdMaskAll.giveSize();
359  activeDofIndex += fieldDofId.giveSize();
360 
361  dofManDofIdMask.clear();
362  }
363 
364  // Reduce arrays to actual size
365  int numActiveDofs = activeDofPos;
366  orderingArray.resize(numActiveDofs), activeDofsArray.resize(numActiveDofs);
367 
368  for ( int i = 1; i <= numActiveDofs; i++ ) {
369  orderingArray.at(i) = ordering_temp.at(i);
370  activeDofsArray.at(i) = activeDofsArrayTemp.at(i);
371  }
372 }
373 
374 
375 void
376 Shell7BaseXFEM :: giveInternalForcesVector(FloatArray &answer, TimeStep *tStep, int useUpdatedGpRecord)
377 {
378  // Computes internal forces as the array of: [f_c, f_d1, ..., f_dn]
379  answer.resize( this->giveNumberOfDofs() );
380  answer.zero();
381  FloatArray solVec, temp;
382 
383  // Continuous part
384  this->giveUpdatedSolutionVector(solVec, tStep);
385  this->computeSectionalForces(temp, tStep, solVec, useUpdatedGpRecord);
386 
387  IntArray activeDofs, ordering;
388  this->computeOrderingArray(ordering, activeDofs, NULL);
389  answer.assemble(temp, ordering);
390 
391  // Disccontinuous part
392  IntArray eiDofIdArray;
393  FloatArray solVecD, tempRed, fCZ;
394  for ( int i = 1; i <= this->xMan->giveNumberOfEnrichmentItems(); i++ ) {
395 
396  EnrichmentItem *ei = this->xMan->giveEnrichmentItem(i);
397  if ( ei->isElementEnriched(this) ) {
398 
399  ei->giveEIDofIdArray(eiDofIdArray);
400  this->computeDiscSolutionVector(eiDofIdArray, tStep, solVecD);
401 
402  this->discComputeSectionalForces(temp, tStep, solVec, solVecD, ei);
403 
404  tempRed.beSubArrayOf(temp, this->activeDofsArrays[i-1]);
405  answer.assemble(tempRed, this->orderingArrays[i-1]);
406 
407  // Cohesive zone model
408  if ( this->hasCohesiveZone(i) ) {
409  // If there are only delaminations present the we only have one contribution per ei.
410  // If there are intralmainar cracks then we get several potential extra terms.
411  // Therefore we must go through them all and check.
412 
413  for ( int j = 1; j <= this->xMan->giveNumberOfEnrichmentItems(); j++ ) {
414  if ( this->xMan->giveEnrichmentItem(j)->isElementEnriched(this) ) {
415  this->computeCohesiveForces( fCZ, tStep, solVec, solVecD, ei, this->xMan->giveEnrichmentItem(j));
416 
417  tempRed.beSubArrayOf(fCZ, this->activeDofsArrays[j-1]);
418  answer.assemble(tempRed, this->orderingArrays[j-1]);
419  }
420  }
421  }
422  }
423  }
424 
425 }
426 
427 
428 void
430 //
431 {
432  int ndofs = Shell7Base :: giveNumberOfDofs();
433  int numberOfLayers = this->layeredCS->giveNumberOfLayers();
434  FloatArray f(ndofs), genEps, ftemp, lCoords, Nd;
435  FloatMatrix B, BEnr;
436  f.zero();
437 
438  for ( int layer = 1; layer <= numberOfLayers; layer++ ) {
439  Material *mat = domain->giveMaterial( this->layeredCS->giveLayerMaterial(layer) );
440 
441  for ( GaussPoint *gp: *integrationRulesArray [ layer - 1 ] ) {
442  lCoords = gp->giveNaturalCoordinates();
443 
444  this->computeEnrichedBmatrixAt(lCoords, B, NULL);
445  this->computeEnrichedBmatrixAt(lCoords, BEnr, ei);
446  genEps.beProductOf(B, solVec);
447  double zeta = giveGlobalZcoord(lCoords);
448  this->computeSectionalForcesAt(Nd, gp, mat, tStep, genEps, zeta);
449 
450  // Computation of nodal forces: f = B^t*[N M T Ms Ts]^t
451  ftemp.beTProductOf( BEnr, Nd );
452  double dV = this->computeVolumeAroundLayer(gp, layer);
453  f.add( dV, ftemp );
454 
455  }
456  }
457 
458  answer.resize(ndofs); answer.zero();
459  answer.assemble(f, this->giveOrderingDofTypes());
460 
461 }
462 
463 
464 void
465 Shell7BaseXFEM :: computeSectionalForcesAt(FloatArray &sectionalForces, IntegrationPoint *ip, Material *mat, TimeStep *tStep, FloatArray &genEps, double zeta)
466 {
467  // New, in terms of PK1 stress
468  // f = \Lambda_i * P * G^I
469  FloatArray PG1(3), PG2(3), PG3(3);
470  FloatMatrix lambda[3], Gcon, P, PG;
471  this->computeStressMatrix(P, genEps, ip, mat, tStep);
472 
473  const FloatArray &lCoords = ip->giveNaturalCoordinates();
474  this->evalInitialContravarBaseVectorsAt(lCoords, Gcon);
475  PG.beProductOf(P,Gcon);
476  PG1.beColumnOf(PG, 1);
477  PG2.beColumnOf(PG, 2);
478  PG3.beColumnOf(PG, 3);
479  this->computeLambdaGMatricesDis(lambda, zeta); // associated with the variation of the test functions
480 
481  // f = lambda_1^T * P*G^1 + lambda_2^T * P*G^2 + lambda_3^T * P*G^3
482  sectionalForces.clear();
483  sectionalForces.plusProduct(lambda[0], PG1, 1.0);
484  sectionalForces.plusProduct(lambda[1], PG2, 1.0);
485  sectionalForces.plusProduct(lambda[2], PG3, 1.0);
486 
487 }
488 
489 
490 
491 
492 
493 
494 double
496 {
497  // Evaluates the corresponding level set depending on the type of enrichment
498  double levelSet = 0.0;
499  if ( dynamic_cast< Delamination * >( ei ) ) {
500  levelSet = lCoords.at(3) - dynamic_cast< Delamination * >( ei )->giveDelamXiCoord();
501  } else if ( dynamic_cast< Crack * >( ei ) ) {
502 
503  Crack *crack = dynamic_cast< Crack * >( ei );
504  FloatArray N;
505  const IntArray &elNodes = this->giveDofManArray();
506  this->fei->evalN( N, lCoords, FEIElementGeometryWrapper(this) );
507  crack->interpLevelSet(levelSet, N, elNodes);
508  } else {
509  OOFEM_ERROR("error in evaluation of levelset");
510  }
511  return levelSet;
512 }
513 
514 #if 0
515 double
516 Shell7BaseXFEM :: edgeEvaluateLevelSet(const FloatArray &lCoords, EnrichmentItem *ei, const int edge)
517 {
518  // Evaluates the corresponding level set depending on the type of enrichment
519  double levelSet = 0.0;
520  if ( dynamic_cast< Delamination * >( ei ) ) {
521  double xiLoad = 0.0;
522  levelSet = xiLoad - dynamic_cast< Delamination * >( ei )->giveDelamXiCoord();
523  } else if ( dynamic_cast< Crack * >( ei ) ) {
524  Crack *crack = dynamic_cast< Crack * >( ei );
525 
526  FloatArray N;
527  //const IntArray &elNodes = this->giveDofManArray();
528  //const IntArray &elNodes = this->giveInterpolation()->givee
529 
530  IntArray edgeNodes, globalNums;
531  static_cast< FEInterpolation3d* >(this->giveInterpolation())->computeLocalEdgeMapping(edgeNodes, edge);
532  globalNums.resize(edgeNodes.giveSize());
533  for ( int i = 1; i <= edgeNodes.giveSize(); i++ ) {
534  globalNums.at(i) = this->giveNode(edgeNodes.at(i))->giveGlobalNumber();
535  }
536 
537  this->fei->edgeEvalN( N, edge, lCoords, FEIElementGeometryWrapper(this) );
538  crack->interpLevelSet(levelSet, N, globalNums);
539 
540  } else {
541  OOFEM_ERROR("error in evaluation of levelset");
542  }
543  return levelSet;
544 }
545 #endif
546 
547 
548 
549 double
551 {
552  // Evaluates the "cut" Heaviside for a ShellCrack
553  double xiBottom = ei->xiBottom;
554  double xiTop = ei->xiTop;
555 
556  return this->evaluateCutHeaviside(xi, xiBottom, xiTop);
557 
558 }
559 
560 double
562 {
563  // Evaluates the "cut" Heaviside for a Delamination
564  double xiBottom = ei->giveDelamXiCoord();
565  double xiTop = ei->giveBoundingDelamXiCoord();
566 
567  return this->evaluateCutHeaviside(xi, xiBottom, xiTop);
568 
569 }
570 
571 double
572 Shell7BaseXFEM :: evaluateCutHeaviside(const double xi, const double xiBottom, const double xiTop) const
573 {
574  // Evaluates the "cut" Heaviside defined as:
575  // H(xi - xi1) - H(xi - xi2) or?
576  // H(xi - xi1) * ( 1 - H(xi - xi2) )
577 
578  if ( ( xiBottom <= xi ) && ( xi <= xiTop ) ) {
579  return 1.0;
580  } else {
581  return 0.0;
582  }
583 
584 }
585 
586 void
588 {
589  // for each interface get maximum interface damage of all the ip's
590  int numZones = this->layeredCS->giveNumberOfLayers() - 1;
591  answer.resize(numZones);
593  FloatArray ipValues;
594  for ( int i = 0; i < numZones; i++ ) {
595  if ( hasCohesiveZone(i+1) ) {
596  double max = 0.0;
597  for ( GaussPoint *gp: *czIntegrationRulesArray [ i ] ) {
598 
599  mat = static_cast < StructuralInterfaceMaterial * > (this->layeredCS->giveInterfaceMaterial(i+1) );
600  mat->giveIPValue(ipValues, gp, IST_DamageScalar, tStep);
601 
602  double val = ipValues.at(1);
603  if ( val > max ) {
604  max = val;
605  }
606 
607  }
608  answer(i) = max;
609  } else {
610  answer(i) = 0.0;
611  }
612  }
613 
614 
615 
616 }
617 
618 
619 void
621 {
622  //Computes the cohesive nodal forces for a given delamination interface
623 
624  Delamination *dei = dynamic_cast< Delamination * >( ei );
625  if ( dei ) { // For now only add cz for delaminations
626  FloatArray answerTemp, lCoords(3);
627  answerTemp.resize(Shell7Base :: giveNumberOfDofs() );
628  answerTemp.zero();
629 
630  FloatMatrix B, Ncoh, NEnr, BEnr, F;
631  int delamNum = dei->giveDelamInterfaceNum();
632 
633  StructuralInterfaceMaterial *intMat = static_cast < StructuralInterfaceMaterial * >
634  (this->layeredCS->giveInterfaceMaterial(delamNum) );
635 
636  FloatMatrix lambdaD, lambdaN, Q;
637  FloatArray Fcoh, T, nCov, jump, unknowns, genEpsC, genEpsD;
638 
639  for ( GaussPoint *gp: *czIntegrationRulesArray [ delamNum - 1 ] ) {
640  double xi = dei->giveDelamXiCoord();
641  lCoords.at(1) = gp->giveNaturalCoordinate(1);
642  lCoords.at(2) = gp->giveNaturalCoordinate(2);
643  lCoords.at(3) = xi;
644 
645  this->computeBmatrixAt(lCoords, B);
646  this->computeCohesiveNmatrixAt(lCoords, Ncoh, coupledToEi);
647 
648  // Compute jump vector
649  this->computeInterfaceJumpAt(dei->giveDelamInterfaceNum(), lCoords, tStep, jump); // -> numerical tol. issue -> normal jump = 1e-10
650 
651  genEpsC.beProductOf(B, solVecC);
652  this->computeFAt(lCoords, F, genEpsC, tStep);
653 
654  // Transform xd and F to a local coord system
655  this->evalInitialCovarNormalAt(nCov, lCoords);
656  Q.beLocalCoordSys(nCov);
657  jump.rotatedWith(Q,'n');
658  F.rotatedWith(Q,'n');
659 
660  // Compute cohesive traction based on jump
661  intMat->giveFirstPKTraction_3d(T, gp, jump, F, tStep);
662 
663  //zzjump.printYourself("spatial jump");
664  //T.printYourself("Traction");
665  T.rotatedWith(Q,'t'); // transform back to global coord system
666 
667  double zeta = xi * this->layeredCS->computeIntegralThick() * 0.5;
668  this->computeLambdaNMatrixDis(lambdaD,zeta);
669  lambdaN.beProductOf(lambdaD, Ncoh);
670  Fcoh.beTProductOf(lambdaN, T);
671  double dA = this->computeAreaAround(gp,xi);
672  answerTemp.add(dA, Fcoh);
673  }
674 
675  int ndofs = Shell7Base :: giveNumberOfDofs();
676  answer.resize(ndofs); answer.zero();
677  const IntArray &ordering = this->giveOrderingDofTypes();
678  answer.assemble(answerTemp, ordering);
679  }
680 }
681 
682 void
684 // Updates the receiver at end of step.
685 {
687 
688  for ( int i = 0; i < this->layeredCS->giveNumberOfLayers() - 1; i++ ) {
689  if ( this->hasCohesiveZone(i+1) ) {
690  czIntegrationRulesArray [ i ]->updateYourself(tStep);
691  }
692  }
693 
694 
695 }
696 
697 
698 
699 void
701 {
702  //Computes the cohesive tangent forces for a given interface
703 
704  /* This tangent should be added for each delamination interface k
705  *
706  * Kcoh_k = [0 0 0 ... 0 0 ... 0
707  * 0 K_kk 0 ... 0 K_kc1 ... K_kcn
708  * 0 .
709  * 0 K_c1k 0 ... 0 K_c1c1 ... K_c1cn
710  * 0
711  * 0 K_cnk 0 ... 0 K_cnc1 ... K_cncn ]
712  *
713  */
714  FloatMatrix temp;
715  int ndofs = this->giveNumberOfDofs();
716  answer.resize(ndofs, ndofs);
717  answer.zero();
718 
719  FloatMatrix tempRed, tempRedT;
720  for ( int i = 1; i <= this->xMan->giveNumberOfEnrichmentItems(); i++ ) {
721 
722  // dei is the current delamination where the material tangent d(trac)/d(jump) is evaluated
723  Delamination *dei = dynamic_cast< Delamination * >( this->xMan->giveEnrichmentItem(i) );
724  if ( dei != NULL && dei->isElementEnriched(this) && this->hasCohesiveZone(i) ) {
725 
726 
727  for ( int j = 1; j <= this->xMan->giveNumberOfEnrichmentItems(); j++ ) {
728  for ( int k = j; k <= this->xMan->giveNumberOfEnrichmentItems(); k++ ) { // upper triangular part
729  // Coupling enrichments
730  //EnrichmentItem *ei_j = this->xMan->giveEnrichmentItem(j);
731  Delamination *dei_j = dynamic_cast< Delamination * >( this->xMan->giveEnrichmentItem(j) );
732  //EnrichmentItem *ei_k = this->xMan->giveEnrichmentItem(k);
733  Delamination *dei_k = dynamic_cast< Delamination * >( this->xMan->giveEnrichmentItem(k) );
734  if ( dei_j && dei_j->isElementEnriched(this) && dei_k && dei_k->isElementEnriched(this) ) {
735 
736  this->computeCohesiveTangentAt(temp, tStep, dei, dei_j, dei_k);
737 
738  // Assemble part correpsonding to active dofs
739  tempRed.beSubMatrixOf(temp, this->activeDofsArrays[dei_j->giveNumber()-1], this->activeDofsArrays[dei_k->giveNumber()-1]);
740  answer.assemble(tempRed, this->orderingArrays[dei_j->giveNumber()-1], this->orderingArrays[dei_k->giveNumber()-1]);
741 
742  if( j != k ) { // add off diagonal contributions
743  tempRedT.beTranspositionOf(tempRed);
744  answer.assemble(tempRedT, this->orderingArrays[dei_k->giveNumber()-1], this->orderingArrays[dei_j->giveNumber()-1]);
745  }
746  }
747  }
748  }
749  }
750  }
751 }
752 
753 
754 
755 void
757 {
758  /* Computes the cohesive tangent contribution (block matrix) for a given interface given two
759  * enrichment items (j,k) it (potentially) couples to.
760  * K_cz = Ncoh_j^t*lambda*t * dT/dj * lambda * Ncoh_k
761  *
762  */
763  FloatArray lCoords(3);
764  FloatMatrix answerTemp, Ncoh_j, Ncoh_k, lambda, D, temp, tangent;
765  int nDofs = Shell7Base :: giveNumberOfDofs();
766  answerTemp.resize(nDofs, nDofs);
767  answerTemp.zero();
768 
769  int delamNum = dei->giveDelamInterfaceNum();
770  std :: unique_ptr< IntegrationRule > &iRuleL = czIntegrationRulesArray [ dei->giveDelamInterfaceNum() - 1 ];
771  StructuralInterfaceMaterial *intMat = static_cast < StructuralInterfaceMaterial * >
772  (this->layeredCS->giveInterfaceMaterial(delamNum) );
773 
774  double xi = dei->giveDelamXiCoord();
775 
776  FloatMatrix Q;
777  FloatArray nCov;
778  for ( GaussPoint *gp: *iRuleL ) {
779  lCoords = { gp->giveNaturalCoordinate(1), gp->giveNaturalCoordinate(2), xi};
780 
781  intMat->give3dStiffnessMatrix_dTdj(D, TangentStiffness, gp, tStep);
782 
783  //IntMatBilinearCZJanssonStatus *status = static_cast< IntMatBilinearCZJanssonStatus * >( intMat->giveStatus(gp) );
784  //double damage = status->giveTempDamage();
785  //if ( damage >= 1 ) { printf("Full damage in elt %i \n",damage,this->giveNumber()); }
786 
787 
788  this->evalInitialCovarNormalAt(nCov, lCoords);
789  Q.beLocalCoordSys(nCov);
790  D.rotatedWith(Q,'t'); // rotate back to global coord system
791 
792  double zeta = giveGlobalZcoord( lCoords);
793  this->computeLambdaNMatrixDis( lambda, zeta );
794  this->computeCohesiveNmatrixAt(lCoords, Ncoh_j, ei_j);
795  this->computeCohesiveNmatrixAt(lCoords, Ncoh_k, ei_k);
796 
798  this->computeTripleProduct(temp, lambda, D, lambda);
799  this->computeTripleProduct(tangent, Ncoh_j, temp, Ncoh_k);
800  double dA = this->computeAreaAround(gp, xi);
801  answerTemp.add(dA,tangent);
802  }
803 
804  answer.resize(nDofs, nDofs);
805  answer.zero();
806  const IntArray &ordering = this->giveOrderingDofTypes();
807  answer.assemble(answerTemp, ordering, ordering);
808 }
809 
810 
811 void
813 {
814  /* Returns the N-matrix associated with the variation of the jump over a delamination interface.
815  * Evaluate \delta jump -> jump = phi(+)-phi(-) = N(+)*a - N(-)*a = [N(+)-N(-)]*a = Ncoh*a
816  * where a is the solution vector for a given dicontinuity (ei)
817  * This should be correct for delaminations (only) as well N(-)=0
818  */
819  FloatMatrix N_minus_side;
820  FloatArray perturbedCoords = lCoords;
821  perturbedCoords.at(3) = lCoords.at(3) + 1.0e-9; // make sure we are on the plus side
822  this->computeEnrichedNmatrixAt(perturbedCoords, answer, ei);
823 
824  perturbedCoords.at(3) = lCoords.at(3) - 1.0e-9; // make sure we are on the minus side
825  this->computeEnrichedNmatrixAt(perturbedCoords, N_minus_side, ei);
826  answer.subtract(N_minus_side);
827 
828 }
829 
830 
831 void
833 {
834 
835  this->OLDcomputeStiffnessMatrix(answer, rMode, tStep);
836  return;
837 
838  int ndofs = this->giveNumberOfDofs();
839  answer.resize(ndofs, ndofs);
840  answer.zero();
841 
842  int numberOfLayers = this->layeredCS->giveNumberOfLayers();
843  FloatMatrix tempRed, tempRedT;
844  FloatMatrix KCC, KDC, KDD;
845  FloatMatrix LCC, LDD, LDC;
846  FloatMatrix B, BenrM, BenrK;
847 
848 
849  IntArray orderingC, activeDofsC;
850  this->computeOrderingArray(orderingC, activeDofsC, NULL);
851  FloatArray solVec;
852  this->giveUpdatedSolutionVector(solVec, tStep);
853 
854  FloatMatrix A [ 3 ] [ 3 ], LB, KOrdered;
855  KOrdered.resize(ndofs,ndofs);
856 
857 
858  const IntArray &ordering = this->giveOrderingDofTypes();
859 
860  for ( int layer = 1; layer <= numberOfLayers; layer++ ) {
861  StructuralMaterial *layerMaterial = static_cast< StructuralMaterial* >( domain->giveMaterial( this->layeredCS->giveLayerMaterial(layer) ) );
862 
863  for ( GaussPoint *gp: *integrationRulesArray [ layer - 1 ] ) {
864  const FloatArray &lCoords = gp->giveNaturalCoordinates();
866  double dV = this->computeVolumeAroundLayer(gp, layer);
867 
868 
869  Shell7Base :: computeLinearizedStiffness(gp, layerMaterial, tStep, A); // called L in new formulation
870  this->discComputeStiffness(LCC, LDD, LDC, gp, layer, A, tStep); // called D in new formulation
871 
872  LB.beProductOf(LCC, B);
873  KCC.clear();
874  KCC.plusProductSymmUpper(B, LB, dV);
875  KCC.symmetrized();
876  KOrdered.zero();
877  KOrdered.assemble(KCC, ordering, ordering); // from dof group to node ordering
878  tempRed.beSubMatrixOf(KOrdered, activeDofsC, activeDofsC);
879  answer.assemble(tempRed, orderingC, orderingC); // position in element stiffness matrix
880 
881  // Discontinuous part
882  int numEI = this->xMan->giveNumberOfEnrichmentItems();
883  for ( int m = 1; m <= numEI; m++ ) {
884  EnrichmentItem *eiM = this->xMan->giveEnrichmentItem(m);
885  this->computeEnrichedBmatrixAt(lCoords, BenrM, eiM);
886 
887  if ( eiM->isElementEnriched(this) ) {
888  LB.beProductOf(LDC, B);
889  KDC.clear();
890  KDC.plusProductUnsym(BenrM, LB, dV);
891  KOrdered.zero();
892  KOrdered.assemble(KDC, ordering, ordering);
893 
894  tempRed.beSubMatrixOf(KOrdered, this->activeDofsArrays[m-1], activeDofsC);
895  tempRedT.beTranspositionOf(tempRed);
896  answer.assemble(tempRed, this->orderingArrays[m-1], orderingC);
897  answer.assemble(tempRedT, orderingC, this->orderingArrays[m-1]);
898 
899 
900  // K_{dk,dl}
901  for ( int k = 1; k <= numEI; k++ ) {
902  EnrichmentItem *eiK = this->xMan->giveEnrichmentItem(k);
903  this->computeEnrichedBmatrixAt(lCoords, BenrK, eiK);
904 
905  if ( eiK->isElementEnriched(this) ) {
906  if ( this->activeDofsArrays[m-1].giveSize() != 0 && this->activeDofsArrays[k-1].giveSize() != 0 ) {
907  LB.beProductOf(LDD, BenrK);
908  KDD.clear();
909  KDD.plusProductSymmUpper(BenrM, LB, dV);
910  KDD.symmetrized();
911  KOrdered.zero();
912  KOrdered.assemble(KDD, ordering, ordering);
913  tempRed.beSubMatrixOf(KOrdered, this->activeDofsArrays[m-1], this->activeDofsArrays[k-1]);
914  answer.assemble(tempRed, this->orderingArrays[m-1], this->orderingArrays[k-1]);
915  }
916 
917  }
918 
919  }
920  }
921  }
922 
923  }
924  }
925 
926 
927  // Cohesive zones
928 #if 1
929  FloatMatrix Kcoh;
930  this->computeCohesiveTangent(Kcoh, tStep);
931  //Kcoh.times(DISC_DOF_SCALE_FAC*DISC_DOF_SCALE_FAC);
932  answer.add(Kcoh);
933 
934 #endif
935 
936 
937  // Add contribution due to pressure load
938 #if 0
939 
940  int nLoads = this->boundaryLoadArray.giveSize() / 2;
941 
942  for ( int k = 1; k <= nLoads; k++ ) { // For each pressure load that is applied
943  int load_number = this->boundaryLoadArray.at(2 * k - 1);
944  int iSurf = this->boundaryLoadArray.at(2 * k); // load_id
945  Load *load = this->domain->giveLoad(load_number);
946  std :: vector< double > efM, efK;
947 
948  if ( ConstantPressureLoad * pLoad = dynamic_cast< ConstantPressureLoad * >(load) ) {
949 
950  IntegrationRule *iRule = specialIntegrationRulesArray [ 1 ];
951 
952  for ( GaussPoint *gp: *iRule ) {
953  this->computePressureTangentMatrixDis(KCC, KCD, KDD, gp, load, iSurf, tStep);
954  KCD.times(DISC_DOF_SCALE_FAC);
955  KDD.times(DISC_DOF_SCALE_FAC*DISC_DOF_SCALE_FAC);
956 
957  // Continuous part
958  answer.assemble(KCC, orderingC, orderingC);
959 
960  // Discontinuous part
961  int numEI = this->xMan->giveNumberOfEnrichmentItems();
962  for ( int m = 1; m <= numEI; m++ ) {
963  Delamination *deiM = dynamic_cast< Delamination * >( this->xMan->giveEnrichmentItem(m) );
964 
965  if ( deiM !=NULL && deiM->isElementEnriched(this) ) {
966  double levelSetM = pLoad->giveLoadOffset() - deiM->giveDelamXiCoord();
967  deiM->evaluateEnrFuncAt(efM, lCoords, levelSetM);
968 
969  IntArray &orderingJ = orderingArrays[m-1];
970  IntArray &activeDofsJ = activeDofsArrays[m-1];
971 
972  // con-dis & dis-con
973  if ( efM[0] > 0.1 ) {
974  tempRed.beSubMatrixOf(KCD, activeDofsC, activeDofsJ);
975  answer.assemble(tempRed, orderingC, orderingJ);
976  tempRedT.beTranspositionOf(tempRed);
977  answer.assemble(tempRedT, orderingJ, orderingC);
978  }
979 
980  // dis-dis
981  for ( int k = 1; k <= numEI; k++ ) {
982  Delamination *deiK = dynamic_cast< Delamination * >( this->xMan->giveEnrichmentItem(k) );
983  if ( deiK != NULL && deiK->isElementEnriched(this) ) {
984  double levelSetK = pLoad->giveLoadOffset() - deiK->giveDelamXiCoord();
985  deiK->evaluateEnrFuncAt(efK, lCoords, levelSetK);
986  if ( efM[0] > 0.1 && efK[0] > 0.1 ) {
987  IntArray &orderingK = orderingArrays[k-1];
988  IntArray &activeDofsK = activeDofsArrays[k-1];
989  tempRed.beSubMatrixOf(KDD, activeDofsJ, activeDofsK);
990  answer.assemble(tempRed, orderingJ, orderingK);
991  }
992  }
993 
994  }
995  }
996 
997  }
998 
999  }
1000 
1001 
1002 
1003  }
1004  }
1005 #endif
1006 
1007 }
1008 
1009 
1010 void
1012 {
1013  // Should compute lambda_i * A_ij * lamda_j for the different combinations of lambda
1014  // L_CC = lambdaC_i^T * A_ij * lambdaC_j
1015  // L_DD = lambdaD_i^T * A_ij * lambdaD_j
1016  // L_CD = lambdaC_i^T * A_ij * lambdaD_j
1017  FloatMatrix B;
1018  FloatMatrix lambdaC [ 3 ], lambdaD [ 3 ];
1019 
1020  const FloatArray &lCoords = ip->giveNaturalCoordinates();
1021  FloatArray solVecC, genEpsC;
1022  Shell7Base :: computeBmatrixAt(lCoords,B);
1023 
1024  double zeta = giveGlobalZcoord( lCoords );
1025  this->giveUpdatedSolutionVector(solVecC, tStep);
1026  genEpsC.beProductOf(B,solVecC);
1027  this->computeLambdaGMatrices(lambdaC, genEpsC, zeta);
1028  this->computeLambdaGMatricesDis(lambdaD, zeta);
1029 
1030  FloatMatrix A_lambdaC(3,18), A_lambdaD(3,18);
1031  LCC.clear(); LDD.clear(); LDC.clear();
1032 
1033 
1034  for (int i = 0; i < 3; i++) {
1035  A_lambdaC.zero(); A_lambdaD.zero();
1036  for (int j = 0; j < 3; j++) {
1037  A_lambdaC.addProductOf(A[i][j], lambdaC[j]);
1038  A_lambdaD.addProductOf(A[i][j], lambdaD[j]);
1039  }
1040  LCC.plusProductSymmUpper(lambdaC[i], A_lambdaC, 1.0);
1041  LDD.plusProductSymmUpper(lambdaD[i], A_lambdaD, 1.0);
1042  LDC.plusProductUnsym(lambdaD[i], A_lambdaC, 1.0);
1043  }
1044  LCC.symmetrized();
1045  LDD.symmetrized();
1046 
1047 
1048 }
1049 
1050 
1051 //remove
1052 void
1054 {
1055  // This is an old unoptimized version.
1056  // The new one doesn't work with all the coupling terms for shellcracks and delaminations.
1057  int ndofs = this->giveNumberOfDofs();
1058  answer.resize(ndofs, ndofs);
1059  answer.zero();
1060 
1061  int numberOfLayers = this->layeredCS->giveNumberOfLayers();
1062  FloatMatrix tempRed, tempRedT;
1063  FloatMatrix KCC, KCD, KDD, Bc;
1064  IntArray orderingC, activeDofsC;
1065  this->computeOrderingArray(orderingC, activeDofsC, NULL);
1066  FloatArray solVec;
1067  this->giveUpdatedSolutionVector(solVec, tStep);
1068 
1069  FloatMatrix A [ 3 ] [ 3 ];
1070 
1071  Shell7Base :: computeBulkTangentMatrix(KCC, solVec, tStep );
1072  answer.assemble(KCC, orderingC, orderingC);
1073 
1074  for ( int layer = 1; layer <= numberOfLayers; layer++ ) {
1075  StructuralMaterial *layerMaterial = static_cast< StructuralMaterial* >( domain->giveMaterial( this->layeredCS->giveLayerMaterial(layer) ) );
1076 
1077  for ( GaussPoint *gp: *integrationRulesArray [ layer - 1 ] ) {
1078  const FloatArray &lCoords = gp->giveNaturalCoordinates();
1079  this->computeEnrichedBmatrixAt(lCoords, Bc, NULL);
1080 
1081  Shell7Base :: computeLinearizedStiffness(gp, layerMaterial, tStep, A);
1082 
1083  // Continuous part K_{c,c}
1084  //this->discComputeBulkTangentMatrix(KCC, gp, NULL, NULL, layer, A, tStep);
1085  //answer.assemble(KCC, orderingC, orderingC);
1086 
1087  // Discontinuous part
1088  int numEI = this->xMan->giveNumberOfEnrichmentItems();
1089  for ( int m = 1; m <= numEI; m++ ) {
1090  EnrichmentItem *eiM = this->xMan->giveEnrichmentItem(m);
1091 
1092  if ( eiM->isElementEnriched(this) ) {
1093 
1094  this->discComputeBulkTangentMatrix(KCD, gp, NULL, eiM, layer, A, tStep);
1095  tempRed.beSubMatrixOf(KCD, activeDofsC, this->activeDofsArrays[m-1]);
1096  answer.assemble(tempRed, orderingC, this->orderingArrays[m-1]);
1097  tempRedT.beTranspositionOf(tempRed);
1098  answer.assemble(tempRedT, this->orderingArrays[m-1], orderingC);
1099 
1100  // K_{dk,dl}
1101  for ( int k = 1; k <= numEI; k++ ) {
1102  EnrichmentItem *eiK = this->xMan->giveEnrichmentItem(k);
1103 
1104  if ( eiK->isElementEnriched(this) ) {
1105  this->discComputeBulkTangentMatrix(KDD, gp, eiM, eiK, layer, A, tStep);
1106  if ( this->activeDofsArrays[m-1].giveSize() != 0 && this->activeDofsArrays[k-1].giveSize() != 0 ) {
1107  tempRed.beSubMatrixOf(KDD, this->activeDofsArrays[m-1], this->activeDofsArrays[k-1]);
1108  answer.assemble(tempRed, this->orderingArrays[m-1], this->orderingArrays[k-1]);
1109  }
1110 
1111  }
1112 
1113  }
1114  }
1115  }
1116 
1117  }
1118  }
1119 
1120 
1121 // Cohesive zones
1122 #if 1
1123 FloatMatrix Kcoh;
1124 this->computeCohesiveTangent(Kcoh, tStep);
1125 //Kcoh.times(DISC_DOF_SCALE_FAC*DISC_DOF_SCALE_FAC);
1126 answer.add(Kcoh);
1127 
1128 #endif
1129 
1130 
1131 // Add contribution due to pressure load
1132 #if 0
1133 
1134 int nLoads = this->boundaryLoadArray.giveSize() / 2;
1135 
1136 for ( int k = 1; k <= nLoads; k++ ) { // For each pressure load that is applied
1137  int load_number = this->boundaryLoadArray.at(2 * k - 1);
1138  int iSurf = this->boundaryLoadArray.at(2 * k); // load_id
1139  Load *load = this->domain->giveLoad(load_number);
1140  std :: vector< double > efM, efK;
1141 
1142  if ( ConstantPressureLoad * pLoad = dynamic_cast< ConstantPressureLoad * >(load) ) {
1143 
1144  IntegrationRule *iRule = specialIntegrationRulesArray [ 1 ];
1145 
1146  for ( GaussPoint *gp: *iRule ) {
1147  this->computePressureTangentMatrixDis(KCC, KCD, KDD, gp, load, iSurf, tStep);
1148  KCD.times(DISC_DOF_SCALE_FAC);
1149  KDD.times(DISC_DOF_SCALE_FAC*DISC_DOF_SCALE_FAC);
1150 
1151  // Continuous part
1152  answer.assemble(KCC, orderingC, orderingC);
1153 
1154  // Discontinuous part
1155  int numEI = this->xMan->giveNumberOfEnrichmentItems();
1156  for ( int m = 1; m <= numEI; m++ ) {
1157  Delamination *deiM = dynamic_cast< Delamination * >( this->xMan->giveEnrichmentItem(m) );
1158 
1159  if ( deiM !=NULL && deiM->isElementEnriched(this) ) {
1160  double levelSetM = pLoad->giveLoadOffset() - deiM->giveDelamXiCoord();
1161  deiM->evaluateEnrFuncAt(efM, lCoords, levelSetM);
1162 
1163  IntArray &orderingJ = orderingArrays[m-1];
1164  IntArray &activeDofsJ = activeDofsArrays[m-1];
1165 
1166  // con-dis & dis-con
1167  if ( efM[0] > 0.1 ) {
1168  tempRed.beSubMatrixOf(KCD, activeDofsC, activeDofsJ);
1169  answer.assemble(tempRed, orderingC, orderingJ);
1170  tempRedT.beTranspositionOf(tempRed);
1171  answer.assemble(tempRedT, orderingJ, orderingC);
1172 }
1173 
1174 // dis-dis
1175 for ( int k = 1; k <= numEI; k++ ) {
1176  Delamination *deiK = dynamic_cast< Delamination * >( this->xMan->giveEnrichmentItem(k) );
1177  if ( deiK != NULL && deiK->isElementEnriched(this) ) {
1178  double levelSetK = pLoad->giveLoadOffset() - deiK->giveDelamXiCoord();
1179  deiK->evaluateEnrFuncAt(efK, lCoords, levelSetK);
1180  if ( efM[0] > 0.1 && efK[0] > 0.1 ) {
1181  IntArray &orderingK = orderingArrays[k-1];
1182  IntArray &activeDofsK = activeDofsArrays[k-1];
1183  tempRed.beSubMatrixOf(KDD, activeDofsJ, activeDofsK);
1184  answer.assemble(tempRed, orderingJ, orderingK);
1185 }
1186 }
1187 
1188 }
1189 }
1190 
1191 }
1192 
1193 }
1194 
1195 
1196 
1197 }
1198 }
1199 #endif
1200 
1201 }
1202 
1203 //remove
1204 void
1206 {
1207 
1208  FloatMatrix temp, B1, B2;
1209  FloatMatrix lambda1 [ 3 ], lambda2 [ 3 ];
1210 
1211  const FloatArray &lCoords = ip->giveNaturalCoordinates();
1212  this->computeEnrichedBmatrixAt(lCoords, B1, ei1);
1213  this->computeEnrichedBmatrixAt(lCoords, B2, ei2);
1214 
1215  int eiNum1 = 0, eiNum2 = 0;
1216  double zeta = giveGlobalZcoord( lCoords );
1217  if ( ei1 ) {
1218  this->computeLambdaGMatricesDis(lambda1, zeta);
1219  eiNum1 = ei1->giveNumber();
1220  } else {
1221  FloatArray solVecC, genEpsC;
1222  this->giveUpdatedSolutionVector(solVecC, tStep);
1223  genEpsC.beProductOf(B1,solVecC);
1224  this->computeLambdaGMatrices(lambda1, genEpsC, zeta);
1225  }
1226 
1227  if ( ei2 ) {
1228  this->computeLambdaGMatricesDis(lambda2, zeta);
1229  eiNum2 = ei2->giveNumber();
1230  } else {
1231  FloatArray solVecC, genEpsC;
1232  this->giveUpdatedSolutionVector(solVecC, tStep);
1233  genEpsC.beProductOf(B2,solVecC);
1234  this->computeLambdaGMatrices(lambda2, genEpsC, zeta);
1235  }
1236 
1237  double dV = this->computeVolumeAroundLayer(ip, layer);
1238 
1239  int ndofs = Shell7Base :: giveNumberOfDofs();
1240  FloatMatrix KDDtemp(ndofs, ndofs);
1241  KDDtemp.zero();
1242  FloatMatrix L(18,18), A_lambda(3,18), LB;
1243  L.zero(); A_lambda.zero();
1244 
1245  if ( eiNum1 == eiNum2 ) { // diagonal element
1246  //if (0 ) { // diagonal element
1247 
1248  for (int i = 0; i < 3; i++) {
1249  A_lambda.zero();
1250  for (int j = 0; j < 3; j++) {
1251  A_lambda.addProductOf(A[i][j], lambda1[j]);
1252  }
1253  L.plusProductSymmUpper(lambda1[i], A_lambda, 1.0);
1254  //L.plusProductUnsym(lambda1[i], A_lambda, dV);
1255  }
1256  L.symmetrized();
1257  LB.beProductOf(L, B1);
1258  KDDtemp.plusProductSymmUpper(B1, LB, dV);
1259  KDDtemp.symmetrized();
1260  } else {
1261  for ( int j = 0; j < 3; j++ ) {
1262  for ( int k = 0; k < 3; k++ ) {
1263  this->computeTripleProduct(temp, lambda1 [ j ], A [ j ][ k ], lambda2 [ k ] );
1264  L.add(dV,temp);
1265  }
1266  }
1267  this->computeTripleProduct(KDDtemp, B1, L, B2 );
1268  }
1269 
1270  KdIJ.resize(ndofs,ndofs);
1271  KdIJ.zero();
1272  const IntArray &ordering = this->giveOrderingDofTypes();
1273 
1274  KdIJ.assemble(KDDtemp, ordering, ordering);
1275 
1276 }
1277 
1278 
1279 
1280 
1281 void
1283 {
1284  // computes the lambda^g matrices associated with the variation and linearization
1285  // of the discontinuous base vectors gd_i.
1286 
1287  // thickness coefficients
1288  double a = zeta ;
1289  double c = 1.0 ;
1290 
1291  // lambda1 = ( I, 0, a*I, 0 , 0, 0 , 0, 0 )
1292  // lambda2 = ( 0, I, 0 , a*I, 0, 0 , 0, 0 )
1293  FloatMatrix eye(3,3), aEye(3,3);
1294  eye.beUnitMatrix();
1295  aEye=eye; aEye.times(a);
1296  lambda[ 0 ].resize(3,18); lambda[ 0 ].zero();
1297  lambda[ 1 ].resize(3,18); lambda[ 1 ].zero();
1298  lambda[ 0 ].setSubMatrix(eye,1,1); lambda[ 0 ].setSubMatrix(aEye,1,7);
1299  lambda[ 1 ].setSubMatrix(eye,1,4); lambda[ 1 ].setSubMatrix(aEye,1,10);
1300 
1301  // lambda3 = ( 0, 0, 0 , 0 , c*I , 0 , 0 , 0 )
1302  lambda[ 2 ].resize(3,18); lambda[ 2 ].zero();
1303  lambda[ 2 ].at(1,13) = lambda[ 2 ].at(2,14) = lambda[ 2 ].at(3,15) = c;
1304 
1305 }
1306 
1307 void
1309 {
1310  // computes the lambda_x matrix associated with the variation and linearization of the
1311  // discontinuous position vector x_di. (\delta x_{di} = lambda_{xd}*\delta n_x)
1312 
1313  // lambda_x = ( I, a*I, 0 )
1314  lambda_xd.resize(3,7);
1315  lambda_xd.zero();
1316  lambda_xd.at(1,1) = lambda_xd.at(2,2) = lambda_xd.at(3,3) = 1.0;
1317  lambda_xd.at(1,4) = lambda_xd.at(2,5) = lambda_xd.at(3,6) = zeta;
1318 }
1319 
1320 
1321 
1322 void
1324 {
1325  // Computes tangent matrix associated with the linearization of pressure loading. Assumes constant pressure.
1326  ConstantPressureLoad* pLoad = dynamic_cast< ConstantPressureLoad * >( load );
1327 
1328  FloatMatrix N, B, gcov, W1, W2;
1329  FloatArray lCoords, solVec, pressure;
1330  FloatArray g1, g2, genEps;
1331  FloatMatrix lambdaGC [ 3 ], lambdaNC, lambdaGD [ 3 ], lambdaND;
1332  double xi = pLoad->giveLoadOffset();
1333  lCoords = ip->giveNaturalCoordinates();
1334  lCoords.at(3) = xi; // local coord where load is applied
1335  double zeta = this->giveGlobalZcoord( lCoords );
1336  this->giveUpdatedSolutionVector(solVec, tStep);
1337 
1338  // compute w1,w2, KC
1339  this->computeNmatrixAt(lCoords, N);
1340  this->computeBmatrixAt(lCoords, B);
1341  genEps.beProductOf(B, solVec);
1342 
1343 
1344  FloatMatrix LCC, LCD, LDD;
1345 
1346  //(xc+xd)*(g1xg2)=xc*g1xg2 + xd*g1xg2 -> xc*(W2*Dg1 - W1*Dg2) + xd*(W2*Dg1 - W1*Dg2)
1347  // Traction tangent, L = lambdaN * ( W2*lambdaG_1 - W1*lambdaG_2 )
1348  load->computeValueAt(pressure, tStep, ip->giveNaturalCoordinates(), VM_Total); // pressure component
1349  this->evalCovarBaseVectorsAt(lCoords, gcov, genEps, tStep);
1350  g1.beColumnOf(gcov,1);
1351  g2.beColumnOf(gcov,2);
1352  W1 = this->giveAxialMatrix(g1);
1353  W2 = this->giveAxialMatrix(g2);
1354 
1355  this->computeLambdaGMatrices(lambdaGC, genEps, zeta);
1356  this->computeLambdaNMatrix(lambdaNC, genEps, zeta);
1357  this->computeLambdaGMatricesDis(lambdaGD, zeta);
1358  this->computeLambdaNMatrixDis(lambdaND, zeta);
1359 
1360  FloatMatrix W2L, W1L;
1361  W2L.beProductOf(W2,lambdaGC[0]);
1362  W1L.beProductOf(W1,lambdaGC[1]);
1363  W2L.subtract(W1L);
1364  LCC.beTProductOf(lambdaNC, W2L);
1365  LCC.times( -pressure.at(1) );
1366 
1367  W2L.beProductOf(W2,lambdaGD[0]);
1368  W1L.beProductOf(W1,lambdaGD[1]);
1369  W2L.subtract(W1L);
1370  LCD.beTProductOf(lambdaNC, W2L);
1371  LCD.times( -pressure.at(1) );
1372 
1373  W2L.beProductOf(W2,lambdaGD[0]);
1374  W1L.beProductOf(W1,lambdaGD[1]);
1375  W2L.subtract(W1L);
1376  LDD.beTProductOf(lambdaND, W2L);
1377  LDD.times( -pressure.at(1) );
1378 
1379 
1380  FloatMatrix KCCtemp, KCDtemp, KDDtemp;
1381  this->computeTripleProduct(KCCtemp, N, LCC, B );
1382  this->computeTripleProduct(KCDtemp, N, LCD, B );
1383  this->computeTripleProduct(KDDtemp, N, LDD, B );
1384 
1385  int ndofs = Shell7Base :: giveNumberOfDofs();
1386  KCC.resize(ndofs,ndofs); KCD.resize(ndofs,ndofs); KDD.resize(ndofs,ndofs);
1387  KCC.zero(); KCD.zero(); KDD.zero();
1388  const IntArray &ordering = this->giveOrderingDofTypes();
1389  KCC.assemble(KCCtemp, ordering, ordering);
1390  KCD.assemble(KCDtemp, ordering, ordering);
1391  KDD.assemble(KDDtemp, ordering, ordering);
1392 }
1393 
1394 void
1396 {
1397  // Num refers in this case to numerical integration in both in-plane and through the thickness.
1398  // For analytically integrated throught he thickness, see computeMassMatrix
1400 
1401 #if 0
1402  FloatMatrix mass, temp;
1403  FloatArray solVec;
1404  this->giveUpdatedSolutionVector(solVec, tStep);
1405  int ndofs = this->giveNumberOfDofs();
1406 
1407 
1408  LayeredCrossSection *layeredCS = dynamic_cast< LayeredCrossSection * >( this->giveCrossSection() );
1409  int numberOfLayers = layeredCS->giveNumberOfLayers(); // conversion of data
1410 
1411  FloatMatrix M11(18, 18), M12(18, 18), M13(18, 6), M22(18, 18), M23(18, 6), M33(6, 6);
1412  M11.zero();
1413  M12.zero();
1414  M13.zero();
1415  M22.zero();
1416  M23.zero();
1417  M33.zero();
1418 
1419  for ( int layer = 1; layer <= numberOfLayers; layer++ ) {
1420  IntegrationRule *iRuleL = integrationRulesArray [ layer - 1 ];
1421  Material *mat = domain->giveMaterial( layeredCS->giveLayerMaterial(layer) );
1422 
1423  for ( GaussPoint *gp: *iRule ) {
1424 
1425  FloatMatrix N11, N22, N33, N;
1426  //this->computeNmatricesAt(gp, N11, N22, N33);
1427  this->computeNmatrixAt(gp, N);
1428  FloatArray xbar, m;
1429  double gam = 0.;
1430  //this->computeSolutionFields(xbar, m, gam, solVec, N11, N22, N33);
1431  FloatArray localCoords = gp->giveNaturalCoordinates();
1432  this->giveUnknownsAt(localCoords, solVec, xbar, m, gam, tStep);
1433  //this->computeNmatrixAt(gp, N);
1434  //unknowns.beProductOf(N,a); // [xbar, m, gam]^T
1435  //m = {unknowns.at(4), unknowns.at(5), unknowns.at(6) };
1436  //double gam = unknowns.at(7);
1437 
1438 
1439  /* Consistent mass matrix M = int{N^t*mass*N}
1440  *
1441  * 3 3 1
1442  * 3 [a*I b*I c*m [A B C
1443  * mass = 3 d*I e*m = D E
1444  * 1 sym f*m.m] sym F]
1445  */
1446 
1447 
1448  double zeta = giveGlobalZcoord( gp->giveNaturalCoordinate(3) );
1449  double fac1 = 4;
1450  double fac2 = 2.0 * zeta * ( 2.0 + gam * zeta );
1451  double fac3 = 2.0 * zeta * zeta;
1452  double fac4 = zeta * zeta * ( 2.0 + gam * zeta ) * ( 2.0 + gam * zeta );
1453  double fac5 = zeta * zeta * zeta * ( 2.0 + gam * zeta );
1454  double fac6 = zeta * zeta * zeta * zeta;
1455  FloatMatrix mass11(3, 3), mass12(3, 3), mass13(3, 1), mass21(3, 3), mass22(3, 3), mass23(3, 1), mass31(1, 3), mass32(1, 3), mass33(1, 1);
1456  mass.resize(7, 7);
1457  mass11.at(1, 1) = mass11.at(2, 2) = mass11.at(3, 3) = fac1; // A
1458  mass12.at(1, 1) = mass12.at(2, 2) = mass12.at(3, 3) = fac2; // B
1459  mass13.at(1, 1) = fac3 * m.at(1);
1460  mass13.at(2, 1) = fac3 * m.at(2);
1461  mass13.at(3, 1) = fac3 * m.at(3); // C
1462  mass22.at(1, 1) = mass22.at(2, 2) = mass22.at(3, 3) = fac4; // D
1463  mass23.at(1, 1) = fac5 * m.at(1);
1464  mass23.at(2, 1) = fac5 * m.at(2);
1465  mass23.at(3, 1) = fac5 * m.at(3); // E
1466  mass33.at(1, 1) = fac6 * m.dotProduct(m); // F
1467  mass21.beTranspositionOf(mass12);
1468  mass31.beTranspositionOf(mass13);
1469  mass32.beTranspositionOf(mass23);
1470  //mass.symmetrized();
1471 
1472  double dV = this->computeVolumeAroundLayer(gp, layer);
1473  double rho = mat->give('d', gp);
1474 
1475  FloatMatrix M11temp, M12temp, M13temp, M22temp, M23temp, M33temp;
1476  this->computeTripleProduct(M11temp, N11, mass11, N11);
1477  this->computeTripleProduct(M12temp, N11, mass12, N22);
1478  this->computeTripleProduct(M13temp, N11, mass13, N33);
1479  this->computeTripleProduct(M22temp, N22, mass22, N22);
1480  this->computeTripleProduct(M23temp, N22, mass23, N33);
1481  this->computeTripleProduct(M33temp, N33, mass33, N33);
1482  M11.add(0.25 * rho * dV, M11temp);
1483  M12.add(0.25 * rho * dV, M12temp);
1484  M13.add(0.25 * rho * dV, M13temp);
1485  M22.add(0.25 * rho * dV, M22temp);
1486  M23.add(0.25 * rho * dV, M23temp);
1487  M33.add(0.25 * rho * dV, M33temp);
1488  }
1489 
1490 
1491  answer.resize(ndofs, ndofs);
1492  answer.zero();
1493 
1494  const IntArray &ordering_phibar = this->giveOrdering(Midplane);
1495  const IntArray &ordering_m = this->giveOrdering(Director);
1496  const IntArray &ordering_gam = this->giveOrdering(InhomStrain);
1497  answer.assemble(M11, ordering_phibar, ordering_phibar);
1498  answer.assemble(M12, ordering_phibar, ordering_m);
1499  answer.assemble(M13, ordering_phibar, ordering_gam);
1500  answer.assemble(M22, ordering_m, ordering_m);
1501  answer.assemble(M23, ordering_m, ordering_gam);
1502  answer.assemble(M33, ordering_gam, ordering_gam);
1503 
1504  FloatMatrix M21, M31, M32;
1505  M21.beTranspositionOf(M12);
1506  M31.beTranspositionOf(M13);
1507  M32.beTranspositionOf(M23);
1508  answer.assemble(M21, ordering_m, ordering_phibar);
1509  answer.assemble(M31, ordering_gam, ordering_phibar);
1510  answer.assemble(M32, ordering_gam, ordering_m);
1511  answer.symmetrized();
1512 
1513  }
1514 #endif
1515 }
1516 
1517 void Shell7BaseXFEM :: computeBoundaryEdgeLoadVector(FloatArray &answer, BoundaryLoad *load, int boundary, CharType type, ValueModeType mode, TimeStep *tStep, bool global)
1518 {
1519  //@todo present formulation returns edge vector localized into element vector, efficient implementation can return only dofs related to edge (bp)
1520  answer.clear();
1521  if ( type != ExternalForcesVector ) {
1522  return;
1523  }
1524 
1525  BoundaryLoad *edgeLoad = dynamic_cast< BoundaryLoad * >(load);
1526  if ( edgeLoad ) {
1527  answer.resize( this->computeNumberOfDofs() );
1528  answer.zero();
1529 
1530  // Continuous part
1531  FloatArray fT;
1532  Shell7Base :: computeTractionForce(fT, boundary, edgeLoad, tStep, mode, true);
1533 
1534  IntArray activeDofs, ordering;
1535  this->computeOrderingArray(ordering, activeDofs, NULL);
1536  answer.assemble(fT, ordering);
1537 
1538  FloatArray componentsTemp, coordsTemp(1);
1539  coordsTemp.at(1) = 0.0;
1540  edgeLoad->computeValueAt(componentsTemp, tStep, coordsTemp, VM_Total);
1542  //double xi = 0.0; // defaults to geometric midplane
1543  //if ( componentsTemp.giveSize() == 8 ) {
1544  // xi = componentsTemp.at(8); // use the 8th component to store the-xi coord where the load acts
1545  //}
1546 
1547  // Disccontinuous part
1548  FloatArray temp, tempRed;
1549  for ( int i = 1; i <= this->xMan->giveNumberOfEnrichmentItems(); i++ ) { // Only one is supported at the moment
1550 
1551  EnrichmentItem *ei = this->xMan->giveEnrichmentItem(i);
1552  if ( ei->isElementEnriched(this) ) {
1553  this->computeEnrTractionForce(temp, boundary, edgeLoad, tStep, mode, ei);
1554  this->computeOrderingArray(ordering, activeDofs, ei);
1555  tempRed.beSubArrayOf(temp, activeDofs);
1556  answer.assemble(tempRed, ordering);
1557  }
1558  }
1559  return;
1560  } else {
1561  OOFEM_ERROR("load type not supported");
1562  return;
1563  }
1564 }
1565 
1566 
1567 void
1569 {
1570 #if 0
1571  int approxOrder = edgeLoad->giveApproxOrder() + this->giveInterpolation()->giveInterpolationOrder();
1572  int numberOfGaussPoints = ( int ) ceil( ( approxOrder + 1. ) / 2. );
1573  GaussIntegrationRule iRule(1, this, 1, 1);
1574  iRule.SetUpPointsOnLine(numberOfGaussPoints, _Unknown);
1575 
1576  GaussPoint *gp;
1577 
1578  FloatMatrix N, Q;
1579  FloatArray fT(7), components, lCoords;
1580  Load :: CoordSystType coordSystType = edgeLoad->giveCoordSystMode();
1581 
1582  FloatArray Nftemp(21), Nf(21);
1583  Nf.zero();
1584  for ( int i = 0; i < iRule.giveNumberOfIntegrationPoints(); i++ ) {
1585  gp = iRule.getIntegrationPoint(i);
1586  const FloatArray &lCoords = gp->giveNaturalCoordinates();
1587 
1588  edgeLoad->computeValueAt(components, tStep, lCoords, mode);
1589  this->edgeComputeEnrichedNmatrixAt(lCoords, N, ei, iEdge);
1590 
1591  if ( coordSystType == Load :: CST_UpdatedGlobal ) {
1592 
1593  // Updated global coord system
1594  FloatMatrix gcov;
1595  this->edgeEvalEnrCovarBaseVectorsAt(lCoords, iEdge, gcov, tStep, ei);
1596  Q.beTranspositionOf(gcov);
1597 
1598  FloatArray distrForces, distrMoments, t1, t2;
1599  distrForces = { components.at(1), components.at(2), components.at(3) };
1600  distrMoments = { components.at(4), components.at(5), components.at(6) };
1601  t1.beTProductOf(Q, distrForces);
1602  t2.beTProductOf(Q, distrMoments);
1603  fT.addSubVector(t1,1);
1604  fT.addSubVector(t2,4);
1605  fT.at(7) = components.at(7); // don't do anything with the 'gamma'-load
1606 
1607  } else if( coordSystType == Load :: CST_Global ) {
1608  // Undeformed global coord system
1609  for ( int i = 1; i <= 7; i++) {
1610  fT.at(i) = components.at(i);
1611  }
1612  } else {
1613  OOFEM_ERROR("ModShell7Base :: computeTractionForce - does not support local coordinate system");
1614  }
1615 
1616  double dL = this->edgeComputeLengthAround(gp, iEdge);
1617 
1618  Nftemp.beTProductOf(N, fT*dL);
1619  Nf.add(Nftemp);
1620  }
1621 
1622  IntArray mask;
1623  this->giveEdgeDofMapping(mask, iEdge);
1625  answer.zero();
1626  answer.assemble(Nf, mask);
1627 
1628  answer.printYourself("f_ext old");
1629 #else
1630 
1631  int approxOrder = edgeLoad->giveApproxOrder() + this->giveInterpolation()->giveInterpolationOrder();
1632  int numberOfGaussPoints = ( int ) ceil( ( approxOrder + 1. ) / 2. );
1633  GaussIntegrationRule iRule(1, this, 1, 1);
1634  iRule.SetUpPointsOnLine(numberOfGaussPoints, _Unknown);
1635 
1636  FloatMatrix N, Q;
1637  FloatArray fT(7), components, lCoords, gCoords, Nf;
1638  Load :: CoordSystType coordSystType = edgeLoad->giveCoordSystMode();
1639 
1641  answer.zero();
1643  Nf.zero();
1644  for ( GaussPoint *gp : iRule ) {
1645  const FloatArray &lCoordsEdge = gp->giveNaturalCoordinates();
1646 
1647  this->fei->edgeLocal2global( gCoords, iEdge, lCoordsEdge, FEIElementGeometryWrapper(this) );
1648  this->fei->global2local( lCoords, gCoords, FEIElementGeometryWrapper(this) );
1649 
1650 
1651  edgeLoad->computeValueAt(components, tStep, lCoordsEdge, mode);
1652  if( components.giveSize() == 8 ) {
1653  lCoords.at(3) = components.at(8);
1654  }
1655  this->computeEnrichedNmatrixAt(lCoords, N, ei);
1656 
1657  if ( coordSystType == Load :: CST_UpdatedGlobal ) {
1658 
1659  // Updated global coord system
1660  FloatMatrix gcov;
1661  this->edgeEvalEnrCovarBaseVectorsAt(lCoordsEdge, iEdge, gcov, tStep, ei);
1662  Q.beTranspositionOf(gcov);
1663 
1664  FloatArray distrForces, distrMoments, t1, t2;
1665  distrForces = { components.at(1), components.at(2), components.at(3) };
1666  distrMoments = { components.at(4), components.at(5), components.at(6) };
1667  t1.beTProductOf(Q, distrForces);
1668  t2.beTProductOf(Q, distrMoments);
1669  fT.addSubVector(t1,1);
1670  fT.addSubVector(t2,4);
1671  fT.at(7) = components.at(7); // don't do anything with the 'gamma'-load
1672 
1673  } else if( coordSystType == Load :: CST_Global ) {
1674  // Undeformed global coord system
1675  for ( int i = 1; i <= 7; i++) {
1676  fT.at(i) = components.at(i);
1677  }
1678  } else {
1679  OOFEM_ERROR("ModShell7Base :: computeTractionForce - does not support local coordinate system");
1680  }
1681 
1682  double dL = this->edgeComputeLengthAround(gp, iEdge);
1683 
1684  //answer.plusProduct(N, fT, dL);
1685  Nf.plusProduct(N, fT, dL);
1686  }
1687  answer.assemble(Nf, this->giveOrderingDofTypes() );
1688 #endif
1689 }
1690 
1691 void
1693 {
1694  // Evaluates the covariant base vectors in the current configuration for an edge
1695  double zeta = lcoords.at(3);
1696 
1697  FloatArray solVecEdge;
1698  FloatMatrix B;
1699  IntArray edgeNodes;
1700  this->fei->computeLocalEdgeMapping(edgeNodes, iedge);
1701  this->edgeComputeEnrichedBmatrixAt(lcoords, B, ei, iedge);
1702  this->edgeGiveUpdatedSolutionVector(solVecEdge, iedge, tStep);
1703 
1704  FloatArray genEpsEdge; // generalized strain
1705  genEpsEdge.beProductOf(B, solVecEdge); // [dxdxi, dmdxi, m, dgamdxi, gam]^T
1706 
1707  FloatArray dxdxi, m, dmdxi;
1708  dxdxi = { genEpsEdge.at(1), genEpsEdge.at(2), genEpsEdge.at(3) };
1709  dmdxi = { genEpsEdge.at(4), genEpsEdge.at(5), genEpsEdge.at(6) };
1710  m = { genEpsEdge.at(7), genEpsEdge.at(8), genEpsEdge.at(9) };
1711  double dgamdxi = genEpsEdge.at(10);
1712  double gam = genEpsEdge.at(11);
1713 
1714  double fac1 = ( zeta + 0.5 * gam * zeta * zeta );
1715  double fac2 = ( 0.5 * zeta * zeta );
1716  double fac3 = ( 1.0 + zeta * gam );
1717 
1718  FloatArray g1, g2, g3;
1719  g2 = dxdxi + fac1*dmdxi + fac2*dgamdxi*m; // base vector along the edge
1720  g3 = fac3*m; // director field
1721 
1722  g2.normalize();
1723  g3.normalize();
1724  g1.beVectorProductOf(g2, g3);
1725  g1.normalize();
1726  gcov = {g1, g2, g3};
1727 }
1728 
1729 
1730 // Surface
1731 /*
1732 void
1733 Shell7BaseXFEM :: computeSurfaceLoadVectorAt(FloatArray &answer, Load *load,
1734  int iSurf, TimeStep *tStep, ValueModeType mode)
1735 {
1736  BoundaryLoad *surfLoad = dynamic_cast< BoundaryLoad * >(load);
1737 
1738  if ( surfLoad ) {
1739  answer.resize( this->giveNumberOfDofs() );
1740  answer.zero();
1741 
1742  // Continuous part
1743  FloatArray solVec, force;
1744  this->giveUpdatedSolutionVector(solVec, tStep);
1745  this->computePressureForce(force, solVec, iSurf, surfLoad, tStep, mode);
1746 
1747  IntArray activeDofs, ordering, eiDofIdArray;
1748  this->computeOrderingArray(ordering, activeDofs, NULL);
1749  answer.assemble(force, ordering);
1750 
1751  // Disccontinuous part
1752 #if 1
1753  FloatArray solVecD;
1754  double xi = 0.0; // defaults to geometric midplane
1755  if ( ConstantPressureLoad * pLoad = dynamic_cast< ConstantPressureLoad * >(load) ) {
1756  xi = pLoad->giveLoadOffset();
1757  }
1758  else if ( ConstantSurfaceLoad * sLoad = dynamic_cast< ConstantSurfaceLoad * >( load ) ) {
1759  xi = sLoad->giveLoadOffset();
1760  //printf("sLoad xi = %e \n",xi);
1761  }
1762  //xi = -1.0;
1763  std :: vector< double > ef;
1764  FloatArray temp, tempRed, lCoords(2);
1765  for ( int i = 1; i <= this->xMan->giveNumberOfEnrichmentItems(); i++ ) {
1766  Delamination *dei = dynamic_cast< Delamination * >( this->xMan->giveEnrichmentItem(i) );
1767  if ( dei != NULL && dei->isElementEnriched(this) ) {
1768  double levelSet = xi - dei->giveDelamXiCoord();
1769  dei->evaluateEnrFuncAt(ef, lCoords, levelSet);
1770  //if (this->giveGlobalNumber() == 10) {printf("xi= %f, levelSet= %f, ef= %f \n",xi,levelSet,ef[0]); }
1771  if ( ef[0] > 0.1 ) {
1772  dei->giveEIDofIdArray(eiDofIdArray);
1773  this->computeDiscSolutionVector(eiDofIdArray, tStep, solVecD);
1774  this->computePressureForce(temp, solVecD, iSurf, surfLoad, tStep, mode);
1775  temp.times(DISC_DOF_SCALE_FAC);
1776  // Assemble
1777  this->computeOrderingArray(ordering, activeDofs, dei);
1778  tempRed.beSubArrayOf(temp, activeDofs);
1779 // if (this->giveGlobalNumber() == 10) {
1780 // ordering.printYourself("ordering");
1781 // activeDofs.printYourself("activeDofs");
1782 // }
1783  answer.assemble(tempRed, ordering);
1784  }
1785  }
1786  }
1787 #endif
1788  return;
1789  } else {
1790  OOFEM_ERROR("load type not supported");
1791  return;
1792  }
1793 }
1794 */
1795 
1796 
1797 // Shifted N and B matrices
1798 void
1800 {
1801  // Returns the enriched and shifted {B} matrix of the receiver, evaluated at gp. Such that
1802  // B*a = [dxbar_dxi, dwdxi, w, dgamdxi, gam]^T, where a is the vector of unknowns
1803 
1804  if ( ei && dynamic_cast< ShellCrack*>(ei) ) {
1805 
1806  int ndofs = Shell7Base :: giveNumberOfDofs();
1807  int ndofs_xm = 3 * this->giveNumberOfDofManagers();
1808  answer.resize(18, ndofs);
1809  answer.zero();
1810  FloatArray N;
1811  FloatMatrix dNdxi;
1812  this->fei->evalN( N, lCoords, FEIElementGeometryWrapper(this) );
1813  this->fei->evaldNdxi( dNdxi, lCoords, FEIElementGeometryWrapper(this) );
1814 
1815  /* 18 18 6
1816  * 6 [B_u 0 0
1817  * 6 0 B_w 0
1818  * 3 0 N_w 0
1819  * 2 0 0 B_gam
1820  * 1 0 0 N_gam]
1821  */
1822 
1823  // Evaluate enrichment function at point given by lcoords
1824 // std :: vector< double > efGP;
1825 // double levelSetGP = this->evaluateLevelSet(lCoords, ei);
1826 // ///TODO : evaluateEnrFuncAt must have an input with only 3 values
1827 // FloatArray lCoords2 = lCoords;
1828 // lCoords2.resizeWithValues(2);
1829 // ei->evaluateEnrFuncAt(efGP, lCoords2, levelSetGP);
1830  int ndofman = this->giveNumberOfDofManagers();
1831 
1832  FloatArray gcoords;
1833  fei->local2global(gcoords, lCoords, FEIElementGeometryWrapper(this) );
1834  //computeGlobalCoordinates(gcoords, lCoords);
1835  gcoords.resizeWithValues(2);
1836 
1837  for ( int i = 1, j = 0; i <= ndofman; i++, j += 3 ) {
1838  if ( !ei->isDofManEnriched( *this->giveDofManager(i) ) ){
1839  continue;
1840  }
1841 
1842  std :: vector< double > efGP;
1843  DofManager *dMan = this->giveDofManager(i);
1844  int nodeInd = dMan->giveGlobalNumber();
1845  ei->evaluateEnrFuncAt(efGP, gcoords, lCoords, nodeInd, *this, N, giveDofManArray());
1846 
1847 
1848  double factor = efGP [ 0 ] - EvaluateEnrFuncInDofMan(i, ei);
1849 
1850  // First column
1851  answer.at(1, 1 + j) = dNdxi.at(i, 1) * factor;
1852  answer.at(2, 2 + j) = dNdxi.at(i, 1) * factor;
1853  answer.at(3, 3 + j) = dNdxi.at(i, 1) * factor;
1854  answer.at(4, 1 + j) = dNdxi.at(i, 2) * factor;
1855  answer.at(5, 2 + j) = dNdxi.at(i, 2) * factor;
1856  answer.at(6, 3 + j) = dNdxi.at(i, 2) * factor;
1857 
1858  // Second column
1859  answer.at(7, ndofs_xm + 1 + j) = dNdxi.at(i, 1) * factor;
1860  answer.at(8, ndofs_xm + 2 + j) = dNdxi.at(i, 1) * factor;
1861  answer.at(9, ndofs_xm + 3 + j) = dNdxi.at(i, 1) * factor;
1862  answer.at(10, ndofs_xm + 1 + j) = dNdxi.at(i, 2) * factor;
1863  answer.at(11, ndofs_xm + 2 + j) = dNdxi.at(i, 2) * factor;
1864  answer.at(12, ndofs_xm + 3 + j) = dNdxi.at(i, 2) * factor;
1865  answer.at(13, ndofs_xm + 1 + j) = N.at(i) * factor;
1866  answer.at(14, ndofs_xm + 2 + j) = N.at(i) * factor;
1867  answer.at(15, ndofs_xm + 3 + j) = N.at(i) * factor;
1868 
1869  // Third column
1870  answer.at(16, ndofs_xm * 2 + 1 + i-1) = dNdxi.at(i, 1) * factor;
1871  answer.at(17, ndofs_xm * 2 + 1 + i-1) = dNdxi.at(i, 2) * factor;
1872  answer.at(18, ndofs_xm * 2 + 1 + i-1) = N.at(i) * factor;
1873  }
1874 
1875 
1876  answer.times( this->evaluateHeavisideXi(lCoords.at(3), static_cast< ShellCrack* >(ei)) );
1877  answer.times(DISC_DOF_SCALE_FAC);
1878 
1879  } else if ( ei && dynamic_cast< Delamination*>(ei) ){
1880  Shell7Base :: computeBmatrixAt(lCoords, answer);
1881  //std :: vector< double > efGP;
1882  //double levelSetGP = this->evaluateLevelSet(lCoords, ei);
1883  //ei->evaluateEnrFuncAt(efGP, lCoords, levelSetGP);
1884  double fac = this->evaluateHeavisideXi(lCoords.at(3), static_cast< Delamination* >(ei) );
1885  answer.times( fac * DISC_DOF_SCALE_FAC );
1886  } else {
1887  Shell7Base :: computeBmatrixAt(lCoords, answer);
1888  }
1889 }
1890 
1891 double
1893 {
1894 
1895  DofManager *dMan = this->giveDofManager(dofManNum);
1896  if ( ei->isDofManEnriched(*dMan) ) {
1897 
1898  int globalNodeInd = dMan->giveGlobalNumber(); // global number in order to pick levelset value in that node
1899  double levelSetNode = 0.0;
1900  ei->evalLevelSetNormalInNode( levelSetNode, globalNodeInd, *(dMan->giveCoordinates()) );
1901  std :: vector< double >efNode;
1902  //const FloatArray &nodePos = * ( dMan->giveCoordinates() );
1903  // evaluateEnrFuncAt requires coords to be size 2
1904  FloatArray nodePos = * ( dMan->giveCoordinates() );
1905  nodePos.resizeWithValues(2);
1906 
1907  FloatArray localCoord;
1908  this->computeLocalCoordinates(localCoord, nodePos);
1909 
1910  //ei->evaluateEnrFuncAt(efNode, nodePos, levelSetNode, globalNodeInd);
1911  ei->evaluateEnrFuncAt(efNode, nodePos, localCoord, globalNodeInd, *this);
1912 
1913  return efNode [ 0 ];
1914  //if( efNode.size() ) {
1915  // return efNode [ 0 ];
1916  //} else {
1917  // return 0.0;
1918  //}
1919  } else {
1920  return 0.0;
1921  }
1922 
1923 }
1924 
1925 
1926 void
1928 {
1929  // Returns the displacement interpolation matrix {N} of the receiver,
1930  // evaluated at gp.
1931 
1932  int ndofs = Shell7Base :: giveNumberOfDofs();
1933  int ndofs_xm = 3 * this->giveNumberOfDofManagers();
1934  answer.resize(7, ndofs);
1935  answer.zero();
1936  FloatArray N;
1937  this->fei->evalN( N, lCoords, FEIElementGeometryWrapper(this) );
1938 
1939  /* nno*3 nno*3 nno
1940  * 3 [N_x 0 0
1941  * 3 0 N_m 0
1942  * 1 0 0 N_gmm ]
1943  */
1944 
1945  if ( ei && dynamic_cast< Crack*>(ei) ) {
1946 
1947  FloatArray gcoords;
1948  this->computeGlobalCoordinates(gcoords, lCoords);
1949 
1950  for ( int i = 1, j = 0; i <= this->giveNumberOfDofManagers(); i++, j += 3 ) {
1951  if ( !ei->isDofManEnriched( *this->giveDofManager(i) ) ){
1952  continue;
1953  }
1954 
1955  std :: vector< double > efGP;
1956  int nodeInd = giveDofManager(i)->giveGlobalNumber();
1957  ei->evaluateEnrFuncAt(efGP, gcoords, lCoords, nodeInd, *this, N, giveDofManArray());
1958 
1959 
1960  double factor = N.at(i) * ( efGP [ 0 ] - EvaluateEnrFuncInDofMan(i, ei) );
1961 
1962  answer.at(1, 1 + j) = factor;
1963  answer.at(2, 2 + j) = factor;
1964  answer.at(3, 3 + j) = factor;
1965  answer.at(4, ndofs_xm + 1 + j) = factor;
1966  answer.at(5, ndofs_xm + 2 + j) = factor;
1967  answer.at(6, ndofs_xm + 3 + j) = factor;
1968  answer.at(7, ndofs_xm * 2 + i) = factor;
1969  }
1970 
1971  answer.times( this->evaluateHeavisideXi(lCoords.at(3), static_cast< ShellCrack* >(ei)) );
1972  answer.times(DISC_DOF_SCALE_FAC);
1973 
1974  } else if ( ei && dynamic_cast< Delamination*>(ei) ) {
1975  Shell7Base :: computeNmatrixAt(lCoords, answer);
1976  //std :: vector< double > efGP;
1977  //double levelSetGP = this->evaluateLevelSet(lCoords, ei);
1978  //ei->evaluateEnrFuncAt(efGP, lCoords, levelSetGP);
1979  double fac = this->evaluateHeavisideXi(lCoords.at(3), static_cast< Delamination* >(ei) );
1980  answer.times( fac * DISC_DOF_SCALE_FAC );
1981  } else {
1982  Shell7Base :: computeNmatrixAt(lCoords, answer);
1983  }
1984 }
1985 
1986 
1987 
1988 void
1990 {
1991  // Returns the displacement interpolation matrix {N} of the receiver
1992  // evaluated at gaussPoint along one edge.
1993  //TODO Add input for which edge!
1994 
1995  answer.resize( 7, this->giveNumberOfEdgeDofs() );
1996  answer.zero();
1997 
1998  FloatArray N;
1999  this->fei->edgeEvalN( N, 1, lCoords, FEIElementGeometryWrapper(this) );
2000 
2001  /* 9 9 3
2002  * 3 [N_x 0 0
2003  * 3 0 N_m 0
2004  * 1 0 0 N_gmm ]
2005  */
2006  int ndofs_xm = this->giveNumberOfEdgeDofs() / 7 * 3; // numEdgeNodes * 3 dofs
2007 
2008  if ( ei && dynamic_cast< Crack*>(ei) ) {
2009 // std :: vector< double > efGP;
2010 // double levelSetGP = this->evaluateLevelSet(lcoords, ei);
2011 // ei->evaluateEnrFuncAt(efGP, lcoords, levelSetGP);
2012 
2013  FloatArray gcoords;
2014 // this->computeGlobalCoordinates(gcoords, lCoords);
2015  fei->edgeLocal2global(gcoords, 1, lCoords, FEIElementGeometryWrapper(this));
2016 
2017  FloatArray elLocCoord;
2018  this->computeLocalCoordinates(elLocCoord, gcoords);
2019 
2020  gcoords.resizeWithValues(2);
2021  elLocCoord.resizeWithValues(2);
2022 
2023  for ( int i = 1, j = 0; i <= this->giveNumberOfEdgeDofManagers(); i++, j += 3 ) {
2024  //if ( !ei->isDofManEnriched(this->giveDofManager(i)) ){
2025  // continue;
2026  //}
2027 
2028  std :: vector< double > efGP;
2029  int nodeInd = giveDofManager(i)->giveGlobalNumber();
2030  ei->evaluateEnrFuncAt(efGP, gcoords, elLocCoord, nodeInd, *this, N, giveDofManArray());
2031 
2032  double factor = efGP [ 0 ] - EvaluateEnrFuncInDofMan(i, ei);
2033  answer.at(1, 1 + j) = N.at(i) * factor;
2034  answer.at(2, 2 + j) = N.at(i) * factor;
2035  answer.at(3, 3 + j) = N.at(i) * factor;
2036  answer.at(4, ndofs_xm + 1 + j) = N.at(i) * factor;
2037  answer.at(5, ndofs_xm + 2 + j) = N.at(i) * factor;
2038  answer.at(6, ndofs_xm + 3 + j) = N.at(i) * factor;
2039  answer.at(7, ndofs_xm * 2 + i) = N.at(i) * factor;
2040  }
2041  answer.times( this->evaluateHeavisideXi(0.0, static_cast< ShellCrack* >(ei)) );
2042  answer.times(DISC_DOF_SCALE_FAC);
2043 
2044  } else if ( ei && dynamic_cast< Delamination*>(ei) ) {
2045  Shell7Base :: edgeComputeNmatrixAt(lCoords, answer);
2046  //std :: vector< double > efGP;
2047  //double levelSetGP = this->edgeEvaluateLevelSet(lCoords, ei);
2048  //ei->evaluateEnrFuncAt(efGP, lCoords, levelSetGP);
2049  double fac = this->evaluateHeavisideXi(0.0, static_cast< Delamination* >(ei) );
2050  answer.times( fac * DISC_DOF_SCALE_FAC );
2051  } else {
2052  Shell7Base :: edgeComputeNmatrixAt(lCoords, answer);
2053  }
2054 
2055 }
2056 
2057 
2058 void
2060 {
2061 /* Returns the matrix {B} of the receiver, evaluated at gp. Such that
2062  * B*a = [dxbar_dxi, dwdxi, w, dgamdxi, gam]^T, where a is the vector of unknowns
2063  */
2064 
2065  answer.resize( 11, this->giveNumberOfEdgeDofs() );
2066  answer.zero();
2067  FloatArray N, dNdxi;
2068 
2069 
2070 
2071  if ( ei && dynamic_cast< Crack*>(ei) ) {
2072 
2073  this->fei->edgeEvalN( N, 1, lCoords, FEIElementGeometryWrapper(this) );
2074  int iedge = 0;
2075  this->fei->edgeEvaldNdxi( dNdxi, iedge, lCoords, FEIElementGeometryWrapper(this) );
2076 
2077  /*
2078  * 3 [B_u 0 0
2079  * 3 0 B_w 0
2080  * 3 0 N_w 0
2081  * 1 0 0 B_gam
2082  * 1 0 0 N_gam]
2083  */
2084 
2085  // Evaluate enrichment function at point given by lcoords
2086 // std :: vector< double > efGP;
2087 // double levelSetGP = this->evaluateLevelSet(lcoords, ei);
2088 // ei->evaluateEnrFuncAt(efGP, lcoords, levelSetGP);
2089 
2090  FloatArray gcoords;
2091  this->computeGlobalCoordinates(gcoords, lCoords);
2092 
2093  int ndofs_xm = this->giveNumberOfEdgeDofs() / 7 * 3; // numEdgeNodes * 3 dofs
2094  int ndofman = this->giveNumberOfEdgeDofManagers();
2095  // First row
2096  for ( int i = 1, j = 0; i <= ndofman; i++, j += 3 ) {
2097 
2098  std :: vector< double > efGP;
2099  int nodeInd = giveDofManager(i)->giveGlobalNumber();
2100  ei->evaluateEnrFuncAt(efGP, gcoords, lCoords, nodeInd, *this, N, giveDofManArray());
2101 
2102  double factor = efGP [ 0 ] - EvaluateEnrFuncInDofMan(i, ei);
2103 
2104  answer.at(1, 1 + j) = dNdxi.at(i) * factor;
2105  answer.at(2, 2 + j) = dNdxi.at(i) * factor;
2106  answer.at(3, 3 + j) = dNdxi.at(i) * factor;
2107 // }
2108 
2109  // Second row
2110 // for ( int i = 1, j = 0; i <= ndofman; i++, j += 3 ) {
2111 
2112 // std :: vector< double > efGP;
2113 // int nodeInd = giveDofManager(i)->giveGlobalNumber();
2114 // ei->evaluateEnrFuncAt(efGP, gcoords, lCoords, nodeInd, *this, N, giveDofManArray());
2115 //
2116 // double factor = efGP [ 0 ] - EvaluateEnrFuncInDofMan(i, ei);
2117 
2118  answer.at(4, ndofs_xm + 1 + j) = dNdxi.at(i) * factor;
2119  answer.at(5, ndofs_xm + 2 + j) = dNdxi.at(i) * factor;
2120  answer.at(6, ndofs_xm + 3 + j) = dNdxi.at(i) * factor;
2121  answer.at(7, ndofs_xm + 1 + j) = N.at(i) * factor;
2122  answer.at(8, ndofs_xm + 2 + j) = N.at(i) * factor;
2123  answer.at(9, ndofs_xm + 3 + j) = N.at(i) * factor;
2124 // }
2125 
2126  // Third row
2127 // for ( int i = 1, j = 0; i <= ndofman; i++, j += 1 ) {
2128 
2129 // std :: vector< double > efGP;
2130 // int nodeInd = giveDofManager(i)->giveGlobalNumber();
2131 // ei->evaluateEnrFuncAt(efGP, gcoords, lCoords, nodeInd, *this, N, giveDofManArray());
2132 //
2133 // double factor = efGP [ 0 ] - EvaluateEnrFuncInDofMan(i, ei);
2134 
2135  answer.at(10, ndofs_xm * 2 + 1 + i-1) = dNdxi.at(i) * factor;
2136  answer.at(11, ndofs_xm * 2 + 1 + i-1) = N.at(i) * factor;
2137  }
2138 
2139  answer.times( this->evaluateHeavisideXi(lCoords.at(3), static_cast< ShellCrack* >(ei)) );
2140  answer.times(DISC_DOF_SCALE_FAC);
2141 
2142  } else if ( ei && dynamic_cast< Delamination*>(ei) ){
2143  Shell7Base :: edgeComputeBmatrixAt(lCoords, answer);
2144  //std :: vector< double > efGP;
2145  //double levelSetGP = this->evaluateLevelSet(lCoords, ei);
2146  //ei->evaluateEnrFuncAt(efGP, lCoords, levelSetGP);
2147  double fac = this->evaluateHeavisideXi(lCoords.at(3), static_cast< Delamination* >(ei) );
2148  answer.times( fac * DISC_DOF_SCALE_FAC );
2149  } else {
2150  Shell7Base :: edgeComputeBmatrixAt(lCoords, answer);
2151  }
2152 
2153 }
2154 
2155 
2156 
2157 
2158 
2159 
2160 // Delamination specific
2161 
2162 
2163 void
2164 Shell7BaseXFEM :: vtkEvalUpdatedGlobalCoordinateAt(const FloatArray &localCoords, int layer, FloatArray &globalCoords, TimeStep *tStep)
2165 {
2166  double zeta = this->giveGlobalZcoord( localCoords );
2167 
2168  // Continuous part
2169  FloatArray solVec;
2170  this->giveUpdatedSolutionVector(solVec, tStep);
2171  FloatArray xc, mc; double gamc=0;
2172  Shell7Base :: giveUnknownsAt(localCoords, solVec, xc, mc, gamc, tStep);
2173  double fac_cont = ( zeta + 0.5 * gamc * zeta * zeta );
2174  globalCoords = xc;
2175  globalCoords.add(fac_cont,mc);
2176 
2177 #if 1
2178  // Discontinuous part
2179  FloatArray solVecD, xd, md, xtemp(3);
2180  double gamd = 0;
2181  for ( int i = 1; i <= this->xMan->giveNumberOfEnrichmentItems(); i++ ) {
2182  EnrichmentItem *ei = this->xMan->giveEnrichmentItem(i);
2183 
2184  if ( ei->isElementEnriched(this) ) {
2185  IntArray eiDofIdArray;
2186  ei->giveEIDofIdArray(eiDofIdArray);
2187  this->computeDiscSolutionVector(eiDofIdArray, tStep, solVecD);
2188  this->giveDisUnknownsAt(localCoords, ei, solVecD, xd, md, gamd, tStep);
2189  double fac_disc = ( zeta + 0.5 * gamd * zeta * zeta );
2190  xtemp = xd;
2191  xtemp.add(fac_disc,md);
2192  globalCoords.add(xtemp);
2193  }
2194 
2195  }
2196 #endif
2197 }
2198 
2199 
2200 void
2202 {
2203  // returns the unknowns evaluated at a point (xi1, xi2, xi3)
2204  FloatArray vec;
2205  FloatMatrix NEnr;
2206  this->computeEnrichedNmatrixAt(lcoords, NEnr, ei);
2207  vec.beProductOf(NEnr, solVec);
2208  x = {vec.at(1), vec.at(2), vec.at(3)};
2209  m = {vec.at(4), vec.at(5), vec.at(6)};
2210  gam = vec.at(7);
2211 
2212 }
2213 
2214 
2215 
2216 void
2217 Shell7BaseXFEM :: giveCompositeExportData(std::vector< VTKPiece > &vtkPieces, IntArray &primaryVarsToExport, IntArray &internalVarsToExport, IntArray cellVarsToExport, TimeStep *tStep )
2218 {
2219  vtkPieces.resize(1);
2220  this->giveShellExportData(vtkPieces[0], primaryVarsToExport, internalVarsToExport, cellVarsToExport, tStep );
2221  //this->giveCZExportData(vtkPieces[1], primaryVarsToExport, internalVarsToExport, cellVarsToExport, tStep );
2222 
2223 }
2224 
2225 
2226 
2227 void
2228 Shell7BaseXFEM :: giveCompositeExportData(VTKPiece &vtkPiece, IntArray &primaryVarsToExport, IntArray &internalVarsToExport, IntArray cellVarsToExport, TimeStep *tStep )
2229 {
2230 
2231  this->giveCZExportData(vtkPiece, primaryVarsToExport, internalVarsToExport, cellVarsToExport, tStep );
2232  //this->giveShellExportData(vtkPiece, primaryVarsToExport, internalVarsToExport, cellVarsToExport, tStep );
2233 
2234 }
2235 
2236 void
2237 Shell7BaseXFEM :: giveShellExportData(VTKPiece &vtkPiece, IntArray &primaryVarsToExport, IntArray &internalVarsToExport, IntArray cellVarsToExport, TimeStep *tStep )
2238 {
2239  int numSubCells = 1;
2240 
2241 
2242  int numLayers = this->layeredCS->giveNumberOfLayers();
2243  //int numCells = numLayers * numSubCells;
2244  // Go through each layer and count the number of subcells
2245  int numCells = 0;
2246  for ( int i = 1; i <= numLayers; i++ ) {
2247  numCells += this->numSubDivisionsArray.at(i);
2248  }
2249 
2250  int numCellNodes = 15; // quadratic wedge
2251 
2252  int numTotalNodes = numCellNodes*numCells;
2253 
2254  vtkPiece.setNumberOfCells(numCells);
2255  vtkPiece.setNumberOfNodes(numTotalNodes);
2256 
2257  std::vector <FloatArray> nodeCoords;
2258  int val = 1;
2259  int offset = 0;
2260  int currentCell = 1;
2261  IntArray nodes(numCellNodes);
2262 
2263  // Compute fictious node coords
2264  int nodeNum = 1;
2265  for ( int layer = 1; layer <= numLayers; layer++ ) {
2266 
2267  numSubCells = (int)this->numSubDivisionsArray[layer - 1];
2268  for ( int subCell = 1; subCell <= numSubCells; subCell++ ) {
2269 
2270  // Node coordinates
2271  if ( numSubCells == 1 ) {
2273  } else {
2274  this->giveFictiousNodeCoordsForExport(nodeCoords, layer, subCell);
2275  }
2276 
2277  for ( int node = 1; node <= numCellNodes; node++ ) {
2278  vtkPiece.setNodeCoords(nodeNum, nodeCoords[node-1] );
2279  nodeNum += 1;
2280  }
2281 
2282  // Connectivity
2283  for ( int i = 1; i <= numCellNodes; i++ ) {
2284  nodes.at(i) = val++;
2285  }
2286  vtkPiece.setConnectivity(currentCell, nodes);
2287 
2288  // Offset
2289  offset += numCellNodes;
2290  vtkPiece.setOffset(currentCell, offset);
2291 
2292  // Cell types
2293 
2294  vtkPiece.setCellType(currentCell, 26); // Quadratic wedge
2295 
2296  currentCell++;
2297  }
2298  }
2299 
2300 
2301 
2302 
2303  // Export nodal variables from primary fields
2304  vtkPiece.setNumberOfPrimaryVarsToExport(primaryVarsToExport.giveSize(), numTotalNodes);
2305 
2306  std::vector<FloatArray> updatedNodeCoords;
2307  FloatArray u(3);
2308  std::vector<FloatArray> values;
2309  for ( int fieldNum = 1; fieldNum <= primaryVarsToExport.giveSize(); fieldNum++ ) {
2310 
2311 // if ( recoverStress ) {
2312 // // Recover shear stresses
2313 // //printf("Shell7BaseXFEM: recover shear stress function \n");
2314 // this->recoverShearStress(tStep);
2315 // }
2316 
2317  UnknownType type = ( UnknownType ) primaryVarsToExport.at(fieldNum);
2318  nodeNum = 1;
2319  currentCell = 1;
2320  for ( int layer = 1; layer <= numLayers; layer++ ) {
2321 
2322  numSubCells = (int)this->numSubDivisionsArray[layer - 1];
2323  for ( int subCell = 1; subCell <= numSubCells; subCell++ ) {
2324 
2325  if ( type == DisplacementVector ) { // compute displacement as u = x - X
2326  if ( numSubCells == 1 ) {
2328  this->giveFictiousUpdatedNodeCoordsForExport(updatedNodeCoords, layer, tStep, 0);
2329  } else {
2330  this->giveFictiousNodeCoordsForExport(nodeCoords, layer, subCell);
2331  this->giveFictiousUpdatedNodeCoordsForExport(updatedNodeCoords, layer, tStep, subCell);
2332  }
2333  for ( int j = 1; j <= numCellNodes; j++ ) {
2334  u = updatedNodeCoords[j-1];
2335  u.subtract(nodeCoords[j-1]);
2336  vtkPiece.setPrimaryVarInNode(fieldNum, nodeNum, u);
2337  nodeNum += 1;
2338  }
2339 
2340  } else {
2341  NodalRecoveryMI_recoverValues(values, layer, ( InternalStateType ) 1, tStep); // does not work well - fix
2342  for ( int j = 1; j <= numCellNodes; j++ ) {
2343  vtkPiece.setPrimaryVarInNode(fieldNum, nodeNum, values[j-1]);
2344  nodeNum += 1;
2345  }
2346  }
2347 
2348  currentCell++;
2349  }
2350  }
2351  }
2352 
2353 
2354 
2355  // Export nodal variables from internal fields
2356 
2357  vtkPiece.setNumberOfInternalVarsToExport( internalVarsToExport.giveSize(), numTotalNodes );
2358  for ( int fieldNum = 1; fieldNum <= internalVarsToExport.giveSize(); fieldNum++ ) {
2359  InternalStateType type = ( InternalStateType ) internalVarsToExport.at(fieldNum);
2360  nodeNum = 1;
2361 
2362  //int currentCell = 1;
2363  for ( int layer = 1; layer <= numLayers; layer++ ) {
2364  numSubCells = (int)this->numSubDivisionsArray[layer - 1];
2365 
2366  for ( int subCell = 1; subCell <= numSubCells; subCell++ ) {
2367  recoverValuesFromIP(values, layer, type, tStep);
2368 
2369  for ( int j = 1; j <= numCellNodes; j++ ) {
2370  vtkPiece.setInternalVarInNode( fieldNum, nodeNum, values[j-1] );
2371  //ZZNodalRecoveryMI_recoverValues(el.nodeVars[fieldNum], layer, type, tStep);
2372  nodeNum += 1;
2373  }
2374  }
2375  }
2376  }
2377 
2378 
2379  // Export cell variables
2380  FloatArray average;
2381  vtkPiece.setNumberOfCellVarsToExport(cellVarsToExport.giveSize(), numCells);
2382  for ( int i = 1; i <= cellVarsToExport.giveSize(); i++ ) {
2383  InternalStateType type = ( InternalStateType ) cellVarsToExport.at(i);
2385  currentCell = 1;
2386  for ( int layer = 1; layer <= numLayers; layer++ ) {
2387  numSubCells = (int)this->numSubDivisionsArray[layer - 1];
2388  for ( int subCell = 1; subCell <= numSubCells; subCell++ ) {
2389  std :: unique_ptr< IntegrationRule > &iRuleL = integrationRulesArray [ layer - 1 ];
2390  VTKXMLExportModule :: computeIPAverage(average, iRuleL.get(), this, type, tStep);
2391  if ( valueType == ISVT_TENSOR_S3 ) {
2392  vtkPiece.setCellVar(i, currentCell, convV6ToV9Stress(average) );
2393  } else {
2394  vtkPiece.setCellVar(i, currentCell, average);
2395  }
2396  currentCell += 1;
2397  }
2398  }
2399 
2400  }
2401 
2402 
2403 
2404 
2405 #if 1
2406 
2407 
2408  // Export of XFEM related quantities
2409  XfemManager *xFemMan = this->xMan;
2410  int nEnrIt = xFemMan->giveNumberOfEnrichmentItems();
2411 
2412  IntArray wedgeToTriMap;
2413  // For each node in the wedge take the value from the triangle node given by the map below
2414  wedgeToTriMap = { 1, 2, 3, 1, 2, 3, 4, 5, 6, 4, 5, 6, 1, 2, 3 };
2415 
2416  vtkPiece.setNumberOfInternalXFEMVarsToExport(xFemMan->vtkExportFields.giveSize(), nEnrIt, numTotalNodes);
2417  for ( int field = 1; field <= xFemMan->vtkExportFields.giveSize(); field++ ) {
2418  XFEMStateType xfemstype = ( XFEMStateType ) xFemMan->vtkExportFields [ field - 1 ];
2419 
2420  for ( int enrItIndex = 1; enrItIndex <= nEnrIt; enrItIndex++ ) {
2421  EnrichmentItem *ei = xFemMan->giveEnrichmentItem(enrItIndex);
2422  nodeNum = 1;
2423  for ( int layer = 1; layer <= numLayers; layer++ ) {
2424  FloatMatrix localNodeCoords;
2425 
2426  numSubCells = (int)this->numSubDivisionsArray[layer - 1];
2427  for ( int subCell = 1; subCell <= numSubCells; subCell++ ) {
2428  FloatArray nodeLocalXi1Coords, nodeLocalXi2Coords, nodeLocalXi3Coords, nodeLocalXi3CoordsMapped;
2429  if ( numSubCells == 1) {
2430  this->interpolationForExport.giveLocalNodeCoords(localNodeCoords);
2431  } else {
2432  giveLocalNodeCoordsForExport(nodeLocalXi1Coords, nodeLocalXi2Coords, nodeLocalXi3Coords, subCell, layer, localNodeCoords);
2433  }
2434  mapXi3FromLocalToShell(nodeLocalXi3CoordsMapped, nodeLocalXi3Coords, layer);
2435  for ( int nodeIndx = 1; nodeIndx <= numCellNodes; nodeIndx++ ) {
2436 
2437  FloatArray lCoords;
2438  //lCoords.setValues(3, nodeLocalXi1Coords.at(nodeIndx), nodeLocalXi2Coords.at(nodeIndx), nodeLocalXi3CoordsMapped.at(nodeIndx));
2439  lCoords.beColumnOf(localNodeCoords, nodeIndx);
2440  Node *node = this->giveNode( wedgeToTriMap.at(nodeIndx) );
2441  FloatArray valueArray;
2442  //const FloatArray *val = NULL;
2443  if ( xfemstype == XFEMST_LevelSetPhi ) {
2444  valueArray.resize(1);
2445  //val = & valueArray;
2446  //ei->evalLevelSetNormalInNode( valueArray.at(1), node->giveNumber() );
2447  valueArray.at(1) = this->evaluateLevelSet(lCoords, ei);
2448  } else if ( xfemstype == XFEMST_LevelSetGamma ) {
2449  valueArray.resize(1);
2450  //val = & valueArray;
2451  ei->evalLevelSetTangInNode( valueArray.at(1), node->giveNumber(), node->giveNodeCoordinates() );
2452  } else if ( xfemstype == XFEMST_NodeEnrMarker ) {
2453  valueArray.resize(1);
2454  //val = & valueArray;
2455  ei->evalNodeEnrMarkerInNode( valueArray.at(1), node->giveNumber() );
2456  } else {
2457  //OOFEM_WARNING2("VTKXMLExportModule::getNodalVariableFromXFEMST: invalid data in node %d", inode);
2458  }
2459 
2460  vtkPiece.setInternalXFEMVarInNode(field, enrItIndex, nodeNum, valueArray);
2461  nodeNum += 1;
2462  }
2463  }
2464  }
2465  }
2466  }
2467 #endif
2468 
2469 
2470 }
2471 
2472 
2473 void
2474 Shell7BaseXFEM :: giveFictiousNodeCoordsForExport(std::vector<FloatArray> &nodes, int layer, int subCell)
2475 {
2476 
2477  // compute fictious node coords
2478  FloatArray nodeLocalXi1Coords, nodeLocalXi2Coords, nodeLocalXi3Coords;
2479  FloatMatrix localNodeCoords;
2480  // need to return local coordinates corresponding to the nodes of the sub triangles
2481  giveLocalNodeCoordsForExport(nodeLocalXi1Coords, nodeLocalXi2Coords, nodeLocalXi3Coords, subCell, layer, localNodeCoords);
2482 
2483  //this->interpolationForExport.giveLocalNodeCoords(localNodeCoords);
2484 
2485  nodes.resize(localNodeCoords.giveNumberOfColumns());
2486  for ( int i = 1; i <= localNodeCoords.giveNumberOfColumns(); i++ ){
2487  FloatArray localCoords(3);
2488  localCoords.at(1) = nodeLocalXi1Coords.at(i);
2489  localCoords.at(2) = nodeLocalXi2Coords.at(i);
2490  localCoords.at(3) = nodeLocalXi3Coords.at(i);
2492  localCoords.beColumnOf(localNodeCoords,i);
2493 
2494  this->vtkEvalInitialGlobalCoordinateAt(localCoords, layer, nodes[i-1]);
2495  }
2496 
2497 }
2498 
2499 
2500 void
2501 Shell7BaseXFEM :: giveFictiousCZNodeCoordsForExport(std::vector<FloatArray> &nodes, int layer, int subCell)
2502 {
2503 
2504  // compute fictious node coords
2505  FloatArray nodeLocalXi1Coords, nodeLocalXi2Coords, nodeLocalXi3Coords;
2506  FloatMatrix localNodeCoords;
2507  // need to return local coordinates corresponding to the nodes of the sub triangles
2508  giveLocalCZNodeCoordsForExport(nodeLocalXi1Coords, nodeLocalXi2Coords, nodeLocalXi3Coords, subCell, localNodeCoords);
2509 
2510  nodes.resize(localNodeCoords.giveNumberOfColumns());
2511  for ( int i = 1; i <= localNodeCoords.giveNumberOfColumns(); i++ ){
2512  FloatArray localCoords(3);
2513  localCoords.beColumnOf(localNodeCoords,i);
2514 
2515  this->vtkEvalInitialGlobalCZCoordinateAt(localCoords, layer, nodes[i-1]);
2516  }
2517 
2518 }
2519 
2520 void
2521 Shell7BaseXFEM :: giveFictiousUpdatedNodeCoordsForExport(std::vector<FloatArray> &nodes, int layer, TimeStep *tStep, int subCell)
2522 {
2523  // compute fictious node coords
2524  FloatArray nodeLocalXi1Coords, nodeLocalXi2Coords, nodeLocalXi3Coords;
2525 
2526  FloatMatrix localNodeCoords;
2527 
2528 
2529  if ( subCell == 0) {
2530  this->interpolationForExport.giveLocalNodeCoords(localNodeCoords);
2531  // must get local z-coord in terms of the total thickness not layerwise
2532 
2533  } else {
2534  giveLocalNodeCoordsForExport(nodeLocalXi1Coords, nodeLocalXi2Coords, nodeLocalXi3Coords, subCell, layer, localNodeCoords);
2535  }
2536  nodes.resize(localNodeCoords.giveNumberOfColumns());
2537  for ( int i = 1; i <= localNodeCoords.giveNumberOfColumns(); i++ ){
2538  FloatArray localCoords(3);
2539  localCoords.beColumnOf(localNodeCoords, i);
2540 
2541  // Map local layer cs to local shell cs
2542  double scaleFactor = 0.9999; // Will be numerically unstable with xfem if the endpoints lie at +-1 - or will it?
2543  double totalThickness = this->layeredCS->computeIntegralThick();
2544  double zMid_i = this->layeredCS->giveLayerMidZ(layer); // global z-coord
2545  double xiMid_i = 1.0 - 2.0 * ( totalThickness - this->layeredCS->giveMidSurfaceZcoordFromBottom() - zMid_i ) / totalThickness; // local z-coord
2546  double deltaxi = localCoords.at(3) * this->layeredCS->giveLayerThickness(layer) / totalThickness; // distance from layer mid
2547  localCoords.at(3) = xiMid_i + deltaxi * scaleFactor;
2548 
2549  this->vtkEvalUpdatedGlobalCoordinateAt(localCoords, layer, nodes[i-1], tStep);
2550  }
2551 }
2552 
2553 void
2554 Shell7BaseXFEM :: giveFictiousUpdatedCZNodeCoordsForExport(std::vector<FloatArray> &nodes, int interface, TimeStep *tStep, int subCell)
2555 {
2556  // compute fictious node coords
2557  FloatArray nodeLocalXi1Coords, nodeLocalXi2Coords, nodeLocalXi3Coords;
2558 
2559  FloatMatrix localNodeCoords;
2560 
2561 
2562  if ( subCell == 0) {
2563  this->interpolationForCZExport.giveLocalNodeCoords(localNodeCoords);
2564  // must get local z-coord in terms of the total thickness not layerwise
2565 
2566  } else {
2567  giveLocalCZNodeCoordsForExport(nodeLocalXi1Coords, nodeLocalXi2Coords, nodeLocalXi3Coords, subCell, localNodeCoords);
2568  }
2569  nodes.resize(localNodeCoords.giveNumberOfColumns());
2570  for ( int i = 1; i <= localNodeCoords.giveNumberOfColumns(); i++ ){
2571  FloatArray localCoords(3);
2572  localCoords.beColumnOf(localNodeCoords, i);
2573  localCoords.at(3) = 1.0;
2574  // Map local layer cs to local shell cs
2575  double scaleFactor = 0.9999; // Will be numerically unstable with xfem if the endpoints lie at +-1 - or will it?
2576  double totalThickness = this->layeredCS->computeIntegralThick();
2577  double zMid_i = this->layeredCS->giveLayerMidZ(interface); // global z-coord
2578  double xiMid_i = 1.0 - 2.0 * ( totalThickness - this->layeredCS->giveMidSurfaceZcoordFromBottom() - zMid_i ) / totalThickness; // local z-coord
2579  double deltaxi = localCoords.at(3) * this->layeredCS->giveLayerThickness(interface) / totalThickness; // distance from layer mid
2580  localCoords.at(3) = xiMid_i + deltaxi * scaleFactor;
2581 
2582  this->vtkEvalUpdatedGlobalCoordinateAt(localCoords, interface, nodes[i-1], tStep);
2583  }
2584 }
2585 
2586 
2587 void
2589 {
2590  // Map local layer cs to local shell cs
2591  answer.resize(15);
2592  for ( int i = 1; i <= 15; i++ ){
2593  double scaleFactor = 0.9999; // Will be numerically unstable with xfem if the endpoints lie at +-1
2594  double totalThickness = this->layeredCS->computeIntegralThick();
2595  double zMid_i = this->layeredCS->giveLayerMidZ(layer); // global z-coord
2596  double xiMid_i = 1.0 - 2.0 * ( totalThickness - this->layeredCS->giveMidSurfaceZcoordFromBottom() - zMid_i ) / totalThickness; // local z-coord
2597  double deltaxi = local.at(i) * this->layeredCS->giveLayerThickness(layer) / totalThickness; // distance from layer mid
2598  local.at(i) = xiMid_i + deltaxi * scaleFactor;
2599 
2600  answer.at(i) = local.at(i);
2601  }
2602 }
2603 
2604 
2605 
2606 void
2607 Shell7BaseXFEM :: giveLocalNodeCoordsForExport(FloatArray &nodeLocalXi1Coords, FloatArray &nodeLocalXi2Coords, FloatArray &nodeLocalXi3Coords, int subCell, int layer, FloatMatrix &localNodeCoords)
2608 {
2609  // Local coords for a quadratic wedge element - coords for subtriangles
2610  double scale = 0.9999;
2611  double z = 1.0*scale;
2612 
2613  // Triangle coordinates
2614  FloatArray g1, g2, g3;
2615  //g1 = this->allTri[subCell-1].giveVertex(1);
2616  //g2 = this->allTri[subCell-1].giveVertex(2);
2617  //g3 = this->allTri[subCell-1].giveVertex(3);
2618  g1 = this->crackSubdivisions[layer-1][subCell-1].giveVertex(1);
2619  g2 = this->crackSubdivisions[layer-1][subCell-1].giveVertex(2);
2620  g3 = this->crackSubdivisions[layer-1][subCell-1].giveVertex(3);
2621 
2622  FloatArray gs1(2), gs2(2), gs3(2);
2623  gs1.zero(); gs2.zero(); gs3.zero();
2624  // Move the triangle nodes slightly towards the center to avoid numerical problems - controlled by 'scale'
2625  double alpha1 = scale; double alpha2 = (1.0-alpha1)*0.5; double alpha3 = alpha2;
2626  //g1.printYourself(); g2.printYourself(); g3.printYourself();
2628  gs1 = alpha1*g1 + alpha2*g2 + alpha3*g3;
2629  gs2 = alpha2*g1 + alpha1*g2 + alpha3*g3;
2630  gs3 = alpha2*g1 + alpha3*g2 + alpha1*g3;
2631 
2632  // Local coordinates for the (scaled) triangle coordinates
2633  FloatArray loc1, loc2, loc3;
2634  this->computeLocalCoordinates(loc1, gs1);
2635  this->computeLocalCoordinates(loc2, gs2);
2636  this->computeLocalCoordinates(loc3, gs3);
2637 
2638  // Compute coordinates for the three mid nodes
2639  FloatArray loc12, loc23, loc31;
2640  loc12 = 0.5 * (loc1 + loc2);
2641  loc23 = 0.5 * (loc2 + loc3);
2642  loc31 = 0.5 * (loc3 + loc1);
2643  double a = loc1.at(1);
2644  double b = loc2.at(1);
2645  double c = loc3.at(1);
2646  double d = loc12.at(1);
2647  double e = loc23.at(1);
2648  double f = loc31.at(1);
2649  nodeLocalXi1Coords = { a, b, c, a, b, c, d, e, f, d, e, f, a, b, c };
2650 
2651  a = loc1.at(2);
2652  b = loc2.at(2);
2653  c = loc3.at(2);
2654  d = loc12.at(2);
2655  e = loc23.at(2);
2656  f = loc31.at(2);
2657  nodeLocalXi2Coords = { a, b, c, a, b, c, d, e, f, d, e, f, a, b, c };
2658 
2659  nodeLocalXi3Coords = { -z, -z, -z, z, z, z, -z, -z, -z, z, z, z, 0., 0., 0. };
2660 
2661  FloatMatrix localNodeCoordsT;
2662  localNodeCoordsT = {nodeLocalXi1Coords, nodeLocalXi2Coords, nodeLocalXi3Coords};
2663  localNodeCoords.beTranspositionOf(localNodeCoordsT);
2664 
2665 }
2666 
2667 
2668 void
2669 Shell7BaseXFEM :: giveLocalCZNodeCoordsForExport(FloatArray &nodeLocalXi1Coords, FloatArray &nodeLocalXi2Coords, FloatArray &nodeLocalXi3Coords, int subCell, FloatMatrix &localNodeCoords)
2670 {
2671  // Local coords for a quadratic triangle element - coords for subtriangles
2672  double scale = 0.999;
2673  //double z = 1.0*scale;
2674 
2675  // Triangle coordinates
2676  FloatArray g1, g2, g3;
2677  g1 = this->allTri[subCell-1].giveVertex(1);
2678  g2 = this->allTri[subCell-1].giveVertex(2);
2679  g3 = this->allTri[subCell-1].giveVertex(3);
2680 
2681  FloatArray gs1, gs2, gs3;
2682  // Move the triangle nodes slightly towards the center to avoid numerical problems - controlled by 'scale'
2683  double alpha1 = scale; double alpha2 = (1.0-alpha1)*0.5; double alpha3 = alpha2;
2684  gs1 = alpha1*g1 + alpha2*g2 + alpha3*g3;
2685  gs2 = alpha2*g1 + alpha1*g2 + alpha3*g3;
2686  gs3 = alpha2*g1 + alpha3*g2 + alpha1*g3;
2687 
2688  // Local coordinates for the (scaled) triangle coordinates
2689  FloatArray loc1, loc2, loc3;
2690  this->computeLocalCoordinates(loc1, gs1);
2691  this->computeLocalCoordinates(loc2, gs2);
2692  this->computeLocalCoordinates(loc3, gs3);
2693 
2694  // Compute coordinates for the three mid nodes
2695  FloatArray loc12, loc23, loc31;
2696  loc12 = 0.5 * (loc1 + loc2);
2697  loc23 = 0.5 * (loc2 + loc3);
2698  loc31 = 0.5 * (loc3 + loc1);
2699  double a = loc1.at(1);
2700  double b = loc2.at(1);
2701  double c = loc3.at(1);
2702  double d = loc12.at(1);
2703  double e = loc23.at(1);
2704  double f = loc31.at(1);
2705  nodeLocalXi1Coords = { a, b, c, d, e, f };
2706 
2707  a = loc1.at(2);
2708  b = loc2.at(2);
2709  c = loc3.at(2);
2710  d = loc12.at(2);
2711  e = loc23.at(2);
2712  f = loc31.at(2);
2713  nodeLocalXi2Coords = { a, b, c, d, e, f };
2714 
2715  nodeLocalXi3Coords = { 0., 0., 0., 0., 0., 0. };
2716 
2717  FloatMatrix localNodeCoordsT;
2718  localNodeCoordsT = {nodeLocalXi1Coords, nodeLocalXi2Coords, nodeLocalXi3Coords};
2719  localNodeCoords.beTranspositionOf(localNodeCoordsT);
2720 
2721 }
2722 
2723 void
2724 Shell7BaseXFEM :: giveCZExportData(VTKPiece &vtkPiece, IntArray &primaryVarsToExport, IntArray &internalVarsToExport, IntArray cellVarsToExport, TimeStep *tStep )
2725 {
2726 
2727  int numSubCells = 1;
2728  if ( this->allTri.size() ) {
2729  numSubCells = (int)this->allTri.size();
2730  }
2731 
2732  int numInterfaces = this->layeredCS->giveNumberOfLayers()-1;
2733  int numCells = numInterfaces * numSubCells;
2734 
2735  int numCellNodes = 6; // quadratic triangle
2736 
2737  int numTotalNodes = numCellNodes*numCells;
2738 
2739  vtkPiece.setNumberOfCells(numCells);
2740  vtkPiece.setNumberOfNodes(numTotalNodes);
2741 
2742  std::vector <FloatArray> nodeCoords;
2743  int val = 1;
2744  int offset = 0;
2745  int currentCell = 1;
2746  IntArray nodes(numCellNodes);
2747 
2748  // Compute fictious node coords
2749  int nodeNum = 1;
2750  for ( int layer = 1; layer <= numInterfaces; layer++ ) {
2751 
2752  for ( int subCell = 1; subCell <= numSubCells; subCell++ ) {
2753 
2754  // Node coordinates
2755  if ( numSubCells == 1 ) {
2757  } else {
2758  this->giveFictiousCZNodeCoordsForExport(nodeCoords, layer, subCell);
2759  }
2760 
2761  for ( int node = 1; node <= numCellNodes; node++ ) {
2762  vtkPiece.setNodeCoords(nodeNum, nodeCoords[node-1] );
2763  nodeNum += 1;
2764  }
2765 
2766  // Connectivity
2767  for ( int i = 1; i <= numCellNodes; i++ ) {
2768  nodes.at(i) = val++;
2769  }
2770  vtkPiece.setConnectivity(currentCell, nodes);
2771 
2772  // Offset
2773  offset += numCellNodes;
2774  vtkPiece.setOffset(currentCell, offset);
2775 
2776  // Cell types
2777  vtkPiece.setCellType(currentCell, 22); // Quadratic triangle
2778 
2779  currentCell++;
2780  }
2781  }
2782 
2783 
2784 
2785 
2786  // Export nodal variables from primary fields
2787  vtkPiece.setNumberOfPrimaryVarsToExport(primaryVarsToExport.giveSize(), numTotalNodes);
2788 
2789  std::vector<FloatArray> updatedNodeCoords;
2790  FloatArray u(3);
2791  std::vector<FloatArray> values;
2792  for ( int fieldNum = 1; fieldNum <= primaryVarsToExport.giveSize(); fieldNum++ ) {
2793  UnknownType type = ( UnknownType ) primaryVarsToExport.at(fieldNum);
2794  nodeNum = 1;
2795  currentCell = 1;
2796  for ( int layer = 1; layer <= numInterfaces; layer++ ) {
2797 
2798  for ( int subCell = 1; subCell <= numSubCells; subCell++ ) {
2799 
2800  if ( type == DisplacementVector ) { // compute displacement as u = x - X
2801  if ( numSubCells == 1 ) {
2803  this->giveFictiousUpdatedCZNodeCoordsForExport(updatedNodeCoords, layer, tStep, 0);
2804  } else {
2805  this->giveFictiousCZNodeCoordsForExport(nodeCoords, layer, subCell);
2806  this->giveFictiousUpdatedCZNodeCoordsForExport(updatedNodeCoords, layer, tStep, subCell);
2807  }
2808  for ( int j = 1; j <= numCellNodes; j++ ) {
2809  u.beDifferenceOf(updatedNodeCoords[j-1], nodeCoords[j-1]);
2810  vtkPiece.setPrimaryVarInNode(fieldNum, nodeNum, u);
2811  nodeNum += 1;
2812  }
2813 
2814  } else {
2815  NodalRecoveryMI_recoverValues(values, layer, ( InternalStateType ) 1, tStep); // does not work well - fix
2816  for ( int j = 1; j <= numCellNodes; j++ ) {
2817  vtkPiece.setPrimaryVarInNode(fieldNum, nodeNum, values[j-1]);
2818  nodeNum += 1;
2819  }
2820  }
2821 
2822  currentCell++;
2823  }
2824  }
2825  }
2826 
2827 
2828 
2829  // Export nodal variables from internal fields
2830 
2831  vtkPiece.setNumberOfInternalVarsToExport( internalVarsToExport.giveSize(), numTotalNodes );
2832  for ( int fieldNum = 1; fieldNum <= internalVarsToExport.giveSize(); fieldNum++ ) {
2833  InternalStateType type = ( InternalStateType ) internalVarsToExport.at(fieldNum);
2834  nodeNum = 1;
2835 
2836  //int currentCell = 1;
2837  for ( int layer = 1; layer <= numInterfaces; layer++ ) {
2838  for ( int subCell = 1; subCell <= numSubCells; subCell++ ) {
2839  this->recoverValuesFromCZIP(values, layer, type, tStep);
2840 
2841  for ( int j = 1; j <= numCellNodes; j++ ) {
2842  vtkPiece.setInternalVarInNode( fieldNum, nodeNum, values[j-1] );
2843  //ZZNodalRecoveryMI_recoverValues(el.nodeVars[fieldNum], layer, type, tStep);
2844  nodeNum += 1;
2845  }
2846  }
2847  }
2848  }
2849 
2850 
2851  // Export cell variables
2852  FloatArray average;
2853  vtkPiece.setNumberOfCellVarsToExport(cellVarsToExport.giveSize(), numCells);
2854  for ( int i = 1; i <= cellVarsToExport.giveSize(); i++ ) {
2855  InternalStateType type = ( InternalStateType ) cellVarsToExport.at(i);
2857  currentCell = 1;
2858  for ( int layer = 1; layer <= numInterfaces; layer++ ) {
2859  for ( int subCell = 1; subCell <= numSubCells; subCell++ ) {
2860  if ( type == IST_CrossSectionNumber ) {
2861  average = FloatArray{ -double(layer) }; // Set a negative number for interfaces
2862  } else {
2863  std :: unique_ptr< IntegrationRule > &iRuleL = integrationRulesArray [ layer - 1 ];
2864  VTKXMLExportModule::computeIPAverage(average, iRuleL.get(), this, type, tStep);
2865  }
2866  if ( valueType == ISVT_TENSOR_S3 ) {
2867  vtkPiece.setCellVar(i, currentCell, convV6ToV9Stress(average) );
2868  } else {
2869  vtkPiece.setCellVar(i, currentCell, average);
2870  }
2871  currentCell += 1;
2872  }
2873  }
2874 
2875  }
2876 
2877 
2878 
2879 
2880 #if 0
2881 
2882 
2883  // Export of XFEM related quantities
2884  XfemManager *xFemMan = this->xMan;
2885  int nEnrIt = xFemMan->giveNumberOfEnrichmentItems();
2886 
2887  IntArray wedgeToTriMap({15, 1, 2, 3, 1, 2, 3, 4, 5, 6, 4, 5, 6, 1, 2, 3} );
2888  // For each node in the wedge take the value from the triangle node given by the map below
2889  // wedgeToTriMap.setValues;
2890 
2891  vtkPiece.setNumberOfInternalXFEMVarsToExport(xFemMan->vtkExportFields.giveSize(), nEnrIt, numTotalNodes);
2892  for ( int field = 1; field <= xFemMan->vtkExportFields.giveSize(); field++ ) {
2893  XFEMStateType xfemstype = ( XFEMStateType ) xFemMan->vtkExportFields [ field - 1 ];
2894 
2895  for ( int enrItIndex = 1; enrItIndex <= nEnrIt; enrItIndex++ ) {
2896  EnrichmentItem *ei = xFemMan->giveEnrichmentItem(enrItIndex);
2897  int nodeNum = 1;
2898  for ( int layer = 1; layer <= numInterfaces; layer++ ) {
2899  FloatMatrix localNodeCoords;
2900 
2901  for ( int subCell = 1; subCell <= numSubCells; subCell++ ) {
2902  FloatArray nodeLocalXi1Coords, nodeLocalXi2Coords, nodeLocalXi3Coords, nodeLocalXi3CoordsMapped;
2903  if ( numSubCells == 1) {
2904  this->interpolationForExport.giveLocalNodeCoords(localNodeCoords);
2905  } else {
2906  giveLocalNodeCoordsForExport(nodeLocalXi1Coords, nodeLocalXi2Coords, nodeLocalXi3Coords, subCell, layer, localNodeCoords);
2907  }
2908  mapXi3FromLocalToShell(nodeLocalXi3CoordsMapped, nodeLocalXi3Coords, layer);
2909  for ( int nodeIndx = 1; nodeIndx <= numCellNodes; nodeIndx++ ) {
2910 
2911  FloatArray lCoords;
2912  //lCoords.setValues(3, nodeLocalXi1Coords.at(nodeIndx), nodeLocalXi2Coords.at(nodeIndx), nodeLocalXi3CoordsMapped.at(nodeIndx));
2913  lCoords.beColumnOf(localNodeCoords, nodeIndx);
2914  //Node *node = this->giveNode( wedgeToTriMap.at(nodeIndx) );
2915  Node *node = this->giveNode( nodeIndx );
2916  FloatArray valueArray;
2917  const FloatArray *val = NULL;
2918  if ( xfemstype == XFEMST_LevelSetPhi ) {
2919  valueArray.resize(1);
2920  val = & valueArray;
2921  valueArray.at(1) = this->evaluateLevelSet(lCoords, ei);
2922  } else if ( xfemstype == XFEMST_LevelSetGamma ) {
2923  valueArray.resize(1);
2924  val = & valueArray;
2925  ei->evalLevelSetTangInNode( valueArray.at(1), node->giveNumber() , node->giveNodeCoordinates());
2926  } else if ( xfemstype == XFEMST_NodeEnrMarker ) {
2927  valueArray.resize(1);
2928  val = & valueArray;
2929  ei->evalNodeEnrMarkerInNode( valueArray.at(1), node->giveNumber() );
2930  } else {
2931  //OOFEM_WARNING2("VTKXMLExportModule::getNodalVariableFromXFEMST: invalid data in node %d", inode);
2932  }
2933 
2934  vtkPiece.setInternalXFEMVarInNode(field, enrItIndex, nodeNum, valueArray);
2935  nodeNum += 1;
2936  }
2937  }
2938  }
2939  }
2940  }
2941 #endif
2942 
2943 
2944 }
2945 
2946 void
2947 Shell7BaseXFEM :: recoverValuesFromCZIP(std::vector<FloatArray> &recoveredValues, int interfce, InternalStateType type, TimeStep *tStep)
2948 {
2949  // recover nodal values by coosing the ip closest to the node
2950 
2951  // composite element interpolator
2952  FloatMatrix localNodeCoords;
2953  //this->interpolationForExport.giveLocalNodeCoords(localNodeCoords);
2954  this->interpolationForCZExport.giveLocalNodeCoords(localNodeCoords);
2955  int numNodes = localNodeCoords.giveNumberOfColumns();
2956  recoveredValues.resize(numNodes);
2957 
2958  std :: unique_ptr< IntegrationRule > &iRule = this->czIntegrationRulesArray [ interfce - 1 ];
2959 
2960  // Find closest ip to the nodes
2961  IntArray closestIPArray(numNodes);
2962  FloatArray nodeCoords, ipValues;
2963 
2964  for ( int i = 1; i <= numNodes; i++ ) {
2965  nodeCoords.beColumnOf(localNodeCoords, i);
2966  double distOld = 3.0; // should not be larger
2967  for ( int j = 0; j < iRule->giveNumberOfIntegrationPoints(); j++ ) {
2968  IntegrationPoint *ip = iRule->getIntegrationPoint(j);
2969  double dist = nodeCoords.distance(ip->giveNaturalCoordinates());
2970  if ( dist < distOld ) {
2971  closestIPArray.at(i) = j;
2972  distOld = dist;
2973  }
2974  }
2975  }
2976 
2978 
2979  // recover ip values
2980  for ( int i = 1; i <= numNodes; i++ ) {
2981  if ( this->layeredCS->giveInterfaceMaterial(interfce) ) {
2982  IntegrationPoint *ip = iRule->getIntegrationPoint( closestIPArray.at(i) );
2983  this->layeredCS->giveInterfaceMaterial(interfce)->giveIPValue(ipValues, ip, type, tStep);
2984  } else {
2985  ipValues.resize(0);
2986  }
2987 
2988  if ( ipValues.giveSize() == 0 && type == IST_AbaqusStateVector) {
2989  recoveredValues[i-1].resize(23);
2990  recoveredValues[i-1].zero();
2991  } else if ( ipValues.giveSize() == 0 ) {
2992  recoveredValues[i-1].resize(giveInternalStateTypeSize(valueType));
2993  recoveredValues[i-1].zero();
2994 
2995  } else if ( valueType == ISVT_TENSOR_S3 ) {
2996  recoveredValues[i-1] = convV6ToV9Stress(ipValues);
2997 
2998  } else {
2999  recoveredValues[i-1] = ipValues;
3000  }
3001  }
3002 
3003 }
3004 
3005 
3006 
3007 void
3009 {
3010  // Computes the product a^T*b*c
3011  FloatMatrix temp;
3012  temp.beTProductOf(a, b);
3013  answer.beProductOf(temp, c);
3014 }
3015 
3016 
3017 void
3019 {
3020  // Recover shear stresses at ip by numerical integration of the momentum balance through the thickness (overloaded from shell7base)
3021 
3022  int numberOfLayers = this->layeredCS->giveNumberOfLayers();
3023 
3024  // Check if delamination/CZ is active. Then use hasCohesiveZone to decide whether the cohforces need to be calculated (otherwise traction BC need to be found)
3025  // Find (possible) layer/interface BC, starting from bottom
3026 // IntArray layerHasBC(numberOfLayers+1); layerHasBC.zero();
3027  IntArray delaminationInterface; delaminationInterface.clear(); // interface (starting from 1) which contains delamination
3028  IntArray interfaceEI(numberOfLayers-1);
3029 
3030  bool hasDelamination = false;
3031  int numEI = this->xMan->giveNumberOfEnrichmentItems();
3032  for ( int iEI = 1; iEI <= numEI; iEI++ ) {
3033 
3034  EnrichmentItem *ei = this->xMan->giveEnrichmentItem(iEI);
3035  if ( ei->isElementEnriched(this) ) {
3036  hasDelamination = true;
3037  // Find cohesive material (for delamination)
3038  Delamination *dei = dynamic_cast< Delamination * >( ei );
3039  int delaminationInterfaceNum = dei->giveDelamInterfaceNum();
3040 // layerHasBC.at(delaminationInterfaceNum+1) = iEI;
3041  delaminationInterface.followedBy(delaminationInterfaceNum);
3042  interfaceEI.at(delaminationInterfaceNum) = iEI;
3043  }
3044  }
3045  delaminationInterface.sort();
3046 
3047  if ( hasDelamination ) {
3048 
3049  int numInPlaneIP = 6;
3050  int numThicknessIP = this->layeredCS->giveNumIntegrationPointsInLayer();
3051  if (numThicknessIP < 2) {
3052  // Polynomial fit involves linear z-component at the moment
3053  OOFEM_ERROR("To few thickness IP per layer to do polynomial fit");
3054  }
3055 
3056  int numDel = delaminationInterface.giveSize();
3057 
3058  // Find top and bottom BC NB: assumes constant over element surface.
3059  // traction BC added to vector of BC.
3060  std::vector <FloatMatrix> tractionBC; tractionBC.resize(numDel+2);
3061  tractionBC[numDel+1].resize(3,numInPlaneIP);
3062  tractionBC[0].resize(3,numInPlaneIP);
3063  giveTractionBC(tractionBC[numDel+1],tractionBC[0], tStep);
3064  //if (this->giveGlobalNumber() == 8 || this->giveGlobalNumber() == 50) {tractionBC[numDel+1].printYourself("tractionTop"); tractionBC[0].printYourself("tractionBtm");}
3065 
3066 #if 0
3067  FloatArray tractionTop, tractionBtm;
3068  giveTractionBC(tractionTop,tractionBtm, tStep);
3069  for ( int i = 1 ; i <= numInPlaneIP ; i++) {
3070  tractionBC[0].at(1,i) = tractionBtm.at(1);
3071  tractionBC[0].at(2,i) = tractionBtm.at(2);
3072  tractionBC[0].at(3,i) = tractionBtm.at(3);
3073  tractionBC[numDel+1].at(1,i) = tractionTop.at(1);
3074  tractionBC[numDel+1].at(2,i) = tractionTop.at(2);
3075  tractionBC[numDel+1].at(3,i) = tractionTop.at(3);
3076  }
3077 #endif
3078  // Find delamination traction BC
3079  for (int iDel = 1 ; iDel <= numDel ; iDel++) {
3080 
3081  tractionBC[iDel].resize(3,numInPlaneIP);
3082 
3083  int interfaceNum = delaminationInterface.at(iDel);
3084  EnrichmentItem *ei = this->xMan->giveEnrichmentItem(interfaceEI.at(interfaceNum));
3085  Delamination *dei = dynamic_cast< Delamination * >( ei );
3086 
3087  if ( this->hasCohesiveZone( interfaceNum ) ) {
3088 #if 1
3089  // CZ traction
3090  std :: unique_ptr< IntegrationRule > &iRuleI = this->czIntegrationRulesArray [ interfaceNum - 1 ];
3091  if (czIntegrationRulesArray [ interfaceNum - 1 ]->giveNumberOfIntegrationPoints() != numInPlaneIP ) {
3092  OOFEM_ERROR("Interface IPs doesn't match the element IPs");
3093  }
3094  StructuralInterfaceMaterial *intMat = dynamic_cast < StructuralInterfaceMaterial * > (this->layeredCS->giveInterfaceMaterial(interfaceNum) );
3095  if (intMat == 0) {
3096  OOFEM_ERROR("NULL pointer to material, shell element %i",this->giveGlobalNumber());
3097  }
3098 
3099  FloatArray lCoords(3), nCov, CZPKtraction(3);
3100  FloatMatrix Q;
3101  int iIGP = 1;
3102  for ( GaussPoint *gp : *iRuleI ) {
3103  double xi = dei->giveDelamXiCoord();
3104  lCoords.at(1) = gp->giveNaturalCoordinate(1);
3105  lCoords.at(2) = gp->giveNaturalCoordinate(2);
3106  lCoords.at(3) = xi;
3107 
3108  //FloatArray GPcoords = gp->giveGlobalCoordinates();
3109  //if (this->giveGlobalNumber() == 126) { GPcoords.printYourself("interface GPs"); }
3110 // this->evalInitialCovarNormalAt(nCov, lCoords); // intial coords
3111 
3112  // Find PK-traction in current coords.
3113  FloatArray solVecC;
3114  this->giveUpdatedSolutionVector(solVecC, tStep);
3115  FloatMatrix B;
3116  this->computeEnrichedBmatrixAt(lCoords, B, NULL); // NULL => Shell7base :: computeBmatrixAt, otherwise include dei
3117  FloatArray genEpsC;
3118  genEpsC.beProductOf(B, solVecC);
3119  this->evalCovarNormalAt(nCov, lCoords, genEpsC, tStep); // Denna verkar ta hänsyn till hoppet, men hur ser jag till att det är normalen ovanför delamineringen?
3120  Q.beLocalCoordSys(nCov);
3121 
3122 #if 0
3123  // Compute 1PK traction from jump vector
3124  FloatArray jump;
3125  this->computeInterfaceJumpAt(dei->giveDelamInterfaceNum(), lCoords, tStep, jump); // -> numerical tol. issue -> normal jump = 1e-10
3126 
3127  genEpsC.beProductOf(B, solVecC);
3128  FloatMatrix F;
3129  this->computeFAt(lCoords, F, genEpsC, tStep);
3130 
3131  // Transform xd and F to a local coord system
3132  this->evalInitialCovarNormalAt(nCov, lCoords);
3133  Q.beLocalCoordSys(nCov);
3134  jump.rotatedWith(Q,'n');
3135  F.rotatedWith(Q,'n');
3136 
3137  // Compute cohesive traction based on jump
3138  intMat->giveFirstPKTraction_3d(CZPKtraction, gp, jump, F, tStep);
3139 #else
3140  // Get 1PK traction directly from interface material status.
3141  StructuralInterfaceMaterialStatus *intMatStatus = dynamic_cast < StructuralInterfaceMaterialStatus * >( intMat->giveStatus(gp) );
3142  if (intMatStatus == 0) {
3143  OOFEM_ERROR("NULL pointer to interface material, shell element %i",this->giveGlobalNumber());
3144  }
3145  CZPKtraction = intMatStatus->giveTempFirstPKTraction(); // 3 components in local coords
3146 #endif
3147 
3148  CZPKtraction.rotatedWith(Q,'t'); // transform back to global coord system
3149  //if (this->giveGlobalNumber() == 9 ) { CZPKtraction.printYourself("CZPKtraction");}
3150 
3151  // Set BC stresses
3152  tractionBC[iDel].at(1,iIGP) = CZPKtraction.at(1);
3153  tractionBC[iDel].at(2,iIGP) = CZPKtraction.at(2);
3154  tractionBC[iDel].at(3,iIGP) = CZPKtraction.at(3);
3155  iIGP++;
3156  }
3157 #endif
3158  } else {
3159  // Delamination zero traction
3160  tractionBC[iDel].zero();
3161  }
3162  //if (this->giveGlobalNumber() == 50) {tractionBC[iDel].printYourself("tractionDel");}
3163  }
3164 
3165  FloatMatrix SmatOld(3,numInPlaneIP); // 3 stress components (S_xz, S_yz, S_zz) * num of in plane ip
3166  double totalThickness = this->layeredCS->computeIntegralThick();
3167  double zeroThicknessLevel = - 0.5 * totalThickness; // assumes midplane is the geometric midplane of layered structure.
3168  FloatMatrix dSmat(3,numInPlaneIP); // 3 stress components (S_xz, S_yz, S_zz) * num of in plane ip
3169  FloatMatrix dSmatLayerIP(3,numInPlaneIP*numThicknessIP); // 3 stress components (S_xz, S_yz, S_zz) * num of wedge ip
3170 
3171  int layerOld = 0;
3172  int iInt = 0;
3173  delaminationInterface.followedBy(numberOfLayers); // creates an array of the layer index of the top layer in a delamination (NB: index = numberOfLayers will allways be the last)
3174  for ( int topLayer : delaminationInterface) {
3175  SmatOld = tractionBC[iInt]; // bottom traction BC of delamination
3176  int numDelLayers = topLayer-layerOld; // number of layers in delamination
3177  std::vector <FloatMatrix> dSmatIP; dSmatIP.resize(numDelLayers); //recovered stress values in wedge IPs
3178  std::vector <FloatMatrix> dSmat; dSmat.resize(numDelLayers); //recovered stress values at delamination top
3179  std::vector <FloatMatrix> dSmatIPupd; dSmatIPupd.resize(numDelLayers); //recovered stress values in wedge IPs adjusted for top and btm traction BC.
3180  std::vector <FloatMatrix> dSmatupd; dSmatupd.resize(numDelLayers); //recovered stress values at delamination top, adjusted for top and btm traction BC
3181 
3182  // Recovered stresses in delaminated layers
3183  double dz = 0.0;
3184  for ( int delLayer = 1 ; delLayer <= numDelLayers; delLayer++ ) {
3185 
3186  this->giveLayerContributionToSR(dSmat[delLayer-1], dSmatIP[delLayer-1], delLayer+layerOld, zeroThicknessLevel + dz, tStep);
3187  SmatOld.add(dSmat[delLayer-1]); // Integrated stress over laminate
3188  dz += this->layeredCS->giveLayerThickness(delLayer+layerOld);
3189 
3190  }
3191 
3192  // Adjust recovered stresses to traction BC (divide integration error 50/50 at top and btm of delamination)
3193  this->fitRecoveredStress2BC(dSmatIPupd, dSmatupd, dSmat, dSmatIP, SmatOld, tractionBC[iInt], tractionBC[iInt+1], zeroThicknessLevel, {0.0,0.0,1.0}, layerOld+1, topLayer);
3194 
3195  for ( int layer = 1 ; layer <= numDelLayers; layer++ ) {
3196  //if (this->giveGlobalNumber() == 48 ) { dSmatIPupd[layer-1].printYourself(); }
3197  this->updateLayerTransvStressesSR( dSmatIPupd[layer-1], layer+layerOld);
3198  }
3199  zeroThicknessLevel += dz;
3200  layerOld = topLayer;
3201  iInt++;
3202  }
3203 #if 0
3204  for ( int layer = 1; layer <= numberOfLayers; layer++ ) {
3205 
3206  // Bör det vara this här istället för Shell7Base?
3207 // Shell7Base :: giveLayerContributionToSR(dSmat, dSmatLayerIP, layer, zeroThicknessLevel, tStep); // NB: performed in global system
3208  this->giveLayerContributionToSR(dSmat, dSmatLayerIP, layer, zeroThicknessLevel, tStep); // NB: performed in global system
3209 
3210 // Shell7Base :: updateLayerStressesSR(dSmatLayerIP, SmatOld, layer);
3211  this->updateLayerTransvStressesSR(dSmatLayerIP, SmatOld, layer);
3212  //dSmatLayerIP.printYourself();
3213  //printf("enr func in dofman %d = %e \n", layer, layer);
3214 
3215  SmatOld.add(dSmat);
3216  if (this->giveGlobalNumber() == 126) {
3217  SmatOld.printYourself();
3218  }
3219  zeroThicknessLevel += this->layeredCS->giveLayerThickness(layer);
3220 
3221  // Add traction from delamination CZ. NB: assumes same number order of GPs in interface and shell elements
3222  if ( layerHasBC.at(layer+1) ) {
3223 
3224  EnrichmentItem *ei = this->xMan->giveEnrichmentItem(layerHasBC.at(layer+1));
3225  Delamination *dei = dynamic_cast< Delamination * >( ei );
3226  int interfaceNum = dei->giveDelamInterfaceNum();
3227 
3228  if ( this->hasCohesiveZone( interfaceNum ) ) {
3229 #if 1
3230  // CZ traction
3231  std :: unique_ptr< IntegrationRule > &iRuleI = czIntegrationRulesArray [ interfaceNum - 1 ];
3232  if (iRuleI->giveNumberOfIntegrationPoints() != numInPlaneIP ) {
3233  OOFEM_ERROR("Interface IPs doesn't match the element IPs");
3234  }
3235 
3236  FloatArray lCoords(3), nCov, CZPKtraction(3);
3237  CZPKtraction.zero();
3238  FloatMatrix Q;
3239  int iIGP = 1;
3240  for ( GaussPoint *gp: *iRuleI ) {
3241  double xi = dei->giveDelamXiCoord();
3242  lCoords.at(1) = gp->giveNaturalCoordinate(1);
3243  lCoords.at(2) = gp->giveNaturalCoordinate(2);
3244  lCoords.at(3) = xi;
3245  #if 0
3246  FloatArray GPcoords = gp->giveGlobalCoordinates();
3247  if (this->giveGlobalNumber() == 126) {
3248  GPcoords.printYourself("interface GPs");
3249  }
3250  #endif
3251 // this->evalInitialCovarNormalAt(nCov, lCoords); // intial coords
3252 
3253  // Find PK-traction in current coords.
3254  FloatArray solVecC;
3255  this->giveUpdatedSolutionVector(solVecC, tStep);
3256  FloatMatrix B;
3257  this->computeEnrichedBmatrixAt(lCoords, B, NULL); // NULL => Shell7base :: computeBmatrixAt, otherwise include dei
3258  FloatArray genEpsC;
3259  genEpsC.beProductOf(B, solVecC);
3260  this->evalCovarNormalAt(nCov, lCoords, genEpsC, tStep); // Denna verkar ta hänsyn till hoppet, men hur ser jag till att det är normalen ovanför delamineringen?
3261  Q.beLocalCoordSys(nCov);
3262 
3263  StructuralInterfaceMaterialStatus* intMatStatus = static_cast < StructuralInterfaceMaterialStatus* > ( gp->giveMaterialStatus() );
3264  if (intMatStatus == 0) {
3265  OOFEM_ERROR("NULL pointer to material status");
3266  }
3267 
3268  CZPKtraction = intMatStatus->giveFirstPKTraction(); // 3 components in local coords
3269 
3270  CZPKtraction.rotatedWith(Q,'t'); // transform back to global coord system
3271  #if 0
3272  if (this->giveGlobalNumber() == 126) {
3273  CZPKtraction.printYourself();
3274  }
3275  #endif
3276  // Set BC stresses
3277  SmatOld.at(1,iIGP) = CZPKtraction.at(1);
3278  SmatOld.at(2,iIGP) = CZPKtraction.at(2);
3279  SmatOld.at(3,iIGP) = CZPKtraction.at(3);
3280  iIGP++;
3281 #endif
3282  }
3283  } else {
3284  // Delamination zero traction
3285  SmatOld.zero();
3286  }
3287  # if 0
3288  if (this->giveGlobalNumber() == 126) {
3289  SmatOld.printYourself();
3290  }
3291  # endif
3292  }
3293  }
3294 #endif
3295 
3296  } else {
3298  }
3299 
3300 }
3301 
3302 
3303 void
3304 Shell7BaseXFEM :: giveFailedInterfaceNumber(IntArray &failedInterfaces, FloatArray &initiationFactors, TimeStep *tStep, bool recoverStresses)
3305 {
3306  // Compares recovered interface stresses to initiation stress (atm just max stress criterion).
3307  // Assumes three stress components in initiationStress: (Sxz, Syz, Szz)
3308  // Returns any new interface that needs to be enriched.
3310 
3311  failedInterfaces.clear();
3312  std :: vector < FloatMatrix > transverseInterfaceStresses;
3313  if (recoverStresses) {
3314  // Find interface stresses using stress recovery
3315  this->giveRecoveredTransverseInterfaceStress(transverseInterfaceStresses, tStep);
3316  } else {
3317  // Take average stresses of adjacent layers.
3318  this->giveAverageTransverseInterfaceStress(transverseInterfaceStresses, tStep);
3319  }
3320  int numSC = 3;
3321  //initiationFactors.resizeWithValues(this->layeredCS->giveNumberOfLayers());
3322  FloatArray interfaceXiCoords;
3323  this->giveLayeredCS()->giveInterfaceXiCoords(interfaceXiCoords);
3324  FloatMatrix failurestresses(2,this->layeredCS->giveNumberOfLayers());
3325 
3326  for ( int iInterface = 1 ; iInterface < this->layeredCS->giveNumberOfLayers() ; iInterface++ ) {
3327 
3328  bool initiateElt = false;
3329  int interfaceMatNumber(this->giveLayeredCS()->giveInterfaceMaterialNum(iInterface));
3330 
3331  if (interfaceMatNumber && !this->DelaminatedInterfaceList.findSorted(iInterface)) {
3332 
3333  std :: unique_ptr< IntegrationRule > &iRuleI = this->czIntegrationRulesArray [ iInterface - 1 ];
3334 
3335  IntArray failedSC;
3336  StructuralInterfaceMaterial *intMat = dynamic_cast < StructuralInterfaceMaterial * > (this->layeredCS->giveInterfaceMaterial(iInterface) );
3337  if (intMat == 0) {
3338  OOFEM_ERROR("NULL pointer to material, shell %i interface %i",this->giveGlobalNumber(),iInterface);
3339  }
3340 
3341  FloatArray sigF = {1,1,1};
3342  FloatArray temp = intMat->giveInterfaceStrength();
3343  if (temp.giveSize() == 1 && temp.at(1) > 0) {
3344  // Same strength in all directions
3345  //sigF.times(temp.at(1)*initiationFactors.at(iInterface));
3346  sigF.times(temp.at(1));
3347  } else if (temp.giveSize() == 3) {
3348  // Assume S1,S1,N
3349  // sigF.beScaled(initiationFactors.at(iInterface),temp);
3350  sigF = temp;
3351  } else {
3352  OOFEM_ERROR( "Intitiation stress for delaminations not found or incorrect on CZ-material" );
3353  }
3354 
3355  //if (this->giveGlobalNumber() == 9) {transverseInterfaceStresses[iInterface-1].printYourself("Interface stresses elt 9"); initiationStress.printYourself("initiationStress");}
3356 
3357  for ( int iGP = 1 ; iGP <= transverseInterfaceStresses[iInterface-1].giveNumberOfColumns() ; iGP++ ) {
3358  if ( transverseInterfaceStresses[iInterface-1].giveNumberOfRows() != numSC ) {
3359  OOFEM_ERROR( "Wrong number of stress components" );
3360  }
3361 
3362  // Collect interface stresses
3363  FloatArray interfaceStresses;
3364  interfaceStresses.beColumnOf(transverseInterfaceStresses[iInterface-1],iGP); // global coords
3365 
3366  //Rotate to element coord.
3367  FloatArray lCoords; lCoords.resize(3);
3368  GaussPoint *gp = iRuleI->getIntegrationPoint(iGP-1);
3369  lCoords.at(1) = gp->giveNaturalCoordinate(1);
3370  lCoords.at(2) = gp->giveNaturalCoordinate(2);
3371  lCoords.at(3) = interfaceXiCoords.at(iInterface);
3372 
3373  FloatArray solVecC, nCov;
3374  this->giveUpdatedSolutionVector(solVecC, tStep);
3375  FloatMatrix Q,B;
3376  this->computeEnrichedBmatrixAt(lCoords, B, NULL); // NULL => Shell7base :: computeBmatrixAt, otherwise include dei
3377  FloatArray genEpsC;
3378  genEpsC.beProductOf(B, solVecC);
3379  this->evalCovarNormalAt(nCov, lCoords, genEpsC, tStep);
3380  Q.beLocalCoordSys(nCov);
3381 
3382  //if (this->giveGlobalNumber() == 61) {interfaceStresses.printYourself("interfaceStresses global"); lCoords.printYourself("lCoords"); }
3383 
3384  interfaceStresses.rotatedWith(Q,'n'); // local coords
3385  double S1(interfaceStresses.at(1)); //Shear x
3386  double S2(interfaceStresses.at(2)); //Shear y
3387  double N(interfaceStresses.at(3)); //normal
3388  //if (this->giveGlobalNumber() == 61) {Q.printYourself("Q"); interfaceStresses.printYourself("interfaceStresses local");}
3389 
3390  // polynom law
3391  double NM = 0.5*(N + fabs(N));
3392  double failCrit = NM*NM/(sigF.at(3)*sigF.at(3)) + (S1*S1 + S2*S2)/(sigF.at(1)*sigF.at(1));
3393  if (failCrit > (initiationFactors.at(iInterface)*initiationFactors.at(iInterface))) {
3394  initiateElt = true;
3395  failurestresses.at(1,iInterface) = NM;
3396  failurestresses.at(2,iInterface) = sqrt(S1*S1 + S2*S2);
3397  }
3398 
3399  // Max stress criterion
3400 // for ( int iSC = 1 ; iSC <= numSC ; iSC++ ) {
3401 // if ( transverseInterfaceStresses[iInterface-1].at(iSC,iGP) > sigF.at(iSC) || (-transverseInterfaceStresses[iInterface-1].at(iSC,iGP)) > sigF.at(iSC)) {
3402 // printf("SC%i = %1.0f, limit = %1.0f \n", iSC, transverseInterfaceStresses[iInterface-1].at(iSC,iGP), sigF.at(iSC));
3403 // initiateElt = true;
3404 // failedSC.followedBy(iSC);
3405 // ///TODO: add break/continue;
3406 // }
3407 // }
3408  }
3409  if (initiateElt) {
3410  failedInterfaces.followedBy( iInterface );
3411 // printf(" Element %i failed in interface %i. \n",this->giveGlobalNumber(),iInterface);
3412 // for (auto iSC : failedSC) {
3413 // printf(" %i ",iSC);
3414 // }
3415 // printf("\n");
3416  }
3417  }
3418  }
3419 // if (!failedInterfaces.isEmpty()) {
3420 // for ( int alreadyFailedInterface : this->DelaminatedInterfaceList ) {
3421 // failedInterfaces.eraseSorted(alreadyFailedInterface);
3422 // }
3423 // }
3424  this->DelaminatedInterfaceList.followedBy(failedInterfaces);
3425  this->DelaminatedInterfaceList.sort();
3426  if (failedInterfaces.giveSize() > 0) {
3427  printf(" Delamination criterion was activated in element %i : \n",this->giveGlobalNumber() );//
3428  for (auto iInterface : failedInterfaces) {
3429  printf(" Interface %i - NM = %f, S = %f \n",iInterface,failurestresses.at(1,iInterface),failurestresses.at(2,iInterface));
3430  }
3431  printf("\n");
3432  }
3433 }
3434 
3435 void
3436 Shell7BaseXFEM::giveAverageTransverseInterfaceStress(std::vector< FloatMatrix >& transverseStress, TimeStep* tStep)
3437 {
3438  transverseStress.clear();
3439  int numberOfLayers = this->layeredCS->giveNumberOfLayers();
3440  transverseStress.resize(numberOfLayers-1);
3441  int numThicknessIP = this->layeredCS->giveNumIntegrationPointsInLayer();
3442  int numInPlaneIP = 6;
3443 
3444  for ( int layer = 1; layer <= numberOfLayers; layer++ ) {
3445  std :: unique_ptr< IntegrationRule > &iRule = this->integrationRulesArray[layer-1];
3446  if (layer < numberOfLayers) {
3447  transverseStress[layer-1].resize(3,numInPlaneIP);
3448  }
3449 
3450  for ( int j = 0; j < numInPlaneIP; j++ ) {
3451 
3452  // thickness GPs
3453  for ( int i = 0; i < numThicknessIP; i++ ) {
3454 
3455  int point = i*numInPlaneIP + j; // wedge integration point number
3456  IntegrationPoint *ip = iRule->getIntegrationPoint(point);
3457  // Collect IP-value
3458  FloatArray tempIPvalues;
3459  this->giveIPValue(tempIPvalues, ip, IST_StressTensor, tStep);
3460 
3461  for ( int iInt = layer-1 ; iInt <= layer ; iInt++ ) {
3462  if ( iInt > 0 && iInt < numberOfLayers ) {
3463  transverseStress[iInt-1].at(1,j+1) += (0.5/numThicknessIP)*tempIPvalues.at(5);
3464  transverseStress[iInt-1].at(2,j+1) += (0.5/numThicknessIP)*tempIPvalues.at(4);
3465  transverseStress[iInt-1].at(3,j+1) += (0.5/numThicknessIP)*tempIPvalues.at(3);
3466  }
3467  }
3468  }
3469  }
3470  }
3471 }
3472 
3473 
3474 void
3475 Shell7BaseXFEM :: giveRecoveredTransverseInterfaceStress(std::vector<FloatMatrix> &transverseStress, TimeStep *tStep)
3476 {
3477  transverseStress.clear();
3478  // Recover shear stresses at ip by numerical integration of the momentum balance through the thickness (overloaded from shell7base)
3479 
3480  int numberOfLayers = this->layeredCS->giveNumberOfLayers();
3481 
3482  IntArray delaminationInterface; delaminationInterface.clear(); // interface (starting from 1) which contains delamination
3483  IntArray interfaceEI(numberOfLayers-1);
3484 
3485  bool hasDelamination = false;
3486  int numEI = this->xMan->giveNumberOfEnrichmentItems();
3487  for ( int iEI = 1; iEI <= numEI; iEI++ ) {
3488 
3489  EnrichmentItem *ei = this->xMan->giveEnrichmentItem(iEI);
3490  if ( ei->isElementEnriched(this) ) {
3491  hasDelamination = true;
3492  // Find cohesive material (for delamination)
3493  Delamination *dei = dynamic_cast< Delamination * >( ei );
3494  int delaminationInterfaceNum = dei->giveDelamInterfaceNum();
3495  delaminationInterface.followedBy(delaminationInterfaceNum);
3496  interfaceEI.at(delaminationInterfaceNum) = iEI;
3497  }
3498  }
3499  delaminationInterface.sort();
3500 
3501  if ( hasDelamination ) {
3502  transverseStress.resize(numberOfLayers-1);
3503 
3504  int numInPlaneIP = 6;
3505  int numThicknessIP = this->layeredCS->giveNumIntegrationPointsInLayer();
3506  if (numThicknessIP < 2) {
3507  // Polynomial fit involves linear z-component at the moment
3508  OOFEM_ERROR("To few thickness IP per layer to do polynomial fit");
3509  }
3510 
3511  int numDel = delaminationInterface.giveSize();
3512 
3513  // Find top and bottom BC NB: assumes constant over element surface.
3514  // traction BC added to vector of BC.
3515  std::vector <FloatMatrix> tractionBC; tractionBC.resize(numDel+2);
3516  tractionBC[numDel+1].resize(3,numInPlaneIP);
3517  tractionBC[0].resize(3,numInPlaneIP);
3518  giveTractionBC(tractionBC[numDel+1],tractionBC[0], tStep);
3519 
3520  // Find delamination traction BC
3521  for (int iDel = 1 ; iDel <= numDel ; iDel++) {
3522 
3523  tractionBC[iDel].resize(3,numInPlaneIP);
3524 
3525  int interfaceNum = delaminationInterface.at(iDel);
3526  EnrichmentItem *ei = this->xMan->giveEnrichmentItem(interfaceEI.at(interfaceNum));
3527  Delamination *dei = dynamic_cast< Delamination * >( ei );
3528 
3529  if ( this->hasCohesiveZone( interfaceNum ) ) {
3530  // CZ traction
3531  std :: unique_ptr< IntegrationRule > &iRuleI = this->czIntegrationRulesArray [ interfaceNum - 1 ];
3532  if (czIntegrationRulesArray [ interfaceNum - 1 ]->giveNumberOfIntegrationPoints() != numInPlaneIP ) {
3533  OOFEM_ERROR("Interface IPs doesn't match the element IPs");
3534  }
3535  StructuralInterfaceMaterial *intMat = dynamic_cast < StructuralInterfaceMaterial * >
3536  (this->layeredCS->giveInterfaceMaterial(interfaceNum) );
3537 
3538  FloatArray lCoords(3), nCov, CZPKtraction(3);
3539  CZPKtraction.zero();
3540  FloatMatrix Q;
3541  int iIGP = 1;
3542  for ( GaussPoint *gp : *iRuleI ) {
3543  double xi = dei->giveDelamXiCoord();
3544  lCoords.at(1) = gp->giveNaturalCoordinate(1);
3545  lCoords.at(2) = gp->giveNaturalCoordinate(2);
3546  lCoords.at(3) = xi;
3547 
3548  // Find PK-traction in current coords.
3549  FloatArray solVecC;
3550  this->giveUpdatedSolutionVector(solVecC, tStep);
3551  FloatMatrix B;
3552  this->computeEnrichedBmatrixAt(lCoords, B, NULL); // NULL => Shell7base :: computeBmatrixAt, otherwise include dei
3553  FloatArray genEpsC;
3554  genEpsC.beProductOf(B, solVecC);
3555  this->evalCovarNormalAt(nCov, lCoords, genEpsC, tStep); // Denna verkar ta hänsyn till hoppet, men hur ser jag till att det är normalen ovanför delamineringen?
3556  Q.beLocalCoordSys(nCov);
3557 
3558 #if 0
3559  // Compute 1PK traction from jump vector
3560  FloatArray jump;
3561  this->computeInterfaceJumpAt(dei->giveDelamInterfaceNum(), lCoords, tStep, jump); // -> numerical tol. issue -> normal jump = 1e-10
3562 
3563  genEpsC.beProductOf(B, solVecC);
3564  FloatMatrix F;
3565  this->computeFAt(lCoords, F, genEpsC, tStep);
3566 
3567  // Transform xd and F to a local coord system
3568  this->evalInitialCovarNormalAt(nCov, lCoords);
3569  Q.beLocalCoordSys(nCov);
3570  jump.rotatedWith(Q,'n');
3571  F.rotatedWith(Q,'n');
3572 
3573  // Compute cohesive traction based on jump
3574  intMat->giveFirstPKTraction_3d(CZPKtraction, gp, jump, F, tStep);
3575 #else
3576  // Get 1PK traction directly from interface material status.
3577  StructuralInterfaceMaterialStatus *intMatStatus = dynamic_cast < StructuralInterfaceMaterialStatus * >( intMat->giveStatus(gp) );
3578  if (intMatStatus == 0) {
3579  OOFEM_ERROR("NULL pointer to interface material, shell element %i",this->giveGlobalNumber());
3580  }
3581  CZPKtraction = intMatStatus->giveTempFirstPKTraction(); // 3 components in local coords
3582 #endif
3583 
3584  CZPKtraction.rotatedWith(Q,'t'); // transform back to global coord system
3585 
3586  // Set BC stresses
3587  tractionBC[iDel].at(1,iIGP) = CZPKtraction.at(1);
3588  tractionBC[iDel].at(2,iIGP) = CZPKtraction.at(2);
3589  tractionBC[iDel].at(3,iIGP) = CZPKtraction.at(3);
3590  iIGP++;
3591  }
3592 
3593  } else {
3594  // Delamination zero traction
3595  tractionBC[iDel].zero();
3596  }
3597  }
3598 
3599  FloatMatrix SmatOld(3,numInPlaneIP); // 3 stress components (S_xz, S_yz, S_zz) * num of in plane ip
3600  double totalThickness = this->layeredCS->computeIntegralThick();
3601  double zeroThicknessLevel = - 0.5 * totalThickness; // assumes midplane is the geometric midplane of layered structure.
3602  FloatMatrix dSmat(3,numInPlaneIP); // 3 stress components (S_xz, S_yz, S_zz) * num of in plane ip
3603  FloatMatrix dSmatLayerIP(3,numInPlaneIP*numThicknessIP); // 3 stress components (S_xz, S_yz, S_zz) * num of wedge ip
3604 
3605  int layerOld = 0;
3606  int iInt = 0;
3607  delaminationInterface.followedBy(numberOfLayers); // creates an array of the layer index of the top layer in a delamination (NB: index = numberOfLayers will allways be the last)
3608  for ( int topLayer : delaminationInterface) {
3609  SmatOld = tractionBC[iInt]; // bottom traction BC of delamination
3610  int numDelLayers = topLayer-layerOld; // number of layers in delamination
3611  std::vector <FloatMatrix> dSmatIP; dSmatIP.resize(numDelLayers); //recovered stress values in wedge IPs
3612  std::vector <FloatMatrix> dSmat; dSmat.resize(numDelLayers); //recovered stress values at delamination top
3613  std::vector <FloatMatrix> dSmatIPupd; dSmatIPupd.resize(numDelLayers); //recovered stress values in wedge IPs adjusted for top and btm traction BC.
3614  std::vector <FloatMatrix> dSmatupd; dSmatupd.resize(numDelLayers); //recovered stress values at delamination top, adjusted for top and btm traction BC
3615 
3616  // Recovered stresses in delaminated layers
3617  double dz = 0.0;
3618  for ( int delLayer = 1 ; delLayer <= numDelLayers; delLayer++ ) {
3619 
3620  this->giveLayerContributionToSR(dSmat[delLayer-1], dSmatIP[delLayer-1], delLayer+layerOld, zeroThicknessLevel + dz, tStep);
3621  SmatOld.add(dSmat[delLayer-1]); // Integrated stress over laminate
3622  dz += this->layeredCS->giveLayerThickness(delLayer+layerOld);
3623 
3624  }
3625 
3626  // Adjust recovered stresses to traction BC (divide integration error 50/50 at top and btm of delamination)
3627 
3628  this->fitRecoveredStress2BC(dSmatIPupd, dSmatupd, dSmat, dSmatIP, SmatOld, tractionBC[iInt], tractionBC[iInt+1], zeroThicknessLevel, {0.0,0.0,1.0}, layerOld+1, topLayer);
3629 
3630  for ( int delLayer = 1 ; delLayer <= numDelLayers; delLayer++ ) {
3631  if ( (delLayer + layerOld) < numberOfLayers ) {
3632  transverseStress[delLayer+layerOld-1] = dSmatupd[delLayer-1];
3633  }
3634  }
3635 
3636  zeroThicknessLevel += dz;
3637  layerOld = topLayer;
3638  iInt++;
3639  }
3640 
3641  } else {
3642  Shell7Base :: giveRecoveredTransverseInterfaceStress(transverseStress, tStep);
3643  }
3644 
3645 }
3646 
3647 
3648 } // end namespace oofem
void setInternalVarInNode(int varNum, int nodeNum, FloatArray valueArray)
CrossSection * giveCrossSection()
Definition: element.C:495
void setInternalXFEMVarInNode(int varNum, int eiNum, int nodeNum, FloatArray valueArray)
void evalInitialContravarBaseVectorsAt(const FloatArray &lCoords, FloatMatrix &Gcon)
Definition: shell7base.C:274
double evaluateHeavisideXi(double xi, ShellCrack *ei)
virtual void giveFailedInterfaceNumber(IntArray &failedInterfaces, FloatArray &initiationFactor, TimeStep *tStep, bool recoverStresses=true)
InternalStateType
Type representing the physical meaning of element or constitutive model internal variable.
std::vector< Triangle > allTri
int giveNumberOfColumns() const
Returns number of columns of receiver.
Definition: floatmatrix.h:158
void setCellVar(int varNum, int cellNum, FloatArray valueArray)
void computeCohesiveTangent(FloatMatrix &answer, TimeStep *tStep)
void subtract(const FloatArray &src)
Subtracts array src to receiver.
Definition: floatarray.C:258
virtual IRResultType initializeFrom(InputRecord *ir)
Initializes receiver according to object description stored in input record.
Definition: shell7base.C:63
void computeLambdaGMatricesDis(FloatMatrix lambdaD[3], double zeta)
bool isElementEnriched(const Element *element) const
Abstract class representing entity, which is included in the FE model using one (or more) global func...
virtual void evaldNdxi(FloatMatrix &answer, const FloatArray &lcoords, const FEICellGeometry &cellgeo)
Evaluates the matrix of derivatives of interpolation functions (shape functions) at given point...
Definition: feinterpol.h:193
void giveFictiousNodeCoordsForExport(std::vector< FloatArray > &nodes, int layer, int subCell)
virtual MaterialStatus * giveStatus(GaussPoint *gp) const
Returns material status of receiver in given integration point.
Definition: material.C:244
bool evalNodeEnrMarkerInNode(double &oNodeEnrMarker, int iNodeInd) const
virtual void evalN(FloatArray &answer, const FloatArray &lcoords, const FEICellGeometry &cellgeo)=0
Evaluates the array of interpolation functions (shape functions) at given point.
double giveDelamXiCoord() const
Definition: delamination.h:86
FloatArray convV6ToV9Stress(const FloatArray &V6)
Definition: shell7base.C:3187
void beVectorProductOf(const FloatArray &v1, const FloatArray &v2)
Computes vector product (or cross product) of vectors given as parameters, , and stores the result in...
Definition: floatarray.C:415
void giveMaxCZDamages(FloatArray &answer, TimeStep *tStep)
Class and object Domain.
Definition: domain.h:115
virtual void give3dStiffnessMatrix_dTdj(FloatMatrix &answer, MatResponseMode rMode, GaussPoint *gp, TimeStep *tStep)
void computeVectorOf(ValueModeType u, TimeStep *tStep, FloatArray &answer)
Returns local vector of unknowns.
Definition: element.C:86
bool isDofManEnriched(const DofManager &iDMan) const
void giveUnknownsAt(const FloatArray &lcoords, FloatArray &solVec, FloatArray &x, FloatArray &m, double &gam, TimeStep *tStep)
Definition: shell7base.C:1620
int giveGlobalNumber() const
Definition: dofmanager.h:501
Domain * domain
Link to domain object, useful for communicating with other FEM components.
Definition: femcmpnn.h:82
void computeCohesiveNmatrixAt(const FloatArray &lCoords, FloatMatrix &answer, EnrichmentItem *ei)
virtual void evalCovarBaseVectorsAt(const FloatArray &lCoords, FloatMatrix &gcon, FloatArray &solVec, TimeStep *tStep)
virtual void vtkEvalInitialGlobalCZCoordinateAt(const FloatArray &localCoords, int interface, FloatArray &globalCoords)
Definition: shell7base.C:1828
std::vector< std::vector< Triangle > > crackSubdivisions
virtual void updateYourself(TimeStep *tStep)
Updates element state after equilibrium in time step has been reached.
int giveDelamInterfaceNum() const
Definition: delamination.h:88
void computeStressMatrix(FloatMatrix &answer, FloatArray &genEps, GaussPoint *gp, Material *mat, TimeStep *tStep)
Definition: shell7base.C:725
Provides Xfem interface for an element.
virtual int giveNumberOfEdgeDofManagers()=0
Load is specified in global c.s.
Definition: load.h:70
void setNumberOfNodes(int numNodes)
virtual Interface * giveInterface(InterfaceType it)
Interface requesting service.
virtual void evaluateEnrFuncAt(std::vector< double > &oEnrFunc, const FloatArray &iGlobalCoord, const FloatArray &iLocalCoord, int iNodeInd, const Element &iEl) const =0
virtual void evaluateEnrFuncAt(std::vector< double > &oEnrFunc, const FloatArray &iGlobalCoord, const FloatArray &iLocalCoord, int iNodeInd, const Element &iEl) const
Definition: delamination.C:334
double & at(int i)
Coefficient access function.
Definition: floatarray.h:131
void giveFictiousCZNodeCoordsForExport(std::vector< FloatArray > &nodes, int layer, int subCell)
int max(int i, int j)
Returns bigger value form two given decimals.
Definition: mathfem.h:71
virtual void giveAverageTransverseInterfaceStress(std::vector< FloatMatrix > &transverseStress, TimeStep *tStep)
virtual void giveRecoveredTransverseInterfaceStress(std::vector< FloatMatrix > &transverseStress, TimeStep *tStep)
Definition: shell7base.C:2372
void beSubMatrixOf(const FloatMatrix &src, int topRow, int bottomRow, int topCol, int bottomCol)
Assigns to the receiver the sub-matrix of another matrix.
Definition: floatmatrix.C:962
int giveGlobalNumber() const
Definition: element.h:1059
ValueModeType
Type representing the mode of UnknownType or CharType, or similar types.
Definition: valuemodetype.h:78
void computeEnrTractionForce(FloatArray &answer, const int iedge, BoundaryLoad *edgeLoad, TimeStep *tStep, ValueModeType mode, EnrichmentItem *ei)
Shell7BaseXFEM(int n, Domain *d)
This class implements a boundary load (force, moment,...) that acts directly on a boundary of some fi...
void setNumberOfInternalVarsToExport(int numVars, int numNodes)
void computeFailureCriteriaQuantities(FailureCriteriaStatus *fc, TimeStep *tStep)
void computeSectionalForcesAt(FloatArray &sectionalForces, IntegrationPoint *ip, Material *mat, TimeStep *tStep, FloatArray &genEps, double zeta)
void giveFictiousCZNodeCoordsForExport(std::vector< FloatArray > &nodes, int interface)
Definition: shell7base.C:3142
void clear()
Clears receiver (zero size).
Definition: floatarray.h:206
int giveInterpolationOrder()
Returns the interpolation order.
Definition: feinterpol.h:159
LayeredCrossSection * layeredCS
Definition: shell7base.h:107
virtual Interface * giveInterface(InterfaceType it)
Interface requesting service.
Definition: shell7base.C:120
virtual void giveLocalNodeCoords(FloatMatrix &answer)
Returns a matrix containing the local coordinates for each node corresponding to the interpolation...
virtual void giveDofManDofIDMask(int inode, IntArray &) const
Returns dofmanager dof mask for node.
Definition: shell7base.C:145
ConnectivityTable * giveConnectivityTable()
Returns receiver&#39;s associated connectivity table.
Definition: domain.C:1170
virtual void computeValueAt(FloatArray &answer, TimeStep *tStep, const FloatArray &coords, ValueModeType mode)=0
Computes components values of load at given point - global coordinates (coordinates given)...
virtual int checkConsistency()
Performs consistency check.
Definition: shell7base.C:75
virtual FloatArray * giveCoordinates()
Definition: dofmanager.h:382
virtual CoordSystType giveCoordSystMode()
Returns receiver&#39;s coordinate system.
Definition: boundaryload.h:151
void computeInterfaceJumpAt(int interf, FloatArray &lCoords, TimeStep *tStep, FloatArray &answer)
Delamination.
Definition: delamination.h:58
virtual bool hasField(InputFieldType id)=0
Returns true if record contains field identified by idString keyword.
const FloatArray & giveFirstPKTraction() const
Returns the const pointer to receiver&#39;s first Piola-Kirchhoff traction vector.
InternalStateValueType
Determines the type of internal variable.
virtual int giveNumberOfDofs()
Definition: shell7base.C:152
Base class for dof managers.
Definition: dofmanager.h:113
virtual void edgeComputeBmatrixAt(const FloatArray &lCoords, FloatMatrix &answer, int li=1, int ui=ALL_STRAINS)
Definition: shell7base.C:1672
void jump(FloatMatrix lambda, FloatArray deltaUnknowns)
virtual void giveCZExportData(VTKPiece &vtkPiece, IntArray &primaryVarsToExport, IntArray &internalVarsToExport, IntArray cellVarsToExport, TimeStep *tStep)
void computeLinearizedStiffness(GaussPoint *gp, StructuralMaterial *mat, TimeStep *tStep, FloatMatrix A[3][3])
Definition: shell7base.C:585
virtual IRResultType initializeFrom(InputRecord *ir)
Initializes receiver according to object description stored in input record.
virtual void giveLocalNodeCoords(FloatMatrix &answer)
Returns a matrix containing the local coordinates for each node corresponding to the interpolation...
Definition: fei3dtrquad.C:103
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 setNumberOfCells(int numCells)
int giveInternalStateTypeSize(InternalStateValueType valType)
Definition: cltypes.C:217
XfemManager * giveXfemManager()
Definition: domain.C:375
void giveInterfaceXiCoords(FloatArray &answer)
virtual int giveNumberOfDofManagers() const
Definition: element.h:656
virtual int computeGlobalCoordinates(FloatArray &answer, const FloatArray &lcoords)
Computes the global coordinates from given element&#39;s local coordinates.
Definition: shell7base.C:158
virtual FEInterpolation * giveInterpolation() const
Definition: element.h:629
FEInterpolation3d * fei
Definition: shell7base.h:112
virtual void edgeGiveUpdatedSolutionVector(FloatArray &answer, const int iedge, TimeStep *tStep)
Definition: shell7base.C:1563
virtual void discComputeBulkTangentMatrix(FloatMatrix &KdIJ, IntegrationPoint *ip, EnrichmentItem *eiI, EnrichmentItem *eiJ, int layer, FloatMatrix A[3][3], TimeStep *tStep)
virtual void edgeEvaldNdxi(FloatArray &answer, int iedge, const FloatArray &lcoords, const FEICellGeometry &cellgeo)
Evaluates the matrix of derivatives of edge interpolation functions (shape functions) at given point...
Definition: feinterpol3d.C:123
virtual void recoverShearStress(TimeStep *tStep)
Definition: shell7base.C:2250
virtual void edgeLocal2global(FloatArray &answer, int iedge, const FloatArray &lcoords, const FEICellGeometry &cellgeo)=0
Evaluates edge global coordinates from given local ones.
void rotatedWith(FloatMatrix &r, char mode)
Returns the receiver a rotated according the change-of-base matrix r.
Definition: floatarray.C:799
Abstract base class representing integration rule.
This class implements a layered cross section in a finite element problem.
void sort()
Sorts array.
Definition: intarray.C:420
virtual double computeVolumeAroundLayer(GaussPoint *mastergp, int layer)=0
void NodalRecoveryMI_recoverValues(std::vector< FloatArray > &recoveredValues, int layer, InternalStateType type, TimeStep *tStep)
Definition: shell7base.C:1464
LayeredCrossSection * giveLayeredCS()
Definition: shell7base.h:98
void beDifferenceOf(const FloatArray &a, const FloatArray &b)
Sets receiver to be a - b.
Definition: floatarray.C:341
void setSubMatrix(const FloatMatrix &src, int sr, int sc)
Adds the given matrix as sub-matrix to receiver.
Definition: floatmatrix.C:557
virtual const IntArray & giveOrderingNodes() const =0
void computePressureTangentMatrixDis(FloatMatrix &KCC, FloatMatrix &KCD, FloatMatrix &KDD, IntegrationPoint *ip, Load *load, const int iSurf, TimeStep *tStep)
void computeDiscSolutionVector(IntArray &dofIdArray, TimeStep *tStep, FloatArray &solVecD)
void beColumnOf(const FloatMatrix &mat, int col)
Reciever will be set to a given column in a matrix.
Definition: floatarray.C:1114
virtual int giveIPValue(FloatArray &answer, GaussPoint *gp, InternalStateType type, TimeStep *tStep)
Returns the integration point corresponding value in full form.
Definition: shell7base.C:764
void setNodeCoords(int nodeNum, FloatArray &coords)
virtual void discComputeStiffness(FloatMatrix &LCC, FloatMatrix &LDD, FloatMatrix &LDC, IntegrationPoint *ip, int layer, FloatMatrix A[3][3], TimeStep *tStep)
void giveFictiousUpdatedNodeCoordsForExport(std::vector< FloatArray > &nodes, int layer, TimeStep *tStep, int subCell)
virtual int giveIPValue(FloatArray &answer, GaussPoint *gp, InternalStateType type, TimeStep *tStep)
Returns the integration point corresponding value in Reduced form.
double distance(const FloatArray &x) const
Computes the distance between position represented by receiver and position given as parameter...
Definition: floatarray.C:489
int giveNumberOfEnrichmentItems() const
Definition: xfemmanager.h:185
void mapXi3FromLocalToShell(FloatArray &answer, FloatArray &local, int layer)
void plusProductUnsym(const FloatMatrix &a, const FloatMatrix &b, double dV)
Adds to the receiver the product .
Definition: floatmatrix.C:780
double computeIntegralThick()
Returns the total thickness of all layers.
void computeSectionalForces(FloatArray &answer, TimeStep *tStep, FloatArray &solVec, int useUpdatedGpRecord=0)
Definition: shell7base.C:800
virtual double give(int aProperty, GaussPoint *gp)
Returns the value of material property &#39;aProperty&#39;.
Definition: material.C:52
void computeMassMatrixNum(FloatMatrix &answer, TimeStep *tStep)
virtual void giveEdgeDofMapping(IntArray &answer, int iEdge) const =0
Assembles edge dof mapping mask, which provides mapping between edge local DOFs and "global" element ...
FEI3dWedgeQuad interpolationForExport
void setCellType(int cellNum, int type)
double giveNaturalCoordinate(int i) const
Returns i-th natural element coordinate of receiver.
Definition: gausspoint.h:136
bool hasCohesiveZone(int interfaceNum)
void setNumberOfInternalXFEMVarsToExport(int numVars, int numEnrichmentItems, int numNodes)
Crack.
Definition: crack.h:54
const IntArray & giveDofManArray() const
Definition: element.h:592
virtual void evalCovarNormalAt(FloatArray &nCov, const FloatArray &lCoords, FloatArray &genEpsC, TimeStep *tStep)
Definition: shell7base.C:1243
virtual void giveFirstPKTraction_3d(FloatArray &answer, GaussPoint *gp, const FloatArray &jump, const FloatMatrix &F, TimeStep *tStep)
void setNumberOfPrimaryVarsToExport(int numVars, int numNodes)
Abstract base class representing a boundary load (force, momentum, ...) that acts directly on a bound...
Definition: boundaryload.h:110
void giveUpdatedSolutionVector(FloatArray &answer, TimeStep *tStep)
Definition: shell7base.C:1525
Material * giveMaterial(int n)
Service for accessing particular domain material model.
Definition: domain.C:281
Element * giveElement(int n)
Service for accessing particular domain fe element.
Definition: domain.C:160
std::vector< IntArray > orderingArrays
double dotProduct(const FloatArray &x) const
Computes the dot product (or inner product) of receiver and argument.
Definition: floatarray.C:463
virtual const IntArray & giveOrderingDofTypes() const =0
#define OOFEM_ERROR(...)
Definition: error.h:61
double giveLayerThickness(int layer)
void clear()
Clears the array (zero size).
Definition: intarray.h:177
virtual void edgeComputeNmatrixAt(const FloatArray &lCoords, FloatMatrix &answer)
Definition: shell7base.C:1642
void setNumberOfCellVarsToExport(int numVars, int numCells)
int giveInterfaceMaterialNum(int interface)
DofIDItem
Type representing particular dof type.
Definition: dofiditem.h:86
void giveLocalNodeCoordsForExport(FloatArray &nodeLocalXi1Coords, FloatArray &nodeLocalXi2Coords, FloatArray &nodeLocalXi3Coords, int subCell, int layer, FloatMatrix &localNodeCoords)
UnknownType
Type representing particular unknown (its physical meaning).
Definition: unknowntype.h:55
void times(double f)
Multiplies receiver by factor f.
Definition: floatmatrix.C:1594
void computeBoundaryEdgeLoadVector(FloatArray &answer, BoundaryLoad *load, int boundary, CharType type, ValueModeType mode, TimeStep *tStep, bool global)
Computes the contribution of the given load at the given boundary edge.
std::vector< IntArray > activeDofsArrays
void rotatedWith(const FloatMatrix &r, char mode= 'n')
Returns the receiver &#39;a&#39; transformed using give transformation matrix r.
Definition: floatmatrix.C:1557
void addProductOf(const FloatMatrix &a, const FloatMatrix &b)
Adds to the receiver product of .
Definition: floatmatrix.C:427
bool evalLevelSetNormalInNode(double &oLevelSet, int iNodeInd, const FloatArray &iGlobalCoord) const
CoordSystType
Load coordinate system type.
Definition: load.h:69
Class representing connectivity table.
Wrapper around element definition to provide FEICellGeometry interface.
Definition: feinterpol.h:95
virtual void edgeGiveUpdatedSolutionVector(FloatArray &answer, const int iedge, TimeStep *tStep)
virtual void evalCovarBaseVectorsAt(const FloatArray &lCoords, FloatMatrix &gcov, FloatArray &genEps, TimeStep *tStep)
Definition: shell7base.C:357
virtual int global2local(FloatArray &answer, const FloatArray &gcoords, const FEICellGeometry &cellgeo)=0
Evaluates local coordinates from given global ones.
void beLocalCoordSys(const FloatArray &normal)
Makes receiver the local coordinate for the given normal.
Definition: floatmatrix.C:515
void beProductOf(const FloatMatrix &aMatrix, const FloatArray &anArray)
Receiver becomes the result of the product of aMatrix and anArray.
Definition: floatarray.C:676
void recoverShearStress(TimeStep *tStep)
virtual int checkConsistency()
Performs consistency check.
double evaluateCutHeaviside(const double xi, const double xiBottom, const double xiTop) const
This class implements a structural interface material status information.
#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
void giveLayerContributionToSR(FloatMatrix &dSmat, FloatMatrix &dSmatLayerIP, int layer, double zeroThicknessLevel, TimeStep *tStep)
Definition: shell7base.C:2455
virtual void computeStiffnessMatrix(FloatMatrix &answer, MatResponseMode rMode, TimeStep *tStep)
Computes the stiffness matrix of receiver.
void resizeWithValues(int s, int allocChunk=0)
Checks size of receiver towards requested bounds.
Definition: floatarray.C:615
virtual int giveApproxOrder()=0
void computeEnrichedNmatrixAt(const FloatArray &lCoords, FloatMatrix &answer, EnrichmentItem *ei)
void beTProductOf(const FloatMatrix &aMatrix, const FloatArray &anArray)
Receiver becomes the result of the product of aMatrix^T and anArray.
Definition: floatarray.C:708
Abstract base class for all material models.
Definition: material.h:95
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
virtual void OLDcomputeStiffnessMatrix(FloatMatrix &answer, MatResponseMode rMode, TimeStep *tStep)
virtual void giveShellExportData(VTKPiece &vtkPiece, IntArray &primaryVarsToExport, IntArray &internalVarsToExport, IntArray cellVarsToExport, TimeStep *tStep)
void giveElementNeighbourList(IntArray &answer, IntArray &elemList)
Returns list of neighboring elements to given elements (they are included too).
std::vector< std::unique_ptr< IntegrationRule > > czIntegrationRulesArray
void giveFictiousNodeCoordsForExport(std::vector< FloatArray > &nodes, int layer)
Definition: shell7base.C:3122
virtual void computeTractionForce(FloatArray &answer, const int iedge, BoundaryLoad *edgeLoad, TimeStep *tStep, ValueModeType mode, bool map2elementDOFs=false)
Definition: shell7base.C:1267
void computeDiscGeneralizedStrainVector(FloatArray &dGenEps, const FloatArray &lCoords, EnrichmentItem *ei, TimeStep *tStep)
void setPrimaryVarInNode(int varNum, int nodeNum, FloatArray valueArray)
int numberOfGaussPoints
Number of integration points as specified by nip.
Definition: element.h:188
void computeCohesiveTangentAt(FloatMatrix &answer, TimeStep *tStep, Delamination *dei, EnrichmentItem *ei_j, EnrichmentItem *ei_k)
void subtract(const FloatMatrix &a)
Subtracts matrix from the receiver.
Definition: floatmatrix.C:1084
virtual void evalInitialCovarNormalAt(FloatArray &nCov, const FloatArray &lCoords)
Definition: shell7base.C:1255
Symmetric 3x3 tensor.
bool evalLevelSetTangInNode(double &oLevelSet, int iNodeInd, const FloatArray &iGlobalCoord) const
virtual int computeNumberOfDofs()
Computes or simply returns total number of element&#39;s local DOFs.
Definition: shell7base.h:77
Class representing vector of real numbers.
Definition: floatarray.h:82
virtual void vtkEvalUpdatedGlobalCoordinateAt(const FloatArray &localCoords, int layer, FloatArray &globalCoords, TimeStep *tStep)
Load is specified in global c.s. but follows the deformation.
Definition: load.h:72
void computeLambdaNMatrixDis(FloatMatrix &lambda_xd, double zeta)
void giveDisUnknownsAt(const FloatArray &lCoords, EnrichmentItem *ei, FloatArray &solVec, FloatArray &x, FloatArray &m, double &gam, TimeStep *tStep)
int findSorted(int value) const
Finds the first occurrence of given value, assuming that the receiver is sorted.
Definition: intarray.C:344
void computeOrderingArray(IntArray &orderingArray, IntArray &activeDofsArray, EnrichmentItem *ei)
Implementation of matrix containing floating point numbers.
Definition: floatmatrix.h:94
double giveBoundingDelamXiCoord() const
Definition: delamination.h:87
IntArray DelaminatedInterfaceList
void interpLevelSet(double &oLevelSet, const FloatArray &iN, const IntArray &iNodeInd) const
Definition: hybridei.C:70
This class manages the xfem part.
Definition: xfemmanager.h:109
virtual void vtkEvalInitialGlobalCoordinateAt(const FloatArray &localCoords, int layer, FloatArray &globalCoords)
Definition: shell7base.C:1812
IRResultType
Type defining the return values of InputRecord reading operations.
Definition: irresulttype.h:47
GaussPoint * getIntegrationPoint(int n)
Access particular integration point of receiver.
virtual void updateYourself(TimeStep *tStep)
Updates element state after equilibrium in time step has been reached.
static void computeIPAverage(FloatArray &answer, IntegrationRule *iRule, Element *elem, InternalStateType isType, TimeStep *tStep)
Computes a cell average of an InternalStateType varible based on the weights in the integrationpoints...
IntArray vtkExportFields
List with the fields that should be exported to VTK.
Definition: xfemmanager.h:167
void setOffset(int cellNum, int offset)
virtual double giveGlobalZcoord(const FloatArray &lCoords)
Definition: shell7base.C:202
const FloatArray & giveNodeCoordinates() const
As giveCoordinates, but non-virtual and therefore faster (because it can be inlined).
Definition: node.h:120
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 edgeComputeEnrichedBmatrixAt(const FloatArray &lCoords, FloatMatrix &answer, EnrichmentItem *ei, const int edge)
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
virtual int giveNumberOfDofs()
This class represent a 7 parameter shell element.
Definition: shell7base.h:68
virtual double computeAreaAround(GaussPoint *gp, double xi)=0
CharType
Definition: chartype.h:87
void resize(int rows, int cols)
Checks size of receiver towards requested bounds.
Definition: floatmatrix.C:1358
Class representing the general Input Record.
Definition: inputrecord.h:101
virtual void printYourself() const
Print receiver on stdout.
Definition: floatarray.C:747
Class representing a general abstraction for surface finite element interpolation class...
Definition: feinterpol3d.h:44
std::vector< Dof * >::const_iterator findDofWithDofId(DofIDItem dofID) const
Finds index of DOF with required physical meaning of receiver.
Definition: dofmanager.C:266
void fitRecoveredStress2BC(std::vector< FloatMatrix > &answer1, std::vector< FloatMatrix > &answer2, std::vector< FloatMatrix > &dSmat, std::vector< FloatMatrix > &dSmatIP, FloatMatrix &SmatOld, FloatMatrix &tractionBtm, FloatMatrix &tractionTop, double zeroThicknessLevel, FloatArray fulfillBC, int startLayer, int endLayer)
Definition: shell7base.C:2793
std::vector< Dof * >::iterator begin()
Definition: dofmanager.h:157
void add(const FloatMatrix &a)
Adds matrix to the receiver.
Definition: floatmatrix.C:1023
Class Interface.
Definition: interface.h:82
XFEMStateType
Definition: xfemmanager.h:92
void followedBy(const IntArray &b, int allocChunk=0)
Appends array b at the end of receiver.
Definition: intarray.C:145
int giveNumberOfIntegrationPoints() const
Returns number of integration points of receiver.
void zero()
Zeroes all coefficients of receiver.
Definition: floatarray.C:658
void computeFAt(const FloatArray &lCoords, FloatMatrix &answer, FloatArray &genEps, TimeStep *tStep)
Definition: shell7base.C:715
virtual void computeBmatrixAt(GaussPoint *gp, FloatMatrix &answer, int li=1, int ui=ALL_STRAINS)
Computes the geometrical matrix of receiver in given integration point.
Definition: shell7base.h:272
virtual void edgeEvalN(FloatArray &answer, int iedge, const FloatArray &lcoords, const FEICellGeometry &cellgeo)=0
Evaluates the array of edge interpolation functions (shape functions) at given point.
void beTProductOf(const FloatMatrix &a, const FloatMatrix &b)
Assigns to the receiver product of .
Definition: floatmatrix.C:367
void edgeComputeEnrichedNmatrixAt(const FloatArray &lCoords, FloatMatrix &answer, EnrichmentItem *ei, const int edge)
const FloatArray & giveTempFirstPKTraction() const
Returns the const pointer to receiver&#39;s temporary first Piola-Kirchhoff traction vector.
void giveInternalForcesVector(FloatArray &answer, TimeStep *tStep, int useUpdatedGpRecord)
Evaluates nodal representation of real internal forces.
void times(double s)
Multiplies receiver with scalar.
Definition: floatarray.C:818
double evaluateLevelSet(const FloatArray &lCoords, EnrichmentItem *ei)
void beTranspositionOf(const FloatMatrix &src)
Assigns to the receiver the transposition of parameter.
Definition: floatmatrix.C:323
EnrichmentItem * giveEnrichmentItem(int n)
Definition: xfemmanager.h:184
virtual void computeBulkTangentMatrix(FloatMatrix &answer, FloatArray &solVec, TimeStep *tStep)
Definition: shell7base.C:533
virtual void giveRecoveredTransverseInterfaceStress(std::vector< FloatMatrix > &transverseStress, TimeStep *tStep)
virtual bool computeLocalCoordinates(FloatArray &answer, const FloatArray &gcoords)
Computes the element local coordinates from given global coordinates.
Definition: element.C:1222
void printYourself() const
Prints matrix to stdout. Useful for debugging.
Definition: floatmatrix.C:1458
void recoverValuesFromIP(std::vector< FloatArray > &nodes, int layer, InternalStateType type, TimeStep *tStep, stressRecoveryType SRtype=copyIPvalue)
Definition: shell7base.C:1980
Abstract base class for all "structural" constitutive models.
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 postInitialize()
Performs post initialization steps.
virtual void giveDofManDofIDMask(int inode, IntArray &answer) const
Returns dofmanager dof mask for node.
virtual void giveCompositeExportData(std::vector< VTKPiece > &vtkPieces, IntArray &primaryVarsToExport, IntArray &internalVarsToExport, IntArray cellVarsToExport, TimeStep *tStep)
void zero()
Zeroes all coefficient of receiver.
Definition: floatmatrix.C:1326
Domain * giveDomain() const
Definition: femcmpnn.h:100
InterfaceType
Enumerative type, used to identify interface type.
Definition: interfacetype.h:43
void setConnectivity(int cellNum, IntArray &nodes)
void computeEnrichedBmatrixAt(const FloatArray &lCoords, FloatMatrix &answer, EnrichmentItem *ei)
double EvaluateEnrFuncInDofMan(int dofManNum, EnrichmentItem *ei)
virtual double edgeComputeLengthAround(GaussPoint *gp, const int iedge)
Definition: shell7base.C:1344
Load is base abstract class for all loads.
Definition: load.h:61
void edgeEvalEnrCovarBaseVectorsAt(const FloatArray &lCoords, const int iedge, FloatMatrix &gcov, TimeStep *tStep, EnrichmentItem *ei)
void updateLayerTransvStressesSR(FloatMatrix &dSmatLayerIP, int layer)
Definition: shell7base.C:2877
void beProductOf(const FloatMatrix &a, const FloatMatrix &b)
Assigns to the receiver product of .
Definition: floatmatrix.C:337
InternalStateValueType giveInternalStateValueType(InternalStateType type)
Definition: cltypes.C:77
void giveFictiousUpdatedCZNodeCoordsForExport(std::vector< FloatArray > &nodes, int layer, TimeStep *tStep, int subCell)
int giveSize() const
Definition: intarray.h:203
int giveSize() const
Returns the size of receiver.
Definition: floatarray.h:218
Abstract base class for all "structural" interface models.
void giveTractionBC(FloatMatrix &tractionTop, FloatMatrix &tractionBtm, TimeStep *tStep)
Definition: shell7base.C:2206
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
virtual int giveNumberOfEdgeDofs()=0
void assemble(const FloatMatrix &src, const IntArray &loc)
Assembles the contribution using localization array into receiver.
Definition: floatmatrix.C:251
void clear()
Sets size of receiver to be an empty matrix. It will have zero rows and zero columns size...
Definition: floatmatrix.h:516
Class implementing node in finite element mesh.
Definition: node.h:87
int giveNumber() const
Definition: femcmpnn.h:107
virtual void giveEIDofIdArray(IntArray &answer) const
double normalize()
Normalizes receiver.
Definition: floatarray.C:828
void computeCohesiveForces(FloatArray &answer, TimeStep *tStep, FloatArray &solVec, FloatArray &solVecD, EnrichmentItem *ei, EnrichmentItem *coupledToEi)
Node * giveNode(int i) const
Returns reference to the i-th node of element.
Definition: element.h:610
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
Load * giveLoad(int n)
Service for accessing particular domain load.
Definition: domain.C:222
void recoverValuesFromCZIP(std::vector< FloatArray > &recoveredValues, int interfce, InternalStateType type, TimeStep *tStep)
virtual int SetUpPointsOnLine(int nPoints, MaterialMode mode)
Sets up receiver&#39;s integration points on unit line integration domain.
void symmetrized()
Initializes the lower half of the receiver according to the upper half.
Definition: floatmatrix.C:1576
void discComputeSectionalForces(FloatArray &answer, TimeStep *tStep, FloatArray &solVec, FloatArray &solVecD, EnrichmentItem *ei)
FEI3dTrQuad interpolationForCZExport
const double DISC_DOF_SCALE_FAC
std::vector< std::vector< FloatArray > > quantities
Class representing integration point in finite element program.
Definition: gausspoint.h:93
IntArray boundaryLoadArray
Definition: element.h:160
void giveLocalCZNodeCoordsForExport(FloatArray &nodeLocalXi1Coords, FloatArray &nodeLocalXi2Coords, FloatArray &nodeLocalXi3Coords, int subCell, FloatMatrix &localNodeCoords)
void computeTripleProduct(FloatMatrix &answer, const FloatMatrix &a, const FloatMatrix &b, const FloatMatrix &c)
void computeLambdaNMatrix(FloatMatrix &lambda, FloatArray &genEps, double zeta)
Definition: shell7base.C:509
virtual void computeLocalEdgeMapping(IntArray &edgeNodes, int iedge)=0
void computeLambdaGMatrices(FloatMatrix lambda[3], FloatArray &genEps, double zeta)
Definition: shell7base.C:460
Class representing solution step.
Definition: timestep.h:80
virtual int giveIPValue(FloatArray &answer, GaussPoint *gp, InternalStateType type, TimeStep *tStep)
Returns the integration point corresponding value in Reduced form.
Definition: material.C:142
FloatMatrix giveAxialMatrix(const FloatArray &vec)
Definition: shell7base.C:687
int numberOfDofMans
Number of dofmanagers.
Definition: element.h:149
void add(const FloatArray &src)
Adds array src to receiver.
Definition: floatarray.C:156
virtual void local2global(FloatArray &answer, const FloatArray &lcoords, const FEICellGeometry &cellgeo)=0
Evaluates global coordinates from given local ones.
Material * giveInterfaceMaterial(int interface)
const FloatArray & giveNaturalCoordinates()
Returns coordinate array of receiver.
Definition: gausspoint.h:138
virtual void postInitialize()
Performs post initialization steps.
Definition: shell7base.C:87
virtual void computeNmatrixAt(const FloatArray &iLocCoords, FloatMatrix &answer)
Computes interpolation matrix for element unknowns.
Definition: shell7base.C:1777
#define _IFT_Shell7BaseXFEM_CohesiveZoneMaterial
Class representing Gaussian-quadrature integration rule.
void resize(int s)
Resizes receiver towards requested size.
Definition: floatarray.C:631
void plusProduct(const FloatMatrix &b, const FloatArray &s, double dV)
Adds the product .
Definition: floatarray.C:226

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