OOFEM  2.4
OOFEM.org - Object Oriented Finite Element Solver
geometrybasedei.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 "xfem/geometrybasedei.h"
36 #include "xfemmanager.h"
37 
38 #include "spatiallocalizer.h"
39 #include "classfactory.h"
40 #include "element.h"
41 #include "node.h"
42 #include "mathfem.h"
43 #include "feinterpol.h"
44 #include "gausspoint.h"
45 #include "dynamicinputrecord.h"
46 #include "dynamicdatareader.h"
47 #include "geometry.h"
48 
50 #include "xfem/propagationlaw.h"
52 
53 #include "engngm.h"
54 #include "timestep.h"
55 
56 #include <string>
57 #include <algorithm>
58 #include <set>
59 #include <memory>
60 
61 namespace oofem {
62 //REGISTER_EnrichmentItem(GeometryBasedEI)
63 
65  EnrichmentItem(n, xm, aDomain)
66 {}
67 
69 {}
70 
72 {
73  IRResultType result; // Required by IR_GIVE_FIELD macro
74  std :: string name;
75 
76  // Instantiate enrichment function
78  result = mir->giveRecordKeywordField(name);
79 
80  if ( result != IRRT_OK ) {
81  mir->report_error(this->giveClassName(), __func__, "", result, __FILE__, __LINE__);
82  }
83 
85  if ( mpEnrichmentFunc != NULL ) {
87  } else {
88  OOFEM_ERROR( "failed to create enrichment function (%s)", name.c_str() );
89  }
90 
91 
92  // Instantiate geometry
94  result = mir->giveRecordKeywordField(name);
95  mpBasicGeometry.reset( classFactory.createGeometry( name.c_str() ) );
96  if ( !mpBasicGeometry ) {
97  OOFEM_ERROR( "unknown geometry domain (%s)", name.c_str() );
98  }
99 
100  mpBasicGeometry->initializeFrom(mir);
101 
102  // Instantiate EnrichmentFront
103  if ( mEnrFrontIndex == 0 ) {
106  } else {
107  std :: string enrFrontNameStart, enrFrontNameEnd;
108 
110  result = enrFrontStartIr->giveRecordKeywordField(enrFrontNameStart);
111 
112  mpEnrichmentFrontStart = classFactory.createEnrichmentFront( enrFrontNameStart.c_str() );
113  if ( mpEnrichmentFrontStart != NULL ) {
114  mpEnrichmentFrontStart->initializeFrom(enrFrontStartIr);
115  } else {
116  OOFEM_ERROR( "Failed to create enrichment front (%s)", enrFrontNameStart.c_str() );
117  }
118 
120  result = enrFrontEndIr->giveRecordKeywordField(enrFrontNameEnd);
121 
122  mpEnrichmentFrontEnd = classFactory.createEnrichmentFront( enrFrontNameEnd.c_str() );
123  if ( mpEnrichmentFrontEnd != NULL ) {
124  mpEnrichmentFrontEnd->initializeFrom(enrFrontEndIr);
125  } else {
126  OOFEM_ERROR( "Failed to create enrichment front (%s)", enrFrontNameEnd.c_str() );
127  }
128  }
129 
130 
131  // Instantiate PropagationLaw
132  if ( mPropLawIndex == 0 ) {
134  } else {
135  std :: string propLawName;
136 
138  result = propLawir->giveRecordKeywordField(propLawName);
139 
140  mpPropagationLaw = classFactory.createPropagationLaw( propLawName.c_str() );
141  if ( mpPropagationLaw != NULL ) {
142  mpPropagationLaw->initializeFrom(propLawir);
143  } else {
144  OOFEM_ERROR( "Failed to create propagation law (%s)", propLawName.c_str() );
145  }
146  }
147 
148  // Set start of the enrichment dof pool for the given EI
149  int xDofPoolAllocSize = this->giveDofPoolSize();
150  this->startOfDofIdPool = this->giveDomain()->giveNextFreeDofID(xDofPoolAllocSize);
151  this->endOfDofIdPool = this->startOfDofIdPool + xDofPoolAllocSize - 1;
152 
153 
154  XfemManager *xMan = this->giveDomain()->giveXfemManager();
155  // mpEnrichmentDomain->CallNodeEnrMarkerUpdate(* this, * xMan);
156  this->updateNodeEnrMarker(* xMan);
157 
158 // writeVtkDebug();
159 
160  return 1;
161 }
162 
164 {
165  // Set start of the enrichment dof pool for the given EI
166  int xDofPoolAllocSize = this->giveDofPoolSize();
167  this->startOfDofIdPool = this->giveDomain()->giveNextFreeDofID(xDofPoolAllocSize);
168  this->endOfDofIdPool = this->startOfDofIdPool + xDofPoolAllocSize - 1;
169 
170 // printf("startOfDofIdPool: %d\n", startOfDofIdPool);
171 // printf("endOfDofIdPool: %d\n", endOfDofIdPool);
172 
173  XfemManager *xMan = this->giveDomain()->giveXfemManager();
174  // mpEnrichmentDomain->CallNodeEnrMarkerUpdate(* this, * xMan);
175  this->updateNodeEnrMarker(* xMan);
176 }
177 
179 {
180  DynamicInputRecord *eiRec = new DynamicInputRecord();
182 
185 
188  }
191  }
192 
194 
195 
196  // Enrichment function
197  DynamicInputRecord *efRec = new DynamicInputRecord();
200 
201  // Geometry
202  DynamicInputRecord *geoRec = new DynamicInputRecord();
203  mpBasicGeometry->giveInputRecord(* geoRec);
205 
206 
207  // Enrichment front
208  if ( mEnrFrontIndex != 0 ) {
209  DynamicInputRecord *efrRecStart = new DynamicInputRecord();
210  mpEnrichmentFrontStart->giveInputRecord(* efrRecStart);
212 
213  DynamicInputRecord *efrRecEnd = new DynamicInputRecord();
216  }
217 
218  // Propagation law
219  if ( mPropLawIndex != 0 ) {
220  DynamicInputRecord *plRec = new DynamicInputRecord();
221  this->mpPropagationLaw->giveInputRecord(* plRec);
223  }
224 }
225 
227 {
228  // Update enrichments ...
229  XfemManager *xMan = this->giveDomain()->giveXfemManager();
230 
231  this->updateNodeEnrMarker(* xMan);
232  // ... and create new dofs if necessary.
234 }
235 
237 {
238  updateLevelSets(ixFemMan);
239 
240  Domain *domain = giveDomain();
241  SpatialLocalizer *localizer = domain->giveSpatialLocalizer();
242 
243  mNodeEnrMarkerMap.clear();
244  TipInfo tipInfoStart, tipInfoEnd;
245  bool foundTips = mpBasicGeometry->giveTips(tipInfoStart, tipInfoEnd);
246 
247 
248  FloatArray center;
249  double radius = 0.0;
250  giveBoundingSphere(center, radius);
251 
252 
253  IntArray elList;
254  localizer->giveAllElementsWithNodesWithinBox(elList, center, radius);
255 
256  // Loop over elements and use the level sets to mark nodes belonging to completely cut elements.
257  for ( int elNum: elList ) {
258  Element *el = domain->giveElement(elNum);
259  int nElNodes = el->giveNumberOfNodes();
260 
261  double minSignPhi = 1, maxSignPhi = -1;
262  double minPhi = std :: numeric_limits< double > :: max();
263  double maxPhi = std :: numeric_limits< double > :: min();
264 
265  FloatArray elCenter(2);
266  elCenter.zero();
267 
268  for ( int elNodeInd = 1; elNodeInd <= nElNodes; elNodeInd++ ) {
269  int nGlob = el->giveNode(elNodeInd)->giveGlobalNumber();
270 
271  double levelSetNormalNode = 0.0;
272  if ( evalLevelSetNormalInNode( levelSetNormalNode, nGlob, el->giveNode(elNodeInd)->giveNodeCoordinates() ) ) {
273  minSignPhi = std :: min( sgn(minSignPhi), sgn(levelSetNormalNode) );
274  maxSignPhi = std :: max( sgn(maxSignPhi), sgn(levelSetNormalNode) );
275 
276  minPhi = std :: min(minPhi, levelSetNormalNode);
277  maxPhi = std :: max(maxPhi, levelSetNormalNode);
278  }
279 
280  elCenter.at(1) += el->giveDofManager(elNodeInd)->giveCoordinate(1) / double ( nElNodes );
281  elCenter.at(2) += el->giveDofManager(elNodeInd)->giveCoordinate(2) / double ( nElNodes );
282  }
283 
284 
285  int numEdgeIntersec = 0;
286 
287  if ( minPhi * maxPhi < mLevelSetTol ) { // If the level set function changes sign within the element.
288  // Count the number of element edges intersected by the interface
289  //int numEdges = nElNodes; // TODO: Is this assumption always true?
290  int numEdges = el->giveInterpolation()->giveNumberOfEdges(); //JIM
291 
292  for ( int edgeIndex = 1; edgeIndex <= numEdges; edgeIndex++ ) {
293  IntArray bNodes;
294  el->giveInterpolation()->boundaryGiveNodes(bNodes, edgeIndex);
295 
296  int niLoc = bNodes.at(1);
297  int niGlob = el->giveNode(niLoc)->giveGlobalNumber();
298  const FloatArray &nodePosI = el->giveNode(niLoc)->giveNodeCoordinates();
299  int njLoc = bNodes.at(2);
300  int njGlob = el->giveNode(njLoc)->giveGlobalNumber();
301  const FloatArray &nodePosJ = el->giveNode(njLoc)->giveNodeCoordinates();
302 
303  double levelSetNormalNodeI = 0.0;
304  double levelSetNormalNodeJ = 0.0;
305  if ( evalLevelSetNormalInNode(levelSetNormalNodeI, niGlob, nodePosI) && evalLevelSetNormalInNode(levelSetNormalNodeJ, njGlob, nodePosJ) ) {
306  if ( levelSetNormalNodeI * levelSetNormalNodeJ < mLevelSetTol ) {
307  double xi = calcXiZeroLevel(levelSetNormalNodeI, levelSetNormalNodeJ);
308 
309  // Compute the exact value of the tangential level set
310  // from the discretized geometry instead of interpolating.
311  double tangDist = 0.0, arcPos = 0.0;
312  const FloatArray &posI = * ( el->giveDofManager(niLoc)->giveCoordinates() );
313  const FloatArray &posJ = * ( el->giveDofManager(njLoc)->giveCoordinates() );
314  FloatArray pos;
315  pos.add(0.5 * ( 1.0 - xi ), posI);
316  pos.add(0.5 * ( 1.0 + xi ), posJ);
317  pos.resizeWithValues(2);
318 
319  mpBasicGeometry->computeTangentialSignDist(tangDist, pos, arcPos);
320 
321  double gamma = tangDist;
322 
323  if ( gamma > 0.0 ) {
324  numEdgeIntersec++;
325  }
326  }
327  }
328  }
329 
330 
331  if ( numEdgeIntersec >= 1 ) {
332  // If we captured a cut element.
333  for ( int elNodeInd = 1; elNodeInd <= nElNodes; elNodeInd++ ) {
334  int nGlob = el->giveNode(elNodeInd)->giveGlobalNumber();
335 
336  auto res = mNodeEnrMarkerMap.find(nGlob);
337  if ( res == mNodeEnrMarkerMap.end() ) {
338  mNodeEnrMarkerMap [ nGlob ] = NodeEnr_BULK;
339  }
340  }
341  }
342  }
343  }
344 
345  // Mark tip nodes for special treatment.
346  if(foundTips) {
347  XfemManager *xMan = this->giveDomain()->giveXfemManager();
350  }
351 }
352 
354 {
355  mLevelSetNormalDirMap.clear();
356  mLevelSetTangDirMap.clear();
357 
358  FloatArray center;
359  double radius = 0.0;
360  giveBoundingSphere(center, radius);
361 
362  Domain *domain = giveDomain();
363  SpatialLocalizer *localizer = domain->giveSpatialLocalizer();
364 
365  std :: list< int >nodeList;
366  localizer->giveAllNodesWithinBox(nodeList, center, radius);
367 
368  for ( int nodeNum: nodeList ) {
369  Node *node = ixFemMan.giveDomain()->giveNode(nodeNum);
370 
371  // Extract node coord
372  FloatArray pos( * node->giveCoordinates() );
373  pos.resizeWithValues(2);
374 
375  // Calc normal sign dist
376  double phi = 0.0;
377  mpBasicGeometry->computeNormalSignDist(phi, pos);
378  mLevelSetNormalDirMap [ nodeNum ] = phi;
379 
380  // Calc tangential sign dist
381  double gamma = 0.0, arcPos = -1.0;
382  mpBasicGeometry->computeTangentialSignDist(gamma, pos, arcPos);
383  mLevelSetTangDirMap [ nodeNum ] = gamma;
384  }
385 
386  mLevelSetsNeedUpdate = false;
387 }
388 
389 void GeometryBasedEI :: evaluateEnrFuncInNode(std :: vector< double > &oEnrFunc, const Node &iNode) const
390 {
391  double levelSetGP = 0.0;
392  const FloatArray &globalCoord = iNode.giveNodeCoordinates();
393  int nodeInd = iNode.giveNumber();
394  this->evalLevelSetNormalInNode(levelSetGP, nodeInd, globalCoord);
395 
396  // const int dim = this->giveDomain()->giveNumberOfSpatialDimensions();
397  // FloatArray gradLevelSetGP(dim);
398 
399  double tangDist = 0.0, minDistArcPos = 0.0;
400  mpBasicGeometry->computeTangentialSignDist(tangDist, globalCoord, minDistArcPos);
401 
402  FloatArray edGlobalCoord, localTangDir;
403 
404  mpBasicGeometry->giveGlobalCoordinates(edGlobalCoord, minDistArcPos);
405  mpBasicGeometry->giveTangent(localTangDir, minDistArcPos);
406 
407 
408  const EfInput efInput(globalCoord, levelSetGP, nodeInd, edGlobalCoord, minDistArcPos, localTangDir);
409 
410 
411  if ( nodeInd == -1 ) {
412  // Bulk enrichment
413  oEnrFunc.resize(1, 0.0);
414  mpEnrichmentFunc->evaluateEnrFuncAt(oEnrFunc [ 0 ], globalCoord, levelSetGP);
415  } else {
416  auto res = mNodeEnrMarkerMap.find(nodeInd);
417  if ( res != mNodeEnrMarkerMap.end() ) {
418  switch ( res->second ) {
419  case NodeEnr_NONE:
420  break;
421  case NodeEnr_BULK:
422  // Bulk enrichment
423  oEnrFunc.resize(1, 0.0);
424  mpEnrichmentFunc->evaluateEnrFuncAt(oEnrFunc [ 0 ], globalCoord, levelSetGP);
425  break;
426  case NodeEnr_START_TIP:
427  mpEnrichmentFrontStart->evaluateEnrFuncAt(oEnrFunc, efInput);
428  break;
429  case NodeEnr_END_TIP:
430  mpEnrichmentFrontEnd->evaluateEnrFuncAt(oEnrFunc, efInput);
431  break;
433  mpEnrichmentFrontStart->evaluateEnrFuncAt(oEnrFunc, efInput);
434  mpEnrichmentFrontEnd->evaluateEnrFuncAt(oEnrFunc, efInput);
435  break;
436  }
437  } else {
438  printf("In EnrichmentItem :: evaluateEnrFuncAt: mNodeEnrMarkerMap not found for iNodeInd %d\n", nodeInd);
439  }
440  }
441 }
442 
443 void GeometryBasedEI :: evaluateEnrFuncAt(std :: vector< double > &oEnrFunc, const FloatArray &iGlobalCoord, const FloatArray &iLocalCoord, int iNodeInd, const Element &iEl) const
444 {
445  FloatArray N;
446  iEl.giveInterpolation()->evalN( N, iLocalCoord, FEIElementGeometryWrapper(& iEl) );
447 
448  evaluateEnrFuncAt( oEnrFunc, iGlobalCoord, iLocalCoord, iNodeInd, iEl, N, iEl.giveDofManArray() );
449 }
450 
451 void GeometryBasedEI :: evaluateEnrFuncAt(std :: vector< double > &oEnrFunc, const FloatArray &iGlobalCoord, const FloatArray &iLocalCoord, int iNodeInd, const Element &iEl, const FloatArray &iN, const IntArray &iElNodes) const
452 {
453  double levelSetGP = 0.0;
454  evalLevelSetNormal(levelSetGP, iGlobalCoord, iN, iElNodes);
455 
456  // const int dim = this->giveDomain()->giveNumberOfSpatialDimensions();
457  // FloatArray gradLevelSetGP(dim);
458 
459  double tangDist = 0.0, minDistArcPos = 0.0;
460  const FloatArray globalCoord = {
461  iGlobalCoord [ 0 ], iGlobalCoord [ 1 ]
462  };
463  mpBasicGeometry->computeTangentialSignDist(tangDist, globalCoord, minDistArcPos);
464 
465  FloatArray edGlobalCoord, localTangDir;
466 
467  mpBasicGeometry->giveGlobalCoordinates(edGlobalCoord, minDistArcPos);
468  mpBasicGeometry->giveTangent(localTangDir, minDistArcPos);
469 
470 
471  const EfInput efInput(iGlobalCoord, levelSetGP, iNodeInd, edGlobalCoord, minDistArcPos, localTangDir);
472 
473 
474  if ( iNodeInd == -1 ) {
475  // Bulk enrichment
476  oEnrFunc.resize(1, 0.0);
477  mpEnrichmentFunc->evaluateEnrFuncAt(oEnrFunc [ 0 ], iGlobalCoord, levelSetGP);
478  } else {
479  auto res = mNodeEnrMarkerMap.find(iNodeInd);
480  if ( res != mNodeEnrMarkerMap.end() ) {
481  switch ( res->second ) {
482  case NodeEnr_NONE:
483  break;
484  case NodeEnr_BULK:
485  // Bulk enrichment
486  oEnrFunc.resize(1, 0.0);
487  mpEnrichmentFunc->evaluateEnrFuncAt(oEnrFunc [ 0 ], iGlobalCoord, levelSetGP);
488  break;
489  case NodeEnr_START_TIP:
490  mpEnrichmentFrontStart->evaluateEnrFuncAt(oEnrFunc, efInput);
491  break;
492  case NodeEnr_END_TIP:
493  mpEnrichmentFrontEnd->evaluateEnrFuncAt(oEnrFunc, efInput);
494  break;
496  mpEnrichmentFrontStart->evaluateEnrFuncAt(oEnrFunc, efInput);
497  mpEnrichmentFrontEnd->evaluateEnrFuncAt(oEnrFunc, efInput);
498  break;
499  }
500  } else {
501  printf("In EnrichmentItem :: evaluateEnrFuncAt: mNodeEnrMarkerMap not found for iNodeInd %d\n", iNodeInd);
502  }
503  }
504 }
505 
506 void GeometryBasedEI :: evaluateEnrFuncDerivAt(std :: vector< FloatArray > &oEnrFuncDeriv, const FloatArray &iGlobalCoord, const FloatArray &iLocalCoord, int iNodeInd, const Element &iEl) const
507 {
508  FloatMatrix dNdx;
509  FloatArray N;
510  FEInterpolation *interp = iEl.giveInterpolation();
511  const FEIElementGeometryWrapper geomWrapper(& iEl);
512  interp->evaldNdx(dNdx, iLocalCoord, geomWrapper);
513  interp->evalN(N, iLocalCoord, geomWrapper);
514 
515  evaluateEnrFuncDerivAt( oEnrFuncDeriv, iGlobalCoord, iLocalCoord, iNodeInd, iEl, N, dNdx, iEl.giveDofManArray() );
516 }
517 
518 void GeometryBasedEI :: evaluateEnrFuncDerivAt(std :: vector< FloatArray > &oEnrFuncDeriv, const FloatArray &iGlobalCoord, const FloatArray &iLocalCoord, int iNodeInd, const Element &iEl, const FloatArray &iN, const FloatMatrix &idNdX, const IntArray &iElNodes) const
519 {
520  auto res = mNodeEnrMarkerMap.find(iNodeInd);
521  if ( res != mNodeEnrMarkerMap.end() ) {
522  double levelSetGP = 0.0;
523  evalLevelSetNormal(levelSetGP, iGlobalCoord, iN, iElNodes);
524 
525  const int dim = 2;
526  FloatArray gradLevelSetGP(dim);
527  evalGradLevelSetNormal(gradLevelSetGP, iGlobalCoord, idNdX, iElNodes);
528 
529  double tangDist = 0.0, minDistArcPos = 0.0;
530  mpBasicGeometry->computeTangentialSignDist(tangDist, iGlobalCoord, minDistArcPos);
531 
532  FloatArray edGlobalCoord, localTangDir;
533 
534 
535  mpBasicGeometry->giveGlobalCoordinates(edGlobalCoord, minDistArcPos);
536  mpBasicGeometry->giveTangent(localTangDir, minDistArcPos);
537 
538  const EfInput efInput(iGlobalCoord, levelSetGP, iNodeInd, edGlobalCoord, minDistArcPos, localTangDir);
539 
540  switch ( res->second ) {
541  case NodeEnr_NONE:
542  break;
543  case NodeEnr_BULK:
544  oEnrFuncDeriv.resize(1);
545  mpEnrichmentFunc->evaluateEnrFuncDerivAt(oEnrFuncDeriv [ 0 ], iGlobalCoord, levelSetGP, gradLevelSetGP);
546  break;
547  case NodeEnr_START_TIP:
548  mpEnrichmentFrontStart->evaluateEnrFuncDerivAt(oEnrFuncDeriv, efInput, gradLevelSetGP);
549  break;
550  case NodeEnr_END_TIP:
551  mpEnrichmentFrontEnd->evaluateEnrFuncDerivAt(oEnrFuncDeriv, efInput, gradLevelSetGP);
552  break;
554  mpEnrichmentFrontStart->evaluateEnrFuncDerivAt(oEnrFuncDeriv, efInput, gradLevelSetGP);
555  mpEnrichmentFrontEnd->evaluateEnrFuncDerivAt(oEnrFuncDeriv, efInput, gradLevelSetGP);
556  break;
557  }
558  } else {
559  printf("In EnrichmentItem :: evaluateEnrFuncDerivAt: mNodeEnrMarkerMap not found for iNodeInd %d\n", iNodeInd);
560  }
561 }
562 
563 void GeometryBasedEI :: evaluateEnrFuncJumps(std :: vector< double > &oEnrFuncJumps, int iNodeInd, GaussPoint &iGP, bool iGPLivesOnCurrentCrack) const
564 {
565  double normalSignDist = 0.0;
566 
567  SpatialLocalizer *localizer = this->giveDomain()->giveSpatialLocalizer();
568 
569  Element *el = localizer->giveElementContainingPoint( iGP.giveGlobalCoordinates() );
570  if ( el != NULL ) {
571  FloatArray N;
572  FEInterpolation *interp = el->giveInterpolation();
573  interp->evalN( N, iGP.giveNaturalCoordinates(), FEIElementGeometryWrapper(el) );
574  //el->computeLocalCoordinates(locCoord, iGlobalCoord);
575 
576  evalLevelSetNormal( normalSignDist, iGP.giveGlobalCoordinates(), N, el->giveDofManArray() );
577  }
578 
579  // this->interpLevelSet(normalSignDist, iGP.giveGlobalCoordinates() );
580 
581  auto res = mNodeEnrMarkerMap.find(iNodeInd);
582  if ( res != mNodeEnrMarkerMap.end() ) {
583  switch ( res->second ) {
584  case NodeEnr_NONE:
585  break;
586  case NodeEnr_BULK:
587  oEnrFuncJumps.resize(1);
588  mpEnrichmentFunc->giveJump(oEnrFuncJumps);
589  break;
590  case NodeEnr_START_TIP:
591  mpEnrichmentFrontStart->evaluateEnrFuncJumps(oEnrFuncJumps, iGP, iNodeInd, iGPLivesOnCurrentCrack, normalSignDist);
592  break;
593  case NodeEnr_END_TIP:
594  mpEnrichmentFrontEnd->evaluateEnrFuncJumps(oEnrFuncJumps, iGP, iNodeInd, iGPLivesOnCurrentCrack, normalSignDist);
595  break;
597  mpEnrichmentFrontStart->evaluateEnrFuncJumps(oEnrFuncJumps, iGP, iNodeInd, iGPLivesOnCurrentCrack, normalSignDist);
598  mpEnrichmentFrontEnd->evaluateEnrFuncJumps(oEnrFuncJumps, iGP, iNodeInd, iGPLivesOnCurrentCrack, normalSignDist);
599  break;
600  }
601  } else {
602  printf("In EnrichmentItem :: evaluateEnrFuncDerivAt: evaluateEnrFuncJumps not found for iNodeInd %d\n", iNodeInd);
603  }
604 }
605 
606 void GeometryBasedEI :: computeIntersectionPoints(std :: vector< FloatArray > &oIntersectionPoints, std :: vector< int > &oIntersectedEdgeInd, Element *element, std :: vector< double > &oMinDistArcPos) const
607 {
608  if ( isElementEnriched(element) ) {
609  // Use the level set functions to compute intersection points
610 
611  // Loop over element edges; an edge is intersected if the
612  // node values of the level set functions have different signs
613 
614  // int numEdges = element->giveNumberOfBoundarySides();
615  //int numEdges = element->giveNumberOfNodes(); // TODO: Is this assumption always true?
616  int numEdges = element->giveInterpolation()->giveNumberOfEdges();
617 
618  for ( int edgeIndex = 1; edgeIndex <= numEdges; edgeIndex++ ) {
619  IntArray bNodes;
620  element->giveInterpolation()->boundaryGiveNodes(bNodes, edgeIndex);
621 
622  int nsLoc = bNodes.at(1);
623  int nsGlob = element->giveNode(nsLoc)->giveGlobalNumber();
624  int neLoc = bNodes.at(2);
625  int neGlob = element->giveNode(neLoc)->giveGlobalNumber();
626 
627  double phiS = 1.0;
628  bool foundPhiS = evalLevelSetNormalInNode( phiS, nsGlob, element->giveNode(nsLoc)->giveNodeCoordinates() );
629 
630  double phiE = 1.0;
631  bool foundPhiE = evalLevelSetNormalInNode( phiE, neGlob, element->giveNode(neLoc)->giveNodeCoordinates() );
632 
633  const FloatArray &xS = * ( element->giveNode(nsLoc)->giveCoordinates() );
634  const FloatArray &xE = * ( element->giveNode(neLoc)->giveCoordinates() );
635  const double edgeLength2 = xS.distance_square(xE);
636  const double gammaRelTol = 1.0e-2;
637 
638  if ( ( foundPhiS && foundPhiE ) && phiS * phiE < mLevelSetRelTol * mLevelSetRelTol * edgeLength2 ) {
639  // Intersection detected
640 
641  double xi = calcXiZeroLevel(phiS, phiE);
642 
643  // Compute the exact value of the tangential level set
644  // from the discretized geometry instead of interpolating.
645  double tangDist = 0.0, arcPos = 0.0;
646  const FloatArray &posI = * ( element->giveDofManager(nsLoc)->giveCoordinates() );
647  const FloatArray &posJ = * ( element->giveDofManager(neLoc)->giveCoordinates() );
648  FloatArray pos;
649  pos.add(0.5 * ( 1.0 - xi ), posI);
650  pos.add(0.5 * ( 1.0 + xi ), posJ);
651  pos.resizeWithValues(2);
652  mpBasicGeometry->computeTangentialSignDist(tangDist, pos, arcPos);
653  double gamma = tangDist;
654 
655 
656  // If we are inside in tangential direction
657  if ( gamma > -gammaRelTol * sqrt(edgeLength2) ) {
658  if ( fabs(phiS - phiE) < mLevelSetTol ) {
659  // If the crack is parallel to the edge.
660 
661  FloatArray ps( * ( element->giveDofManager(nsLoc)->giveCoordinates() ) );
662  ps.resizeWithValues(2);
663  FloatArray pe( * ( element->giveDofManager(neLoc)->giveCoordinates() ) );
664  pe.resizeWithValues(2);
665 
666  // Check that the intersection points have not already been identified.
667  // This may happen if the crack intersects the element exactly at a node,
668  // so that intersection is detected for both element edges in that node.
669 
670  bool alreadyFound = false;
671 
672  int numPointsOld = oIntersectionPoints.size();
673  for ( int k = 1; k <= numPointsOld; k++ ) {
674  double dist = ps.distance(oIntersectionPoints [ k - 1 ]);
675 
676  if ( dist < mLevelSetTol ) {
677  alreadyFound = true;
678  break;
679  }
680  }
681 
682  if ( !alreadyFound ) {
683  oIntersectionPoints.push_back(ps);
684 
685  double arcPos = 0.0, tangDist = 0.0;
686  mpBasicGeometry->computeTangentialSignDist(tangDist, ps, arcPos);
687  oMinDistArcPos.push_back(arcPos);
688 
689  oIntersectedEdgeInd.push_back(edgeIndex);
690  }
691 
692  alreadyFound = false;
693 
694  numPointsOld = oIntersectionPoints.size();
695  for ( int k = 1; k <= numPointsOld; k++ ) {
696  double dist = pe.distance(oIntersectionPoints [ k - 1 ]);
697 
698  if ( dist < mLevelSetTol ) {
699  alreadyFound = true;
700  break;
701  }
702  }
703 
704  if ( !alreadyFound ) {
705  oIntersectionPoints.push_back(pe);
706 
707  double arcPos = 0.0, tangDist = 0.0;
708  mpBasicGeometry->computeTangentialSignDist(tangDist, pe, arcPos);
709  oMinDistArcPos.push_back(arcPos);
710 
711  oIntersectedEdgeInd.push_back(edgeIndex);
712  }
713  } else {
714  FloatArray ps( * ( element->giveDofManager(nsLoc)->giveCoordinates() ) );
715  FloatArray pe( * ( element->giveDofManager(neLoc)->giveCoordinates() ) );
716 
717  FloatArray p;
718  p.resizeWithValues(2);
719 
720  for ( int i = 1; i <= 2; i++ ) {
721  ( p.at(i) ) = 0.5 * ( 1.0 - xi ) * ( ( ps.at(i) ) ) + 0.5 * ( 1.0 + xi ) * ( ( pe.at(i) ) );
722  }
723 
724 
725  // Check that the intersection point has not already been identified.
726  // This may happen if the crack intersects the element exactly at a node,
727  // so that intersection is detected for both element edges in that node.
728 
729  bool alreadyFound = false;
730 
731 
732  int numPointsOld = oIntersectionPoints.size();
733  for ( int k = 1; k <= numPointsOld; k++ ) {
734  double dist = p.distance(oIntersectionPoints [ k - 1 ]);
735 
736  if ( dist < mLevelSetTol ) {
737  alreadyFound = true;
738  break;
739  }
740  }
741 
742  if ( !alreadyFound ) {
743  oIntersectionPoints.push_back(p);
744 
745  double arcPos = 0.0, tangDist = 0.0;
746  mpBasicGeometry->computeTangentialSignDist(tangDist, p, arcPos);
747  oMinDistArcPos.push_back(arcPos);
748 
749  oIntersectedEdgeInd.push_back(edgeIndex);
750  }
751  }
752  }
753  }
754  }
755  }
756 }
757 
758 void GeometryBasedEI :: computeIntersectionPoints(std :: vector< FloatArray > &oIntersectionPoints, std :: vector< int > &oIntersectedEdgeInd, Element *element, const Triangle &iTri, std :: vector< double > &oMinDistArcPos) const
759 {
760  // Use the level set functions to compute intersection points
761 
762  // Loop over element edges; an edge is intersected if the
763  // node values of the level set functions have different signs
764 
765  const int numEdges = 3;
766 
767  for ( int edgeIndex = 1; edgeIndex <= numEdges; edgeIndex++ ) {
768  FloatArray xS, xE;
769 
770  // Global coordinates of vertices
771  switch ( edgeIndex ) {
772  case 1:
773  xS = iTri.giveVertex(1);
774  xE = iTri.giveVertex(2);
775  break;
776  case 2:
777  xS = iTri.giveVertex(2);
778  xE = iTri.giveVertex(3);
779  break;
780 
781  case 3:
782  xS = iTri.giveVertex(3);
783  xE = iTri.giveVertex(1);
784  break;
785  default:
786  break;
787  }
788 
789  // Local coordinates of vertices
790  FloatArray xiS;
791  element->computeLocalCoordinates(xiS, xS);
792  FloatArray xiE;
793  element->computeLocalCoordinates(xiE, xE);
794 
795  const IntArray &elNodes = element->giveDofManArray();
796  FloatArray Ns, Ne;
797  FEInterpolation *interp = element->giveInterpolation();
798 
799  interp->evalN( Ns, xiS, FEIElementGeometryWrapper(element) );
800  interp->evalN( Ne, xiE, FEIElementGeometryWrapper(element) );
801 
802 
803  double phiS = 0.0, phiE = 0.0;
804  double gammaS = 0.0, gammaE = 0.0;
805 
806  bool levelSetDefinedInAllNodes = true;
807  for ( int i = 1; i <= Ns.giveSize(); i++ ) {
808  double phiSNode = 0.0;
809  if ( evalLevelSetNormalInNode( phiSNode, elNodes [ i - 1 ], element->giveNode(i)->giveNodeCoordinates() ) ) {
810  phiS += Ns.at(i) * phiSNode;
811  } else {
812  levelSetDefinedInAllNodes = false;
813  }
814 
815  double gammaSNode = 0.0;
816  if ( evalLevelSetTangInNode( gammaSNode, elNodes [ i - 1 ], element->giveNode(i)->giveNodeCoordinates() ) ) {
817  gammaS += Ns.at(i) * gammaSNode;
818  } else {
819  levelSetDefinedInAllNodes = false;
820  }
821 
822  double phiENode = 0.0;
823  if ( evalLevelSetNormalInNode( phiENode, elNodes [ i - 1 ], element->giveNode(i)->giveNodeCoordinates() ) ) {
824  phiE += Ne.at(i) * phiENode;
825  } else {
826  levelSetDefinedInAllNodes = false;
827  }
828 
829  double gammaENode = 0.0;
830  if ( evalLevelSetTangInNode( gammaENode, elNodes [ i - 1 ], element->giveNode(i)->giveNodeCoordinates() ) ) {
831  gammaE += Ne.at(i) * gammaENode;
832  } else {
833  levelSetDefinedInAllNodes = false;
834  }
835  }
836 
837  if ( phiS * phiE < mLevelSetTol2 && levelSetDefinedInAllNodes ) {
838  // Intersection detected
839 
840  double xi = calcXiZeroLevel(phiS, phiE);
841  double gamma = 0.5 * ( 1.0 - xi ) * gammaS + 0.5 * ( 1.0 + xi ) * gammaE;
842 
843  // If we are inside in tangential direction
844  if ( gamma > 0.0 ) {
845  if ( fabs(phiS - phiE) < mLevelSetTol ) {
846  // If the crack is parallel to the edge.
847 
848  FloatArray ps(xS);
849  ps.resizeWithValues(2);
850  FloatArray pe(xE);
851  pe.resizeWithValues(2);
852 
853  // Check that the intersection points have not already been identified.
854  // This may happen if the crack intersects the element exactly at a node,
855  // so that intersection is detected for both element edges in that node.
856 
857  bool alreadyFound = false;
858 
859  int numPointsOld = oIntersectionPoints.size();
860  for ( int k = 1; k <= numPointsOld; k++ ) {
861  double dist = ps.distance(oIntersectionPoints [ k - 1 ]);
862 
863  if ( dist < mLevelSetTol ) {
864  alreadyFound = true;
865  break;
866  }
867  }
868 
869  if ( !alreadyFound ) {
870  oIntersectionPoints.push_back(ps);
871 
872  double arcPos = 0.0, tangDist = 0.0;
873  mpBasicGeometry->computeTangentialSignDist(tangDist, ps, arcPos);
874  oMinDistArcPos.push_back(arcPos);
875 
876  oIntersectedEdgeInd.push_back(edgeIndex);
877  }
878 
879  alreadyFound = false;
880 
881  numPointsOld = oIntersectionPoints.size();
882  for ( int k = 1; k <= numPointsOld; k++ ) {
883  double dist = pe.distance(oIntersectionPoints [ k - 1 ]);
884 
885  if ( dist < mLevelSetTol ) {
886  alreadyFound = true;
887  break;
888  }
889  }
890 
891  if ( !alreadyFound ) {
892  oIntersectionPoints.push_back(pe);
893 
894  double arcPos = 0.0, tangDist = 0.0;
895  mpBasicGeometry->computeTangentialSignDist(tangDist, pe, arcPos);
896  oMinDistArcPos.push_back(arcPos);
897 
898  oIntersectedEdgeInd.push_back(edgeIndex);
899  }
900  } else {
901  FloatArray ps(xS);
902  FloatArray pe(xE);
903 
904  int nDim = std :: min( ps.giveSize(), pe.giveSize() );
905  FloatArray p;
906  p.resize(nDim);
907 
908  for ( int i = 1; i <= nDim; i++ ) {
909  ( p.at(i) ) = 0.5 * ( 1.0 - xi ) * ( ( ps.at(i) ) ) + 0.5 * ( 1.0 + xi ) * ( ( pe.at(i) ) );
910  }
911 
912 
913  // Check that the intersection point has not already been identified.
914  // This may happen if the crack intersects the element exactly at a node,
915  // so that intersection is detected for both element edges in that node.
916 
917  bool alreadyFound = false;
918 
919 
920  int numPointsOld = oIntersectionPoints.size();
921  for ( int k = 1; k <= numPointsOld; k++ ) {
922  double dist = p.distance(oIntersectionPoints [ k - 1 ]);
923 
924  if ( dist < mLevelSetTol ) {
925  alreadyFound = true;
926  break;
927  }
928  }
929 
930  if ( !alreadyFound ) {
931  oIntersectionPoints.push_back(p);
932 
933  double arcPos = 0.0, tangDist = 0.0;
934  p.resizeWithValues(2);
935  mpBasicGeometry->computeTangentialSignDist(tangDist, p, arcPos);
936  oMinDistArcPos.push_back(arcPos);
937 
938  oIntersectedEdgeInd.push_back(edgeIndex);
939  }
940  }
941  }
942  }
943  }
944 }
945 
947 {
948  // For debugging only
949  int tStepInd = 0;
950  TimeStep *tStep = domain->giveEngngModel()->giveCurrentStep(false);
951  if(tStep != NULL) {
952  tStepInd = tStep->giveNumber();
953  }
954  this->mpBasicGeometry->printVTK(tStepInd, number);
955 }
956 
957 void GeometryBasedEI :: giveSubPolygon(std :: vector< FloatArray > &oPoints, const double &iXiStart, const double &iXiEnd) const
958 {
959  mpBasicGeometry->giveSubPolygon(oPoints, iXiStart, iXiEnd);
960 }
961 
962 void GeometryBasedEI :: propagateFronts(bool &oFrontsHavePropagated)
963 {
964  oFrontsHavePropagated = false;
965 
966  TipPropagation tipPropStart;
968  // mpEnrichmentDomain->propagateTip(tipPropStart);
969  // TODO: Generalize
970  // Propagate start point
971  FloatArray pos( mpBasicGeometry->giveVertex(1) );
972  pos.add(tipPropStart.mPropagationLength, tipPropStart.mPropagationDir);
973  mpBasicGeometry->insertVertexFront(pos);
974 
975  oFrontsHavePropagated = true;
976  }
977 
978  TipPropagation tipPropEnd;
980  // mpEnrichmentDomain->propagateTip(tipPropEnd);
981  // TODO: Generalize
982  // Propagate end point
983  FloatArray pos( mpBasicGeometry->giveVertex( mpBasicGeometry->giveNrVertices() ) );
984  pos.add(tipPropEnd.mPropagationLength, tipPropEnd.mPropagationDir);
985  mpBasicGeometry->insertVertexBack(pos);
986 
987  oFrontsHavePropagated = true;
988  }
989 
990 #if 0
991  // For debugging only
992  if ( mpEnrichmentDomain->getVtkDebug() ) {
993  int tStepInd = this->domain->giveEngngModel()->giveCurrentStep()->giveNumber();
994 
995  EnrichmentDomain_BG *enrDomBG = dynamic_cast< EnrichmentDomain_BG * >( mpEnrichmentDomain );
996 
997  if ( enrDomBG != NULL ) {
998  PolygonLine *pl = dynamic_cast< PolygonLine * >( enrDomBG->bg );
999  if ( pl != NULL ) {
1000  pl->printVTK(tStepInd, number);
1001  }
1002  }
1003  }
1004 #endif
1005  updateGeometry();
1006 
1007 // if( domain->giveEngngModel()->giveProblemScale() == macroScale ) {
1008 // writeVtkDebug();
1009 // }
1010 }
1011 
1012 bool GeometryBasedEI :: giveElementTipCoord(FloatArray &oCoord, double &oArcPos, Element &iEl, const FloatArray &iElCenter) const
1013 {
1014  TipInfo tipInfoStart, tipInfoEnd;
1015  mpBasicGeometry->giveTips(tipInfoStart, tipInfoEnd);
1016 
1017 
1018  std :: vector< TipInfo >tipInfos = {
1019  tipInfoStart, tipInfoEnd
1020  };
1021 
1022  double minDist2 = std :: numeric_limits< double > :: max();
1023  size_t minIndex = 0;
1024  bool foundTip = false;
1025 
1026  for ( size_t i = 0; i < tipInfos.size(); i++ ) {
1027  if ( tipInfos [ i ].mGlobalCoord.distance_square(iElCenter) < minDist2 ) {
1028  minDist2 = tipInfos [ i ].mGlobalCoord.distance_square(iElCenter);
1029  minIndex = i;
1030  foundTip = true;
1031  }
1032  }
1033 
1034  if ( !foundTip ) {
1035  return false;
1036  } else {
1037  // Check if the tip point is inside the element
1038  const FloatArray &globCoord = tipInfos [ minIndex ].mGlobalCoord;
1039  FloatArray locCoord;
1040  if ( !iEl.computeLocalCoordinates(locCoord, globCoord) ) {
1041  return false;
1042  }
1043 
1044  oCoord = tipInfos [ minIndex ].mGlobalCoord;
1045  oArcPos = tipInfos [ minIndex ].mArcPos;
1046  return true;
1047  }
1048 }
1049 
1050 void GeometryBasedEI :: giveBoundingSphere(FloatArray &oCenter, double &oRadius)
1051 {
1052  // Compute bounding sphere from enrichment domain ...
1053  mpBasicGeometry->giveBoundingSphere(oCenter, oRadius);
1054 
1055  // ... increase the radius to cover the support of
1056  // the enrichment front ...
1058 
1059 
1060  if ( domain->giveNumberOfSpatialDimensions() == 2 ) {
1061  // Compute mean area if applicable
1062  double meanArea = domain->giveArea() / domain->giveNumberOfElements();
1063  double meanLength = sqrt(meanArea);
1064  //printf("meanLength: %e\n", meanLength );
1065 
1066  oRadius = max(oRadius, meanLength);
1067  }
1068 
1069  // ... and make sure that all nodes of partly cut elements are included.
1070  oRadius *= 2.0; // TODO: Compute a better estimate based on maximum element size. /ES
1071 }
1072 } /* namespace oofem */
The base class for all spatial localizers.
void setField(int item, InputFieldType id)
void evaluateEnrFuncJumps(std::vector< double > &oEnrFuncJumps, int iNodeInd, GaussPoint &iGP, bool iGPLivesOnCurrentCrack) const
int number
Component number.
Definition: femcmpnn.h:80
const FloatArray & giveVertex(int n) const
Definition: geometry.h:124
virtual int giveDofPoolSize() const
bool isElementEnriched(const Element *element) const
virtual void evaluateEnrFuncJumps(std::vector< double > &oEnrFuncJumps, GaussPoint &iGP, int iNodeInd, bool iGPLivesOnCurrentCrack, const double &iNormalSignDist) const =0
Abstract class representing entity, which is included in the FE model using one (or more) global func...
std::unique_ptr< BasicGeometry > mpBasicGeometry
#define _IFT_EnrichmentItem_front
virtual void evalN(FloatArray &answer, const FloatArray &lcoords, const FEICellGeometry &cellgeo)=0
Evaluates the array of interpolation functions (shape functions) at given point.
BasicGeometry * createGeometry(const char *name)
Definition: classfactory.C:341
virtual IRResultType initializeFrom(InputRecord *ir)=0
Class and object Domain.
Definition: domain.h:115
void giveSubPolygon(std::vector< FloatArray > &oPoints, const double &iXiStart, const double &iXiEnd) const
virtual void giveBoundingSphere(FloatArray &oCenter, double &oRadius)
std::unordered_map< int, NodeEnrichmentType > mNodeEnrMarkerMap
FloatArray mPropagationDir
Definition: tipinfo.h:44
Class representing the implementation of a dynamic data reader for in-code use.
int giveGlobalNumber() const
Definition: dofmanager.h:501
Domain * domain
Link to domain object, useful for communicating with other FEM components.
Definition: femcmpnn.h:82
const double mLevelSetTol2
#define _IFT_EnrichmentItem_inheritbc
double & at(int i)
Coefficient access function.
Definition: floatarray.h:131
int max(int i, int j)
Returns bigger value form two given decimals.
Definition: mathfem.h:71
virtual void updateNodeEnrMarker(XfemManager &ixFemMan)
double sgn(double i)
Returns the signum of given value (if value is < 0 returns -1, otherwise returns 1) ...
Definition: mathfem.h:91
TipInfo gathers useful information about a crack tip, like its position and tangent direction...
Definition: tipinfo.h:24
virtual void evaluateEnrFuncDerivAt(std::vector< FloatArray > &oEnrFuncDeriv, const EfInput &iEfInput, const FloatArray &iGradLevelSet) const =0
virtual void evaluateEnrFuncInNode(std::vector< double > &oEnrFunc, const Node &iNode) const
int mPropLawIndex
mPropLawIndex: nonzero if a propagation law is present, zero otherwise.
virtual void giveAllElementsWithNodesWithinBox(elementContainerType &elemSet, const FloatArray &coords, const double radius)
Returns container (set) of all domain elements having node within given box.
virtual FloatArray * giveCoordinates()
Definition: dofmanager.h:382
EngngModel * giveEngngModel()
Returns engineering model to which receiver is associated.
Definition: domain.C:433
Abstract base class for all finite elements.
Definition: element.h:145
virtual int instanciateYourself(DataReader &dr)
virtual void evaluateEnrFuncAt(std::vector< double > &oEnrFunc, const EfInput &iEfInput) const =0
static const double mLevelSetRelTol
virtual void evaluateEnrFuncDerivAt(FloatArray &oEnrFuncDeriv, const FloatArray &iPos, const double &iLevelSet, const FloatArray &iGradLevelSet) const =0
virtual void evaluateEnrFuncAt(std::vector< double > &oEnrFunc, const FloatArray &iGlobalCoord, const FloatArray &iLocalCoord, int iNodeInd, const Element &iEl) const
Class representing the abstraction for input data source.
Definition: datareader.h:50
int giveNumberOfElements() const
Returns number of elements in domain.
Definition: domain.h:434
EnrichmentFunction * createEnrichmentFunction(const char *name, int num, Domain *domain)
Definition: classfactory.C:301
Dummy propagation law that does nothing.
int giveNumberOfSpatialDimensions()
Returns number of spatial dimensions.
Definition: domain.C:1067
EnrichmentFront * createEnrichmentFront(const char *name)
Definition: classfactory.C:321
virtual void giveInputRecord(DynamicInputRecord &input)
Setups the input record string of receiver.
Definition: femcmpnn.C:77
Class implementing an array of integers.
Definition: intarray.h:61
int & at(int i)
Coefficient access function.
Definition: intarray.h:103
virtual void report_error(const char *_class, const char *proc, InputFieldType id, IRResultType result, const char *file, int line)=0
Prints the error message.
XfemManager * giveXfemManager()
Definition: domain.C:375
virtual void createEnrichedDofs()
virtual FEInterpolation * giveInterpolation() const
Definition: element.h:629
virtual void evalGradLevelSetNormal(FloatArray &oGradLevelSet, const FloatArray &iGlobalCoord, const FloatMatrix &idNdX, const IntArray &iNodeInd) const =0
Evaluate the gradient of the normal direction level set in the point iGlobalCoord.
#define min
virtual void propagateFronts(bool &oFrontsHavePropagated)
virtual int giveNumberOfNodes() const
Returns number of nodes of receiver.
Definition: element.h:662
double distance(const FloatArray &x) const
Computes the distance between position represented by receiver and position given as parameter...
Definition: floatarray.C:489
Class representing a general abstraction for finite element interpolation class.
Definition: feinterpol.h:132
GeometryBasedEI(int n, XfemManager *xm, Domain *aDomain)
std::unordered_map< int, double > mLevelSetTangDirMap
#define max
const IntArray & giveDofManArray() const
Definition: element.h:592
virtual void giveAllNodesWithinBox(nodeContainerType &nodeList, const FloatArray &coords, const double radius)=0
Returns container (list) of all domain nodes within given box.
int giveNumber()
Returns receiver&#39;s number.
Definition: timestep.h:129
virtual void printVTK(int iTStepIndex, int iLineIndex)
Definition: geometry.C:1661
Element * giveElement(int n)
Service for accessing particular domain fe element.
Definition: domain.C:160
virtual IRResultType giveRecordKeywordField(std::string &answer, int &value)=0
Reads the record id field (type of record) and its corresponding number.
bool mInheritBoundaryConditions
If newly created enriched dofs should inherit boundary conditions from the node they are introduced i...
#define OOFEM_ERROR(...)
Definition: error.h:61
virtual void MarkNodesAsFront(std::unordered_map< int, NodeEnrichmentType > &ioNodeEnrMarkerMap, XfemManager &ixFemMan, const std::unordered_map< int, double > &iLevelSetNormalDirMap, const std::unordered_map< int, double > &iLevelSetTangDirMap, const TipInfo &iTipInfo)=0
MarkNodesAsFront: Intput: -ioNodeEnrMarker: A vector with the same size as the number of nodes in the...
#define _IFT_EnrichmentItem_propagationlaw
virtual bool propagateInterface(Domain &iDomain, EnrichmentFront &iEnrFront, TipPropagation &oTipProp)=0
virtual void computeIntersectionPoints(std::vector< FloatArray > &oIntersectionPoints, std::vector< int > &oIntersectedEdgeInd, Element *element, std::vector< double > &oMinDistArcPos) const
SpatialLocalizer * giveSpatialLocalizer()
Returns receiver&#39;s associated spatial localizer.
Definition: domain.C:1184
virtual const char * giveClassName() const
bool evalLevelSetNormalInNode(double &oLevelSet, int iNodeInd, const FloatArray &iGlobalCoord) const
virtual double giveSupportRadius() const =0
Wrapper around element definition to provide FEICellGeometry interface.
Definition: feinterpol.h:95
std::unordered_map< int, double > mLevelSetNormalDirMap
virtual void giveInputRecord(DynamicInputRecord &input)
Setups the input record string of receiver.
#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
virtual void giveJump(std::vector< double > &oJumps) const =0
Returns the discontinuous jump in the enrichment function when the lvel set function changes sign...
double distance_square(const FloatArray &iP1, const FloatArray &iP2, double &oXi, double &oXiUnbounded) const
Definition: floatarray.C:499
virtual Element * giveElementContainingPoint(const FloatArray &coords, const IntArray *regionList=NULL)=0
Returns the element, containing given point and belonging to one of the region in region list...
virtual bool giveElementTipCoord(FloatArray &oCoord, double &oArcPos, Element &iEl, const FloatArray &iElCenter) const
double giveArea()
Gives the sum of the area of all elements.
Definition: domain.C:1378
virtual void giveInputRecord(DynamicInputRecord &input)=0
const FloatArray & giveGlobalCoordinates()
Definition: gausspoint.h:160
virtual InputRecord * giveInputRecord(InputRecordType irType, int recordId)=0
Returns input record corresponding to given InputRecordType value and its record_id.
virtual void evaluateEnrFuncAt(double &oEnrFunc, const FloatArray &iPos, const double &iLevelSet) const =0
virtual void writeVtkDebug() const
virtual IRResultType initializeFrom(InputRecord *ir)=0
virtual IRResultType initializeFrom(InputRecord *ir)
Initializes receiver according to object description stored in input record.
virtual void boundaryGiveNodes(IntArray &answer, int boundary)=0
Gives the boundary nodes for requested boundary number.
int giveNextFreeDofID(int increment=1)
Gives the next free dof ID.
Definition: domain.C:1411
bool evalLevelSetTangInNode(double &oLevelSet, int iNodeInd, const FloatArray &iGlobalCoord) const
Class representing vector of real numbers.
Definition: floatarray.h:82
Implementation of matrix containing floating point numbers.
Definition: floatmatrix.h:94
PropagationLaw * mpPropagationLaw
This class manages the xfem part.
Definition: xfemmanager.h:109
IRResultType
Type defining the return values of InputRecord reading operations.
Definition: irresulttype.h:47
EnrichmentFront * mpEnrichmentFrontStart
const FloatArray & giveNodeCoordinates() const
As giveCoordinates, but non-virtual and therefore faster (because it can be inlined).
Definition: node.h:120
EnrichmentFunction * mpEnrichmentFunc
Class representing the general Input Record.
Definition: inputrecord.h:101
void zero()
Zeroes all coefficients of receiver.
Definition: floatarray.C:658
EnrichmentFront * mpEnrichmentFrontEnd
int mEnrFrontIndex
mEnrFrontIndex: nonzero if an enrichment front is present, zero otherwise.
Class representing the a dynamic Input Record.
ClassFactory & classFactory
Definition: classfactory.C:59
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 FloatArray * giveCoordinates()
Definition: node.h:114
Domain * giveDomain() const
Definition: femcmpnn.h:100
virtual void evaluateEnrFuncDerivAt(std::vector< FloatArray > &oEnrFuncDeriv, const FloatArray &iGlobalCoord, const FloatArray &iLocalCoord, int iNodeInd, const Element &iEl) const
static double calcXiZeroLevel(const double &iQ1, const double &iQ2)
virtual void updateDofIdPool()
double mPropagationLength
Definition: tipinfo.h:45
virtual void giveInputRecord(DynamicInputRecord &input)=0
virtual void updateGeometry()
virtual TimeStep * giveCurrentStep(bool force=false)
Returns current time step.
Definition: engngm.h:683
#define _IFT_EnrichmentItem_inheritorderedbc
int giveSize() const
Returns the size of receiver.
Definition: floatarray.h:218
PropagationLaw * createPropagationLaw(const char *name)
Definition: classfactory.C:331
virtual double giveCoordinate(int i)
Definition: dofmanager.h:380
Node * giveNode(int n)
Service for accessing particular domain node.
Definition: domain.h:371
the oofem namespace is to define a context or scope in which all oofem names are defined.
void updateLevelSets(XfemManager &ixFemMan)
DofManager * giveDofManager(int i) const
Definition: element.C:514
static const double mLevelSetTol
Domain * giveDomain()
Definition: xfemmanager.h:202
Class implementing node in finite element mesh.
Definition: node.h:87
int giveNumber() const
Definition: femcmpnn.h:107
Node * giveNode(int i) const
Returns reference to the i-th node of element.
Definition: element.h:610
Class representing integration point in finite element program.
Definition: gausspoint.h:93
void insertInputRecord(InputRecordType type, InputRecord *record)
Main purpose of this class it the possibility to add new input records in code.
virtual void evalLevelSetNormal(double &oLevelSet, const FloatArray &iGlobalCoord, const FloatArray &iN, const IntArray &iNodeInd) const =0
Evaluate the normal direction level set in the point iGlobalCoord.
Class representing solution step.
Definition: timestep.h:80
virtual void appendInputRecords(DynamicDataReader &oDR)
void add(const FloatArray &src)
Adds array src to receiver.
Definition: floatarray.C:156
virtual double evaldNdx(FloatMatrix &answer, const FloatArray &lcoords, const FEICellGeometry &cellgeo)=0
Evaluates the matrix of derivatives of interpolation functions (shape functions) at given point...
const FloatArray & giveNaturalCoordinates()
Returns coordinate array of receiver.
Definition: gausspoint.h:138
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:28 for OOFEM by doxygen 1.8.11 written by Dimitri van Heesch, © 1997-2011