OOFEM  2.4
OOFEM.org - Object Oriented Finite Element Solver
xfemelementinterface.C
Go to the documentation of this file.
1 /*
2  *
3  * ##### ##### ###### ###### ### ###
4  * ## ## ## ## ## ## ## ### ##
5  * ## ## ## ## #### #### ## # ##
6  * ## ## ## ## ## ## ## ##
7  * ## ## ## ## ## ## ## ##
8  * ##### ##### ## ###### ## ##
9  *
10  *
11  * OOFEM : Object Oriented Finite Element Code
12  *
13  * Copyright (C) 1993 - 2013 Borek Patzak
14  *
15  *
16  *
17  * Czech Technical University, Faculty of Civil Engineering,
18  * Department of Structural Mechanics, 166 29 Prague, Czech Republic
19  *
20  * This library is free software; you can redistribute it and/or
21  * modify it under the terms of the GNU Lesser General Public
22  * License as published by the Free Software Foundation; either
23  * version 2.1 of the License, or (at your option) any later version.
24  *
25  * This program is distributed in the hope that it will be useful,
26  * but WITHOUT ANY WARRANTY; without even the implied warranty of
27  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
28  * Lesser General Public License for more details.
29  *
30  * You should have received a copy of the GNU Lesser General Public
31  * License along with this library; if not, write to the Free Software
32  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
33  */
34 
35 #include "xfemelementinterface.h"
36 #include "enrichmentitem.h"
37 #include "geometrybasedei.h"
38 #include "engngm.h"
39 #include "gausspoint.h"
40 #include "materialmode.h"
41 #include "fei2dquadlin.h"
42 #include "patchintegrationrule.h"
43 #include "delaunay.h"
44 #include "xfemmanager.h"
45 #include "floatarray.h"
46 #include "floatmatrix.h"
47 #include "dynamicinputrecord.h"
48 #include "mathfem.h"
49 
50 #include "XFEMDebugTools.h"
51 #include <string>
52 #include <sstream>
53 
54 namespace oofem {
56  Interface(),
57  element(e),
58  mUsePlaneStrain(false)
59 {
60  mpCZIntegrationRules.clear();
62 }
63 
65 {}
66 
68 {
69  ComputeBOrBHMatrix(oAnswer, iGP, iEl, false, iGP.giveNaturalCoordinates());
70 }
71 
73 {
74  ComputeBOrBHMatrix(oAnswer, iGP, iEl, true, iGP.giveNaturalCoordinates());
75 }
76 
77 void XfemElementInterface :: ComputeBOrBHMatrix(FloatMatrix &oAnswer, GaussPoint &iGP, Element &iEl, bool iComputeBH, const FloatArray &iNaturalGpCoord)
78 {
79  /*
80  * Computes the B or BH matrix.
81  * iComputeBH = true implies that BH is computed,
82  * while B is computed if iComputeBH = false.
83  *
84  * We could take the natural coordinates directly from the Gauss point instead of entering them separately.
85  * However, there are situations where one wants to add a small perturbation to the coordinates and hence
86  * it is easier to enter them separately.
87  */
88  const int dim = 2;
89  const int nDofMan = iEl.giveNumberOfDofManagers();
90 
91  int shearInd = 3, numRows = 3;
92  if ( mUsePlaneStrain ) {
93  shearInd = 4;
94  numRows = 4;
95  }
96 
97  if ( iComputeBH ) {
98  numRows++;
99  }
100 
101  FloatMatrix dNdx;
102  FloatArray N;
103  FEInterpolation *interp = iEl.giveInterpolation();
104  const FEIElementGeometryWrapper geomWrapper(& iEl);
105  interp->evaldNdx(dNdx, iNaturalGpCoord, geomWrapper);
106  interp->evalN(N, iNaturalGpCoord, geomWrapper);
107 
108  const IntArray &elNodes = iEl.giveDofManArray();
109 
110  // Compute global coordinates of Gauss point
111  FloatArray globalCoord = {
112  0.0, 0.0
113  };
114 
115  for ( int i = 1; i <= nDofMan; i++ ) {
116  const Node *node = iEl.giveNode(i);
117  const FloatArray &nodeCoord = node->giveNodeCoordinates();
118  globalCoord.at(1) += N.at(i) * nodeCoord [ 0 ];
119  globalCoord.at(2) += N.at(i) * nodeCoord [ 1 ];
120  }
121 
122 
123  // Standard FE part of B-matrix
124  std :: vector< FloatMatrix >Bc(nDofMan);
125  for ( int i = 1; i <= nDofMan; i++ ) {
126  FloatMatrix &BNode = Bc [ i - 1 ];
127  BNode.resize(numRows, 2);
128  BNode.at(1, 1) = dNdx.at(i, 1);
129  BNode.at(2, 2) = dNdx.at(i, 2);
130  BNode.at(shearInd, 1) = dNdx.at(i, 2);
131 
132  if ( iComputeBH ) {
133  BNode.at(shearInd + 1, 2) = dNdx.at(i, 1);
134  } else {
135  BNode.at(shearInd, 2) = dNdx.at(i, 1);
136  }
137  }
138 
139 
140  // XFEM part of B-matrix
141  double enrDofsScaleFactor = 1.0;
142  XfemManager *xMan = NULL;
143  if ( iEl.giveDomain()->hasXfemManager() ) {
144  xMan = iEl.giveDomain()->giveXfemManager();
145  enrDofsScaleFactor = xMan->giveEnrDofScaleFactor();
146  }
147 
148  std :: vector< FloatMatrix >Bd(nDofMan); // One Bd per node
149 
150  int counter = nDofMan * dim;
151 
152  int numEnrNode = 0;
153 
154  for ( int j = 1; j <= nDofMan; j++ ) {
155  DofManager *dMan = iEl.giveDofManager(j);
156  const Node *node = iEl.giveNode(j);
157 
158  // Compute the total number of enrichments for node j
159  if ( iEl.giveDomain()->hasXfemManager() ) {
160  numEnrNode = XfemElementInterface_giveNumDofManEnrichments(* dMan, * xMan);
161  }
162 
163  if ( numEnrNode > 0 ) {
164  FloatMatrix &BdNode = Bd [ j - 1 ];
165  BdNode.resize(numRows, numEnrNode * dim);
166 
167 
168  const int globalNodeInd = dMan->giveGlobalNumber();
169 
170  int nodeEnrCounter = 0;
171 
172  const std :: vector< int > &nodeEiIndices = xMan->giveNodeEnrichmentItemIndices(globalNodeInd);
173  for ( size_t i = 0; i < nodeEiIndices.size(); i++ ) {
174  EnrichmentItem *ei = xMan->giveEnrichmentItem(nodeEiIndices [ i ]);
175 
176  if ( ei->isDofManEnriched(* dMan) ) {
177 // int numEnr = ei->giveNumDofManEnrichments(* dMan);
178 
179  // Enrichment function derivative in Gauss point
180  std :: vector< FloatArray >efgpD;
181  ei->evaluateEnrFuncDerivAt(efgpD, globalCoord, iNaturalGpCoord, globalNodeInd, * element, N, dNdx, elNodes);
182  // Enrichment function in Gauss Point
183  std :: vector< double >efGP;
184  ei->evaluateEnrFuncAt(efGP, globalCoord, iNaturalGpCoord, globalNodeInd, * element, N, elNodes);
185 
186 
187  const FloatArray &nodePos = node->giveNodeCoordinates();
188 
189 // double levelSetNode = 0.0;
190 // ei->evalLevelSetNormalInNode(levelSetNode, globalNodeInd, nodePos);
191 
192  std :: vector< double >efNode;
193  FloatArray nodeNaturalCoord;
194  iEl.computeLocalCoordinates(nodeNaturalCoord, nodePos);
195  ei->evaluateEnrFuncInNode(efNode, * node);
196 
197  int numEnr = efGP.size();
198  for ( int k = 0; k < numEnr; k++ ) {
199  // matrix to be added anytime a node is enriched
200  // Creates nabla*(ef*N)
201  FloatArray grad_ef_N;
202  grad_ef_N.resize(dim);
203  for ( int p = 1; p <= dim; p++ ) {
204  grad_ef_N.at(p) = dNdx.at(j, p) * ( efGP [ k ] - efNode [ k ] ) + N.at(j) * efgpD [ k ].at(p);
205  }
206 
207  BdNode.at(1, nodeEnrCounter + 1) = grad_ef_N.at(1);
208  BdNode.at(2, nodeEnrCounter + 2) = grad_ef_N.at(2);
209  BdNode.at(shearInd, nodeEnrCounter + 1) = grad_ef_N.at(2);
210 
211  if ( iComputeBH ) {
212  BdNode.at(shearInd + 1, nodeEnrCounter + 2) = grad_ef_N.at(1);
213  } else {
214  BdNode.at(shearInd, nodeEnrCounter + 2) = grad_ef_N.at(1);
215  }
216 
217  nodeEnrCounter += 2;
218  counter += 2;
219  }
220  }
221  }
222  }
223  }
224 
225 
226  // Create the total B-matrix by appending each contribution to B after one another.
227  oAnswer.resize(numRows, counter);
228 
229  int column = 1;
230  for ( int i = 0; i < nDofMan; i++ ) {
231  oAnswer.setSubMatrix(Bc [ i ], 1, column);
232  column += 2;
233  if ( Bd [ i ].isNotEmpty() ) {
234  Bd[i].times(enrDofsScaleFactor);
235  oAnswer.setSubMatrix(Bd [ i ], 1, column);
236 
237  column += Bd [ i ].giveNumberOfColumns();
238  }
239  }
240 }
241 
242 void XfemElementInterface :: XfemElementInterface_createEnrNmatrixAt(FloatMatrix &oAnswer, const FloatArray &iLocCoord, Element &iEl, bool iSetDiscontContribToZero)
243 {
244  std :: vector< int >elNodes;
245 
246  int numElNodes = iEl.giveNumberOfDofManagers();
247 
248  for ( int i = 0; i < numElNodes; i++ ) {
249  elNodes.push_back(i + 1);
250  }
251 
252  XfemElementInterface_createEnrNmatrixAt(oAnswer, iLocCoord, iEl, elNodes, iSetDiscontContribToZero);
253 }
254 
255 void XfemElementInterface :: XfemElementInterface_createEnrNmatrixAt(FloatMatrix &oAnswer, const FloatArray &iLocCoord, Element &iEl, const std :: vector< int > &iLocNodeInd, bool iSetDiscontContribToZero)
256 {
257  const int dim = 2;
258  const int nDofMan = iEl.giveNumberOfDofManagers();
259 
260  FloatArray Nc;
261  FEInterpolation *interp = iEl.giveInterpolation();
262  interp->evalN( Nc, iLocCoord, FEIElementGeometryWrapper(& iEl) );
263 
264  const IntArray &elNodes = iEl.giveDofManArray();
265 
266  // Compute global coordinates of Gauss point
267  FloatArray globalCoord(2);
268  globalCoord.zero();
269 
270  for ( int i = 1; i <= nDofMan; i++ ) {
271  DofManager *dMan = iEl.giveDofManager(i);
272  globalCoord.at(1) += Nc.at(i) * dMan->giveCoordinate(1);
273  globalCoord.at(2) += Nc.at(i) * dMan->giveCoordinate(2);
274  }
275 
276 
277  // XFEM part of N-matrix
278  XfemManager *xMan = iEl.giveDomain()->giveXfemManager();
279  double enrDofsScaleFactor = xMan->giveEnrDofScaleFactor();
280 
281  int counter = iLocNodeInd.size() * dim;
282 
283  std :: vector< std :: vector< double > >Nd( iLocNodeInd.size() );
284  for ( int j = 1; j <= int( iLocNodeInd.size() ); j++ ) {
285  DofManager *dMan = iEl.giveDofManager(iLocNodeInd [ j - 1 ]);
286  Node *node = dynamic_cast< Node * >( dMan );
287 
288  // Compute the total number of enrichments for node j
289  int numEnrNode = XfemElementInterface_giveNumDofManEnrichments(* dMan, * xMan);
290  std :: vector< double > &NdNode = Nd [ j - 1 ];
291  NdNode.assign(numEnrNode, 0.0);
292 
293 
294  int globalNodeInd = dMan->giveGlobalNumber();
295 
296  size_t nodeCounter = 0;
297 
298  int placeInArray = element->giveDomain()->giveDofManPlaceInArray(globalNodeInd);
299  const std :: vector< int > &nodeEiIndices = xMan->giveNodeEnrichmentItemIndices(placeInArray);
300  for ( size_t i = 0; i < nodeEiIndices.size(); i++ ) {
301  EnrichmentItem *ei = xMan->giveEnrichmentItem(nodeEiIndices [ i ]);
302 
303  if ( ei->isDofManEnriched(* dMan) ) {
304 // int numEnr = ei->giveNumDofManEnrichments(* dMan);
305 
306 
307  // Enrichment function in Gauss Point
308  std :: vector< double >efGP;
309  ei->evaluateEnrFuncAt(efGP, globalCoord, iLocCoord, globalNodeInd, iEl, Nc, elNodes);
310 
311 
312  const FloatArray &nodePos = * ( dMan->giveCoordinates() );
313 
314  std :: vector< double >efNode;
315 
316  FloatArray nodePosLocCoord;
317  iEl.computeLocalCoordinates(nodePosLocCoord, nodePos);
318  ei->evaluateEnrFuncInNode(efNode, * node);
319 
320 
321  int numEnr = efGP.size();
322  for ( int k = 0; k < numEnr; k++ ) {
323  if ( iSetDiscontContribToZero ) {
324  NdNode [ nodeCounter ] = 0.0;
325  } else {
326  NdNode [ nodeCounter ] = ( efGP [ k ] - efNode [ k ] ) * Nc.at(j);
327  }
328  counter++;
329  nodeCounter++;
330  }
331  }
332  }
333  }
334 
335  int numN = iLocNodeInd.size();
336 
337  for ( int j = 1; j <= int( iLocNodeInd.size() ); j++ ) {
338  numN += Nd [ j - 1 ].size();
339  }
340 
341  FloatArray NTot;
342  NTot.resize(numN);
343  NTot.zero();
344  int column = 1;
345 
346  for ( int i = 1; i <= int( iLocNodeInd.size() ); i++ ) {
347  NTot.at(column) = Nc.at(iLocNodeInd [ i - 1 ]);
348  column++;
349 
350  const std :: vector< double > &NdNode = Nd [ i - 1 ];
351  for ( size_t j = 1; j <= NdNode.size(); j++ ) {
352  NTot.at(column) = NdNode [ j - 1 ]*enrDofsScaleFactor;
353  column++;
354  }
355  }
356 
357  oAnswer.beNMatrixOf(NTot, 2);
358 }
359 
361 {
362  int numEnrNode = 0;
363  int globalNodeInd = iDMan.giveGlobalNumber();
364  int placeInArray = element->giveDomain()->giveDofManPlaceInArray(globalNodeInd);
365  const std :: vector< int > &nodeEiIndices = iXMan.giveNodeEnrichmentItemIndices(placeInArray);
366  for ( size_t i = 0; i < nodeEiIndices.size(); i++ ) {
367  EnrichmentItem *ei = iXMan.giveEnrichmentItem(nodeEiIndices [ i ]);
368  if ( ei->isDofManEnriched(iDMan) ) {
369  numEnrNode += ei->giveNumDofManEnrichments(iDMan);
370  }
371  }
372 
373  return numEnrNode;
374 }
375 
376 void XfemElementInterface :: XfemElementInterface_partitionElement(std :: vector< Triangle > &oTriangles, const std :: vector< FloatArray > &iPoints)
377 {
378  Delaunay dl;
379  dl.triangulate(iPoints, oTriangles);
380 }
381 
382 
383 
385 {
386  bool partitionSucceeded = false;
387 
388  XfemManager *xMan = this->element->giveDomain()->giveXfemManager();
389  if ( xMan->isElementEnriched(element) ) {
391 
392  bool firstIntersection = true;
393 
394  std :: vector< std :: vector< FloatArray > >pointPartitions;
395  std :: vector< Triangle >allTri;
396 
397  std :: vector< int >enrichingEIs;
398  int elPlaceInArray = xMan->giveDomain()->giveElementPlaceInArray( element->giveGlobalNumber() );
399  xMan->giveElementEnrichmentItemIndices(enrichingEIs, elPlaceInArray);
400 
401 
402  for ( size_t p = 0; p < enrichingEIs.size(); p++ ) {
403  int eiIndex = enrichingEIs [ p ];
404 
405  if ( firstIntersection ) {
406  // Get the points describing each subdivision of the element
407  double startXi, endXi;
408  bool intersection = false;
409  this->XfemElementInterface_prepareNodesForDelaunay(pointPartitions, startXi, endXi, eiIndex, intersection);
410 
411  if ( intersection ) {
412  firstIntersection = false;
413 
414  // Use XfemElementInterface_partitionElement to subdivide the element
415  for ( int i = 0; i < int ( pointPartitions.size() ); i++ ) {
416  // Triangulate the subdivisions
417  this->XfemElementInterface_partitionElement(allTri, pointPartitions [ i ]);
418  }
419 
420  partitionSucceeded = true;
421  }
422  } // if(firstIntersection)
423  else {
424  // Loop over triangles
425  std :: vector< Triangle >allTriCopy;
426  for ( size_t triIndex = 0; triIndex < allTri.size(); triIndex++ ) {
427  // Call alternative version of XfemElementInterface_prepareNodesForDelaunay
428  std :: vector< std :: vector< FloatArray > >pointPartitionsTri;
429  double startXi, endXi;
430  bool intersection = false;
431  XfemElementInterface_prepareNodesForDelaunay(pointPartitionsTri, startXi, endXi, allTri [ triIndex ], eiIndex, intersection);
432 
433  if ( intersection ) {
434  // Use XfemElementInterface_partitionElement to subdivide triangle j
435  for ( int i = 0; i < int ( pointPartitionsTri.size() ); i++ ) {
436  this->XfemElementInterface_partitionElement(allTriCopy, pointPartitionsTri [ i ]);
437  }
438  } else {
439  allTriCopy.push_back(allTri [ triIndex ]);
440  }
441  }
442 
443  allTri = allTriCopy;
444  }
445  }
446 
448  // When we reach this point, we have a
449  // triangulation that is adapted to all
450  // cracks passing through the element.
451  // Therefore, we can set up integration
452  // points on each triangle.
453 
454  if ( xMan->giveVtkDebug() ) {
455  std :: stringstream str3;
456  int elIndex = this->element->giveGlobalNumber();
457  str3 << "TriEl" << elIndex << ".vtk";
458  std :: string name3 = str3.str();
459 
460  if ( allTri.size() > 0 ) {
462  }
463  }
464 
465 
466  int ruleNum = 1;
467  if ( partitionSucceeded ) {
468  std :: vector< std :: unique_ptr< IntegrationRule > >intRule;
469  intRule.emplace_back( new PatchIntegrationRule(ruleNum, element, allTri) );
470  intRule [ 0 ]->SetUpPointsOnTriangle(xMan->giveNumGpPerTri(), matMode);
471  element->setIntegrationRules( std :: move(intRule) );
472  }
473  }
474 
475  return partitionSucceeded;
476 }
477 
478 void XfemElementInterface :: XfemElementInterface_prepareNodesForDelaunay(std :: vector< std :: vector< FloatArray > > &oPointPartitions, double &oCrackStartXi, double &oCrackEndXi, int iEnrItemIndex, bool &oIntersection)
479 {
480  int dim = element->giveDofManager(1)->giveCoordinates()->giveSize();
481 
483  elCenter.zero();
484  std :: vector< const FloatArray * >nodeCoord;
485  for ( int i = 1; i <= this->element->giveNumberOfDofManagers(); i++ ) {
486  nodeCoord.push_back( element->giveDofManager(i)->giveCoordinates() );
487  elCenter.add( * ( element->giveDofManager(i)->giveCoordinates() ) );
488  }
489  elCenter.times( 1.0 / double( element->giveNumberOfDofManagers() ) );
490 
491  XfemManager *xMan = this->element->giveDomain()->giveXfemManager();
492  GeometryBasedEI *ei = dynamic_cast< GeometryBasedEI * >( xMan->giveEnrichmentItem(iEnrItemIndex) );
493 
494  if ( ei == NULL ) {
495  oIntersection = false;
496  return;
497  }
498 
499  std :: vector< FloatArray >intersecPoints;
500  std :: vector< int >intersecEdgeInd;
501 
502  std :: vector< double >minDistArcPos;
503  ei->computeIntersectionPoints(intersecPoints, intersecEdgeInd, element, minDistArcPos);
504 
505  for ( size_t i = 0; i < intersecPoints.size(); i++ ) {
506  intersecPoints [ i ].resizeWithValues(dim);
507  }
508 
509 
510  if ( intersecPoints.size() == 2 ) {
511  // The element is completely cut in two.
512  // Therefore, we create two subpartitions:
513  // one on each side of the interface.
514  oPointPartitions.resize(2);
515 
516  putPointsInCorrectPartition(oPointPartitions, intersecPoints, nodeCoord);
517 
518  // Export start and end points of
519  // the intersection line.
520  oCrackStartXi = std :: min(minDistArcPos [ 0 ], minDistArcPos [ 1 ]);
521  oCrackEndXi = std :: max(minDistArcPos [ 0 ], minDistArcPos [ 1 ]);
522 
523  oIntersection = true;
524  return;
525  } else if ( intersecPoints.size() == 1 ) {
526  std :: vector< FloatArray >edgeCoords;
527 
528  FloatArray tipCoord;
529  tipCoord.resize(dim);
530 
531  bool foundTip = false;
532  double tipArcPos = -1.0;
533 
534  if ( ei->giveElementTipCoord(tipCoord, tipArcPos, * element, elCenter) ) {
535  foundTip = true;
536  tipCoord.resizeWithValues(dim);
537  }
538  int nEdges = this->element->giveInterpolation()->giveNumberOfEdges();
539  if ( foundTip ) {
540  oPointPartitions.clear();
541 
542  // Divide into subdomains
543  int triPassed = 0;
544  for ( int i = 1; i <= nEdges; i++ ) {
545  IntArray bNodes;
546  this->element->giveInterpolation()->boundaryGiveNodes(bNodes, i);
547 
548 
549  if( bNodes.giveSize() == 2 ) {
550 
551  int nsLoc = bNodes.at(1);
552  int neLoc = bNodes.at( bNodes.giveSize() );
553 
554  const FloatArray &coordS = * ( element->giveDofManager(nsLoc)->giveCoordinates() );
555  const FloatArray &coordE = * ( element->giveDofManager(neLoc)->giveCoordinates() );
556 
557  if ( i == intersecEdgeInd [ 0 ] ) {
558  oPointPartitions.push_back( std :: vector< FloatArray >() );
559  oPointPartitions [ triPassed ].push_back(tipCoord);
560  oPointPartitions [ triPassed ].push_back(intersecPoints [ 0 ]);
561  oPointPartitions [ triPassed ].push_back(coordE);
562  triPassed++;
563 
564  oPointPartitions.push_back( std :: vector< FloatArray >() );
565  oPointPartitions [ triPassed ].push_back(tipCoord);
566  oPointPartitions [ triPassed ].push_back(coordS);
567  oPointPartitions [ triPassed ].push_back(intersecPoints [ 0 ]);
568  triPassed++;
569  } else {
570  oPointPartitions.push_back( std :: vector< FloatArray >() );
571  oPointPartitions [ triPassed ].push_back(tipCoord);
572  oPointPartitions [ triPassed ].push_back(coordS);
573  oPointPartitions [ triPassed ].push_back(coordE);
574  triPassed++;
575  }
576  }
577  else if( bNodes.giveSize() == 3 ) {
578 
579  // Start
580  const FloatArray &coordS = * ( element->giveDofManager(bNodes(0))->giveCoordinates() );
581 
582  // Center
583  const FloatArray &coordC = * ( element->giveDofManager(bNodes(2))->giveCoordinates() );
584 
585  // End
586  const FloatArray &coordE = * ( element->giveDofManager(bNodes(1))->giveCoordinates() );
587 
588 
589  if ( i == intersecEdgeInd [ 0 ] ) {
590 
591  // Check if the intersection point is closer to the start or end, compared to the center point.
592  double dist_S_2 = intersecPoints[0].distance_square(coordS);
593 // double dist_E_2 = intersecPoints[0].distance_square(coordE);
594  double dist_C_2 = coordC.distance_square(coordS);
595 
596  if( dist_S_2 < dist_C_2 ) {
597  oPointPartitions.push_back( std :: vector< FloatArray >() );
598  oPointPartitions [ triPassed ].push_back(intersecPoints [ 0 ]);
599  oPointPartitions [ triPassed ].push_back(tipCoord);
600  oPointPartitions [ triPassed ].push_back(coordS);
601  triPassed++;
602 
603  oPointPartitions.push_back( std :: vector< FloatArray >() );
604  oPointPartitions [ triPassed ].push_back(coordC);
605  oPointPartitions [ triPassed ].push_back(tipCoord);
606  oPointPartitions [ triPassed ].push_back(intersecPoints [ 0 ]);
607  triPassed++;
608 
609  oPointPartitions.push_back( std :: vector< FloatArray >() );
610  oPointPartitions [ triPassed ].push_back(coordE);
611  oPointPartitions [ triPassed ].push_back(tipCoord);
612  oPointPartitions [ triPassed ].push_back(coordC);
613  triPassed++;
614 
615  }
616  else {
617 
618  oPointPartitions.push_back( std :: vector< FloatArray >() );
619  oPointPartitions [ triPassed ].push_back(coordC);
620  oPointPartitions [ triPassed ].push_back(tipCoord);
621  oPointPartitions [ triPassed ].push_back(coordS);
622  triPassed++;
623 
624 
625  oPointPartitions.push_back( std :: vector< FloatArray >() );
626  oPointPartitions [ triPassed ].push_back(intersecPoints [ 0 ]);
627  oPointPartitions [ triPassed ].push_back(tipCoord);
628  oPointPartitions [ triPassed ].push_back(coordC);
629  triPassed++;
630 
631  oPointPartitions.push_back( std :: vector< FloatArray >() );
632  oPointPartitions [ triPassed ].push_back(coordE);
633  oPointPartitions [ triPassed ].push_back(tipCoord);
634  oPointPartitions [ triPassed ].push_back(coordC);
635  triPassed++;
636 
637  }
638 
639 
640  } else {
641  oPointPartitions.push_back( std :: vector< FloatArray >() );
642  oPointPartitions [ triPassed ].push_back(tipCoord);
643  oPointPartitions [ triPassed ].push_back(coordS);
644  oPointPartitions [ triPassed ].push_back(coordC);
645  triPassed++;
646 
647  oPointPartitions.push_back( std :: vector< FloatArray >() );
648  oPointPartitions [ triPassed ].push_back(tipCoord);
649  oPointPartitions [ triPassed ].push_back(coordC);
650  oPointPartitions [ triPassed ].push_back(coordE);
651  triPassed++;
652  }
653 
654  }
655  else {
656  printf("bNodes.giveSize(): %d\n", bNodes.giveSize() );
657  OOFEM_ERROR("Unsupported size of bNodes.")
658  }
659  }
660 
661  // Export start and end points of
662  // the intersection line.
663  oCrackStartXi = std :: min(minDistArcPos [ 0 ], tipArcPos);
664  oCrackEndXi = std :: max(minDistArcPos [ 0 ], tipArcPos);
665  } // If a tip was found
666  else {
667  // printf( "Warning: no tip found in element %d with only one edge intersection.\n", element->giveGlobalNumber() );
668 
669  oPointPartitions.resize(1);
670 
671  for ( int i = 1; i <= this->element->giveNumberOfDofManagers(); i++ ) {
672  const FloatArray &nodeCoord = * element->giveDofManager(i)->giveCoordinates();
673  oPointPartitions [ 0 ].push_back(nodeCoord);
674  }
675 
676  // test Jim
677  // Add first intersection point
678  oPointPartitions [ 0 ].push_back(intersecPoints [ 0 ]);
679 
680  // want to add the extrapolated intersection point
681  //FloatArray test;
682  //test.setValues(2, 0.0, 0.4);
683  //oPointPartitions [ 0 ].push_back( test );
684 
685  // Export start and end points of
686  // the intersection line.
687  oCrackStartXi = minDistArcPos [ 0 ];
688  oCrackEndXi = tipArcPos;
689  }
690 
691  oIntersection = true;
692 
693 
694  //oPointPartitions.resize(0);
695  //oIntersection = true;
696  //false;
697  return;
698  }
699 
700  oIntersection = false;
701 }
702 
703 void XfemElementInterface :: XfemElementInterface_prepareNodesForDelaunay(std :: vector< std :: vector< FloatArray > > &oPointPartitions, double &oCrackStartXi, double &oCrackEndXi, const Triangle &iTri, int iEnrItemIndex, bool &oIntersection)
704 {
705  int dim = element->giveDofManager(1)->giveCoordinates()->giveSize();
706 
707  FloatArray elCenter( iTri.giveVertex(1).giveSize() );
708  elCenter.zero();
709  std :: vector< const FloatArray * >nodeCoord;
710  for ( int i = 1; i <= 3; i++ ) {
711  nodeCoord.push_back( & iTri.giveVertex(i) );
712  elCenter.add( iTri.giveVertex(i) );
713  }
714  elCenter.times(1.0 / 3.0);
715 
716 
717  XfemManager *xMan = this->element->giveDomain()->giveXfemManager();
718  GeometryBasedEI *ei = dynamic_cast< GeometryBasedEI * >( xMan->giveEnrichmentItem(iEnrItemIndex) );
719 
720  if ( ei == NULL ) {
721  oIntersection = false;
722  return;
723  }
724 
725  std :: vector< FloatArray >intersecPoints;
726  std :: vector< int >intersecEdgeInd;
727 
728  std :: vector< double >minDistArcPos;
729  ei->computeIntersectionPoints(intersecPoints, intersecEdgeInd, element, iTri, minDistArcPos);
730  for ( size_t i = 0; i < intersecPoints.size(); i++ ) {
731  intersecPoints [ i ].resizeWithValues(dim);
732  }
733 
734  if ( intersecPoints.size() == 2 ) {
735  // The element is completely cut in two.
736  // Therefore, we create two subpartitions:
737  // one on each side of the interface.
738 
739  oPointPartitions.resize(2);
740 
741  putPointsInCorrectPartition(oPointPartitions, intersecPoints, nodeCoord);
742 
743  // Export start and end points of
744  // the intersection line.
745  oCrackStartXi = std :: min(minDistArcPos [ 0 ], minDistArcPos [ 1 ]);
746  oCrackEndXi = std :: max(minDistArcPos [ 0 ], minDistArcPos [ 1 ]);
747 
748  oIntersection = true;
749  return;
750  } else if ( intersecPoints.size() == 1 ) {
751  int nEdges = 3;
752  std :: vector< FloatArray >edgeCoords, nodeCoords;
753 
754  FloatArray tipCoord;
755  int dim = element->giveDofManager(1)->giveCoordinates()->giveSize();
756  tipCoord.resize(dim);
757 
758  bool foundTip = false;
759  double tipArcPos = -1.0;
760 
761  if ( ei->giveElementTipCoord(tipCoord, tipArcPos, * element, elCenter) ) {
762  tipCoord.resizeWithValues(dim);
763  foundTip = true;
764  }
765 
766  if ( foundTip ) {
767  oPointPartitions.resize( ( nEdges + 1 ) );
768 
769  // Divide into subdomains
770  int triPassed = 0;
771  for ( int i = 1; i <= nEdges; i++ ) {
772  const FloatArray &coordS = iTri.giveVertex(i);
773 
774  int endInd = i + 1;
775  if ( i == nEdges ) {
776  endInd = 1;
777  }
778  const FloatArray &coordE = iTri.giveVertex(endInd);
779 
780  if ( i == intersecEdgeInd [ 0 ] ) {
781  oPointPartitions [ triPassed ].push_back(tipCoord);
782  oPointPartitions [ triPassed ].push_back(intersecPoints [ 0 ]);
783  oPointPartitions [ triPassed ].push_back(coordE);
784  triPassed++;
785 
786  oPointPartitions [ triPassed ].push_back(tipCoord);
787  oPointPartitions [ triPassed ].push_back(coordS);
788  oPointPartitions [ triPassed ].push_back(intersecPoints [ 0 ]);
789  triPassed++;
790  } else {
791  oPointPartitions [ triPassed ].push_back(tipCoord);
792  oPointPartitions [ triPassed ].push_back(coordS);
793  oPointPartitions [ triPassed ].push_back(coordE);
794  triPassed++;
795  }
796  }
797 
798  // Export start and end points of
799  // the intersection line.
800  oCrackStartXi = std :: min(minDistArcPos [ 0 ], tipArcPos);
801  oCrackEndXi = std :: max(minDistArcPos [ 0 ], tipArcPos);
802  } // If a tip was found
803  else {
804  oPointPartitions.resize(1);
805 
806  for ( int i = 1; i <= 3; i++ ) {
807  const FloatArray &nodeCoord = iTri.giveVertex(i);
808  oPointPartitions [ 0 ].push_back(nodeCoord);
809  }
810 
811  // Export start and end points of
812  // the intersection line.
813  oCrackStartXi = minDistArcPos [ 0 ];
814  oCrackEndXi = tipArcPos;
815  }
816 
817  oIntersection = true;
818  return;
819  }
820 
821  oIntersection = false;
822 }
823 
824 void XfemElementInterface :: putPointsInCorrectPartition(std :: vector< std :: vector< FloatArray > > &oPointPartitions,
825  const std :: vector< FloatArray > &iIntersecPoints,
826  const std :: vector< const FloatArray * > &iNodeCoord) const
827 {
828  for ( size_t i = 0; i < iIntersecPoints.size(); i++ ) {
829  oPointPartitions [ 0 ].push_back(iIntersecPoints [ i ]);
830  oPointPartitions [ 1 ].push_back(iIntersecPoints [ i ]);
831  }
832 
833  // Check on which side of the interface each node is located.
834  const double &x1 = iIntersecPoints [ 0 ].at(1);
835  const double &x2 = iIntersecPoints [ 1 ].at(1);
836  const double &y1 = iIntersecPoints [ 0 ].at(2);
837  const double &y2 = iIntersecPoints [ 1 ].at(2);
838 
839  for ( size_t i = 1; i <= iNodeCoord.size(); i++ ) {
840  const double &x = iNodeCoord [ i - 1 ]->at(1);
841  const double &y = iNodeCoord [ i - 1 ]->at(2);
842  double det = ( x1 - x ) * ( y2 - y ) - ( x2 - x ) * ( y1 - y );
843 
844  if ( det > 0.0 ) {
845  oPointPartitions [ 0 ].push_back(* iNodeCoord [ i - 1 ]);
846  } else {
847  oPointPartitions [ 1 ].push_back(* iNodeCoord [ i - 1 ]);
848  }
849  }
850 }
851 
852 void XfemElementInterface :: partitionEdgeSegment(int iBndIndex, std :: vector< Line > &oSegments, std :: vector< FloatArray > &oIntersectionPoints, const double &iTangDistPadding)
853 {
854  const double levelSetTol2 = 1.0e-12;
855  // const double gammaPadding = 0.001;
856 
857  XfemManager *xMan = this->element->giveDomain()->giveXfemManager();
858 
859  FEInterpolation *interp = element->giveInterpolation(); // Geometry interpolation
860  IntArray edgeNodes;
861  FEInterpolation2d *interp2d = dynamic_cast< FEInterpolation2d * >( interp );
862  if ( interp2d == NULL ) {
863  OOFEM_ERROR("In XfemElementInterface :: partitionEdgeSegment: failed to cast to FEInterpolation2d.\n")
864  }
865  interp2d->computeLocalEdgeMapping(edgeNodes, iBndIndex);
866 
867  // Fetch start and end points.
868  const FloatArray &xS = * ( element->giveDofManager( edgeNodes.at(1) )->giveCoordinates() );
869  const FloatArray &xE = * ( element->giveDofManager( edgeNodes.at(2) )->giveCoordinates() );
870 
871  // The point of departure is the original edge segment.
872  // This segment will be subdivided as many times as necessary.
873  Line seg1(xS, xE);
874  // oSegments.clear();
875  oSegments.push_back(seg1);
876 
877 
878  // Loop over enrichment items
879  int numEI = xMan->giveNumberOfEnrichmentItems();
880  for ( int eiIndex = 1; eiIndex <= numEI; eiIndex++ ) {
881  EnrichmentItem *ei = xMan->giveEnrichmentItem(eiIndex);
882 
883  std :: vector< Line >newSegments;
884 
885  // Loop over segments
886  size_t numSeg = oSegments.size();
887  for ( size_t segInd = 0; segInd < numSeg; segInd++ ) {
888  // Check if the segment is cut by the current enrichment item
889 
890  const FloatArray &seg_xS = oSegments [ segInd ].giveVertex(1);
891  const FloatArray &seg_xE = oSegments [ segInd ].giveVertex(2);
892 
893 
894  // Local coordinates of vertices
895  FloatArray xiS;
896  bool evaluationSucceeded = true;
897  if ( !element->computeLocalCoordinates(xiS, seg_xS) ) {
898  //TODO: Check for numerical round-off error
899  // printf("xiS: "); xiS.printYourself();
900  // evaluationSucceeded = false;
901  }
902  FloatArray xiE;
903  if ( !element->computeLocalCoordinates(xiE, seg_xE) ) {
904  // printf("xiE: "); xiE.printYourself();
905  // evaluationSucceeded = false;
906  }
907 
908  const IntArray &elNodes = element->giveDofManArray();
909  FloatArray Ns, Ne;
910  interp->evalN( Ns, xiS, FEIElementGeometryWrapper(element) );
911  interp->evalN( Ne, xiE, FEIElementGeometryWrapper(element) );
912 
913  double phiS = 0.0, phiE = 0.0;
914  double gammaS = 0.0, gammaE = 0.0;
915 
916 
917  for ( int i = 1; i <= Ns.giveSize(); i++ ) {
918  const FloatArray &nodePos = * ( element->giveNode(i)->giveCoordinates() );
919  double phiNode = 0.0;
920  if ( !ei->evalLevelSetNormalInNode(phiNode, elNodes [ i - 1 ], nodePos) ) {
921  evaluationSucceeded = false;
922  }
923 
924  double gammaNode = 0.0;
925  if ( !ei->evalLevelSetTangInNode(gammaNode, elNodes [ i - 1 ], nodePos) ) {
926  evaluationSucceeded = false;
927  }
928 
929  phiS += Ns.at(i) * phiNode;
930  gammaS += Ns.at(i) * gammaNode;
931 
932  phiE += Ne.at(i) * phiNode;
933  gammaE += Ne.at(i) * gammaNode;
934  }
935 
936 
937  if ( phiS * phiE < levelSetTol2 && evaluationSucceeded ) {
938  double xi = EnrichmentItem :: calcXiZeroLevel(phiS, phiE);
939  double gamma = 0.5 * ( 1.0 - xi ) * gammaS + 0.5 * ( 1.0 + xi ) * gammaE;
940 
941  // If we are inside in tangential direction
942  if ( gamma > -iTangDistPadding ) {
943  // If so, subdivide it ...
944 
945  // Compute global coordinates of the intersection point
946  int nDim = std :: min( seg_xS.giveSize(), seg_xE.giveSize() );
947  FloatArray p;
948  p.resize(nDim);
949 
950  for ( int i = 1; i <= nDim; i++ ) {
951  ( p.at(i) ) = 0.5 * ( 1.0 - xi ) * ( ( seg_xS.at(i) ) ) + 0.5 * ( 1.0 + xi ) * ( ( seg_xE.at(i) ) );
952  }
953 
954  Line segA(seg_xS, p);
955  newSegments.push_back(segA);
956  Line segB(p, seg_xE);
957  newSegments.push_back(segB);
958 
959  // Export the intersection point
960  oIntersectionPoints.push_back(p);
961  } else {
962  newSegments.push_back(oSegments [ segInd ]);
963  }
964  } else {
965  // ... else keep the segment.
966  newSegments.push_back(oSegments [ segInd ]);
967  }
968  }
969 
970  oSegments = newSegments;
971  }
972 }
973 
975 {
976  if ( mUsePlaneStrain ) {
977  return _PlaneStrain;
978  } else {
979  return _PlaneStress;
980  }
981 }
982 
984 {
985  size_t numSeg = mpCZIntegrationRules.size();
986 
987  for ( size_t i = 0; i < numSeg; i++ ) {
988  if ( mpCZIntegrationRules [ i ] != NULL ) {
989  mpCZIntegrationRules [ i ]->updateYourself(tStep);
990  }
991  }
992 
993  numSeg = mpCZExtraIntegrationRules.size();
994  for ( size_t i = 0; i < numSeg; i++ ) {
995  if ( mpCZExtraIntegrationRules [ i ] != NULL ) {
996  mpCZExtraIntegrationRules [ i ]->updateYourself(tStep);
997  }
998  }
999 
1000 }
1001 
1003 {
1004  const int dim = 2;
1005  oJump.resize(dim);
1006  oJump.beProductOf(iNMatrix, iSolVec);
1007 }
1008 
1009 void XfemElementInterface :: computeNCohesive(FloatMatrix &oN, GaussPoint &iGP, int iEnrItemIndex, const std :: vector< int > &iTouchingEnrItemIndices)
1010 {
1011  const int dim = 2;
1012 
1013  FloatArray Nc, globalCoord, localCoord;
1014  globalCoord = iGP.giveGlobalCoordinates();
1015  element->computeLocalCoordinates(localCoord, globalCoord);
1017  interp->evalN( Nc, localCoord, FEIElementGeometryWrapper(element) );
1018 
1019  const int nDofMan = element->giveNumberOfDofManagers();
1020 
1021  // XFEM part of N-matrix
1023  double enrDofsScaleFactor = xMan->giveEnrDofScaleFactor();
1024 
1025 
1026  int counter = nDofMan * dim;
1027 
1028  std :: vector< std :: vector< double > >Nd(nDofMan);
1029 
1030  for ( int j = 1; j <= nDofMan; j++ ) {
1031  DofManager *dMan = element->giveDofManager(j);
1032 
1033  // Compute the total number of enrichments for node j
1034  int numEnrNode = XfemElementInterface_giveNumDofManEnrichments(* dMan, * xMan);
1035  std :: vector< double > &NdNode = Nd [ j - 1 ];
1036  NdNode.assign(numEnrNode, 0.0);
1037 
1038 
1039  int globalNodeInd = dMan->giveGlobalNumber();
1040 
1041 
1042  int ndNodeInd = 0;
1043  const std :: vector< int > &nodeEiIndices = xMan->giveNodeEnrichmentItemIndices(globalNodeInd);
1044  for ( size_t i = 0; i < nodeEiIndices.size(); i++ ) {
1045  EnrichmentItem *ei = xMan->giveEnrichmentItem(nodeEiIndices [ i ]);
1046 
1047  GeometryBasedEI *geoEI = dynamic_cast< GeometryBasedEI * >( ei );
1048 
1049  if ( geoEI != NULL ) {
1050  if ( geoEI->isDofManEnriched(* dMan) ) {
1051  int numEnr = geoEI->giveNumDofManEnrichments(* dMan);
1052 
1053  std :: vector< double >efJumps;
1054  bool gpLivesOnCurrentCrack = ( nodeEiIndices [ i ] == iEnrItemIndex );
1055 
1056  bool gpLivesOnInteractingCrack = false;
1057  for ( int touchingEIIndex : iTouchingEnrItemIndices ) {
1058  if ( nodeEiIndices [ i ] == touchingEIIndex ) {
1059  gpLivesOnInteractingCrack = true;
1060  }
1061  }
1062 
1063  if ( nodeEiIndices [ i ] == iEnrItemIndex || gpLivesOnInteractingCrack ) {
1064  geoEI->evaluateEnrFuncJumps(efJumps, globalNodeInd, iGP, gpLivesOnCurrentCrack);
1065  }
1066 
1067  for ( int k = 0; k < numEnr; k++ ) {
1068  if ( nodeEiIndices [ i ] == iEnrItemIndex || gpLivesOnInteractingCrack ) {
1069  NdNode [ ndNodeInd ] = efJumps [ k ] * Nc.at(j);
1070  } else {
1071  NdNode [ ndNodeInd ] = 0.0;
1072  }
1073 
1074  counter++;
1075  ndNodeInd++;
1076  }
1077  }
1078  }
1079  }
1080  }
1081 
1082  int numN = nDofMan;
1083 
1084  for ( int j = 1; j <= nDofMan; j++ ) {
1085  numN += Nd [ j - 1 ].size();
1086  }
1087 
1088  FloatArray NTot;
1089  NTot.resize(numN);
1090  NTot.zero();
1091  int column = 1;
1092 
1093  for ( int i = 1; i <= nDofMan; i++ ) {
1094  // NTot.at(column) = Nc.at(i); // We do not want the continuous part.
1095  column++;
1096 
1097  const std :: vector< double > &NdNode = Nd [ i - 1 ];
1098  for ( size_t j = 1; j <= NdNode.size(); j++ ) {
1099  NTot.at(column) = NdNode [ j - 1 ]*enrDofsScaleFactor;
1100  column++;
1101  }
1102  }
1103 
1104  oN.beNMatrixOf(NTot, 2);
1105 }
1106 } // end namespace oofem
virtual void XfemElementInterface_prepareNodesForDelaunay(std::vector< std::vector< FloatArray > > &oPointPartitions, double &oCrackStartXi, double &oCrackEndXi, int iEnrItemIndex, bool &oIntersection)
Returns an array of array of points. Each array of points defines the points of a subregion of the el...
void evaluateEnrFuncJumps(std::vector< double > &oEnrFuncJumps, int iNodeInd, GaussPoint &iGP, bool iGPLivesOnCurrentCrack) const
const FloatArray & giveVertex(int n) const
Definition: geometry.h:124
Abstract class representing entity, which is included in the FE model using one (or more) global func...
virtual void evalN(FloatArray &answer, const FloatArray &lcoords, const FEICellGeometry &cellgeo)=0
Evaluates the array of interpolation functions (shape functions) at given point.
int giveNumGpPerTri() const
Definition: xfemmanager.h:178
bool isDofManEnriched(const DofManager &iDMan) const
int giveGlobalNumber() const
Definition: dofmanager.h:501
const std::vector< int > & giveNodeEnrichmentItemIndices(int iNodeIndex) const
Definition: xfemmanager.h:248
virtual void evaluateEnrFuncAt(std::vector< double > &oEnrFunc, const FloatArray &iGlobalCoord, const FloatArray &iLocalCoord, int iNodeInd, const Element &iEl) const =0
double & at(int i)
Coefficient access function.
Definition: floatarray.h:131
void XfemElementInterface_createEnrBHmatrixAt(FloatMatrix &oAnswer, GaussPoint &iGP, Element &iEl)
Creates enriched BH-matrix.
int giveGlobalNumber() const
Definition: element.h:1059
void setIntegrationRules(std::vector< std::unique_ptr< IntegrationRule > > irlist)
Sets integration rules.
Definition: element.C:562
Class representing a general abstraction for surface finite element interpolation class...
Definition: feinterpol2d.h:45
void giveElementEnrichmentItemIndices(std::vector< int > &oElemEnrInd, int iElementIndex) const
Definition: xfemmanager.C:583
virtual FloatArray * giveCoordinates()
Definition: dofmanager.h:382
Abstract base class for all finite elements.
Definition: element.h:145
Base class for dof managers.
Definition: dofmanager.h:113
virtual MaterialMode giveMaterialMode()
Returns material mode for receiver integration points.
Definition: element.h:691
MaterialMode
Type representing material mode of integration point.
Definition: materialmode.h:89
virtual void evaluateEnrFuncDerivAt(std::vector< FloatArray > &oEnrFuncDeriv, const FloatArray &iGlobalCoord, const FloatArray &iLocalCoord, int iNodeInd, const Element &iEl) const =0
Class implementing an array of integers.
Definition: intarray.h:61
int & at(int i)
Coefficient access function.
Definition: intarray.h:103
void XfemElementInterface_createEnrBmatrixAt(FloatMatrix &oAnswer, GaussPoint &iGP, Element &iEl)
Creates enriched B-matrix.
XfemManager * giveXfemManager()
Definition: domain.C:375
virtual int giveNumberOfDofManagers() const
Definition: element.h:656
virtual void computeLocalEdgeMapping(IntArray &edgeNodes, int iedge)=0
static void WriteTrianglesToVTK(const std::string &iName, const std::vector< Triangle > &iTriangles)
virtual FEInterpolation * giveInterpolation() const
Definition: element.h:629
void putPointsInCorrectPartition(std::vector< std::vector< FloatArray > > &oPointPartitions, const std::vector< FloatArray > &iIntersecPoints, const std::vector< const FloatArray * > &iNodeCoord) const
virtual void evaluateEnrFuncInNode(std::vector< double > &oEnrFunc, const Node &iNode) const =0
#define min
void setSubMatrix(const FloatMatrix &src, int sr, int sc)
Adds the given matrix as sub-matrix to receiver.
Definition: floatmatrix.C:557
bool giveVtkDebug() const
Definition: xfemmanager.h:243
int giveNumDofManEnrichments(const DofManager &iDMan) const
Class representing a general abstraction for finite element interpolation class.
Definition: feinterpol.h:132
int giveNumberOfEnrichmentItems() const
Definition: xfemmanager.h:185
#define max
void triangulate(const std::vector< FloatArray > &iVertices, std::vector< Triangle > &oTriangles) const
Definition: delaunay.C:80
virtual bool XfemElementInterface_updateIntegrationRule()
Updates integration rule based on the triangulation.
const IntArray & giveDofManArray() const
Definition: element.h:592
void updateYourselfCZ(TimeStep *tStep)
XfemElementInterface(Element *e)
Constructor.
double giveEnrDofScaleFactor() const
Definition: xfemmanager.h:180
#define OOFEM_ERROR(...)
Definition: error.h:61
virtual void computeIntersectionPoints(std::vector< FloatArray > &oIntersectionPoints, std::vector< int > &oIntersectedEdgeInd, Element *element, std::vector< double > &oMinDistArcPos) const
O(n4) algorithm, only for testing purposes.
Definition: delaunay.h:53
bool evalLevelSetNormalInNode(double &oLevelSet, int iNodeInd, const FloatArray &iGlobalCoord) const
void XfemElementInterface_createEnrNmatrixAt(FloatMatrix &oAnswer, const FloatArray &iLocCoord, Element &iEl, bool iSetDiscontContribToZero)
Creates enriched N-matrix.
Wrapper around element definition to provide FEICellGeometry interface.
Definition: feinterpol.h:95
void beProductOf(const FloatMatrix &aMatrix, const FloatArray &anArray)
Receiver becomes the result of the product of aMatrix and anArray.
Definition: floatarray.C:676
#define N(p, q)
Definition: mdm.C:367
void resizeWithValues(int s, int allocChunk=0)
Checks size of receiver towards requested bounds.
Definition: floatarray.C:615
double at(int i, int j) const
Coefficient access function.
Definition: floatmatrix.h:176
double distance_square(const FloatArray &iP1, const FloatArray &iP2, double &oXi, double &oXiUnbounded) const
Definition: floatarray.C:499
virtual bool giveElementTipCoord(FloatArray &oCoord, double &oArcPos, Element &iEl, const FloatArray &iElCenter) const
void partitionEdgeSegment(int iBndIndex, std::vector< Line > &oSegments, std::vector< FloatArray > &oIntersectionPoints, const double &iTangDistPadding=0.0)
Partition a boundary segment to account for cracks cutting the boundary.
int giveDofManPlaceInArray(int iGlobalDofManNum) const
Returns the array index of the dofman with global number iGlobalDofManNum, so that it can be fetched ...
Definition: domain.C:196
const FloatArray & giveGlobalCoordinates()
Definition: gausspoint.h:160
std::vector< std::unique_ptr< IntegrationRule > > mpCZIntegrationRules
void ComputeBOrBHMatrix(FloatMatrix &oAnswer, GaussPoint &iGP, Element &iEl, bool iComputeBH, const FloatArray &iNaturalGpCoord)
Help function for computation of B and BH.
void beNMatrixOf(const FloatArray &n, int nsd)
Assigns the receiver to be a repeated diagonal matrix.
Definition: floatmatrix.C:505
std::vector< std::unique_ptr< IntegrationRule > > mpCZExtraIntegrationRules
bool hasXfemManager()
Definition: domain.C:386
virtual void boundaryGiveNodes(IntArray &answer, int boundary)=0
Gives the boundary nodes for requested boundary number.
bool evalLevelSetTangInNode(double &oLevelSet, int iNodeInd, const FloatArray &iGlobalCoord) const
Class representing vector of real numbers.
Definition: floatarray.h:82
int XfemElementInterface_giveNumDofManEnrichments(const DofManager &iDMan, XfemManager &iXMan) const
Computes total number of enrichments in a node.
Implementation of matrix containing floating point numbers.
Definition: floatmatrix.h:94
This class manages the xfem part.
Definition: xfemmanager.h:109
const FloatArray & giveNodeCoordinates() const
As giveCoordinates, but non-virtual and therefore faster (because it can be inlined).
Definition: node.h:120
void resize(int rows, int cols)
Checks size of receiver towards requested bounds.
Definition: floatmatrix.C:1358
bool isElementEnriched(const Element *elem)
Definition: xfemmanager.C:104
Class Interface.
Definition: interface.h:82
bool mUsePlaneStrain
Flag that tells if plane stress or plane strain is assumed.
void zero()
Zeroes all coefficients of receiver.
Definition: floatarray.C:658
EnrichmentItem * giveEnrichmentItem(int n)
Definition: xfemmanager.h:184
virtual int giveNumberOfEdges() const
Returns number of edges.
Definition: feinterpol.h:479
virtual bool computeLocalCoordinates(FloatArray &answer, const FloatArray &gcoords)
Computes the element local coordinates from given global coordinates.
Definition: element.C:1222
virtual void XfemElementInterface_partitionElement(std::vector< Triangle > &oTriangles, const std::vector< FloatArray > &iPoints)
Partitions the element into patches by a triangulation.
int giveElementPlaceInArray(int iGlobalElNum) const
Returns the array index of the element with global number iGlobalElNum, so that it can be fetched by ...
Definition: domain.C:183
virtual FloatArray * giveCoordinates()
Definition: node.h:114
Domain * giveDomain() const
Definition: femcmpnn.h:100
static double calcXiZeroLevel(const double &iQ1, const double &iQ2)
void push_back(const double &iVal)
Add one element.
Definition: floatarray.h:118
int giveSize() const
Definition: intarray.h:203
int giveSize() const
Returns the size of receiver.
Definition: floatarray.h:218
void computeNCohesive(FloatMatrix &oN, GaussPoint &iGP, int iEnrItemIndex, const std::vector< int > &iTouchingEnrItemIndices)
Compute N-matrix for cohesive zone.
virtual double giveCoordinate(int i)
Definition: dofmanager.h:380
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
Domain * giveDomain()
Definition: xfemmanager.h:202
Class implementing node in finite element mesh.
Definition: node.h:87
Node * giveNode(int i) const
Returns reference to the i-th node of element.
Definition: element.h:610
void computeDisplacementJump(GaussPoint &iGP, FloatArray &oJump, const FloatArray &iSolVec, const FloatMatrix &iNMatrix)
Class representing integration point in finite element program.
Definition: gausspoint.h:93
Class representing solution step.
Definition: timestep.h:80
EnrichmentItem with geometry described by BasicGeometry.
virtual double evaldNdx(FloatMatrix &answer, const FloatArray &lcoords, const FEICellGeometry &cellgeo)=0
Evaluates the matrix of derivatives of interpolation functions (shape functions) at given point...
PatchIntegrationRule provides integration over a triangle patch.
const FloatArray & giveNaturalCoordinates()
Returns coordinate array of receiver.
Definition: gausspoint.h:138
void resize(int s)
Resizes receiver towards requested size.
Definition: floatarray.C:631

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