69GeometryBasedEI :: ~GeometryBasedEI()
72int GeometryBasedEI :: instanciateYourself(
DataReader &dr)
85 OOFEM_ERROR(
"failed to create enrichment function (%s)", name.c_str() );
96 OOFEM_ERROR(
"unknown geometry domain (%s)", name.c_str() );
108 std::string enrFrontName;
109 efIr.giveRecordKeywordField(enrFrontName);
110 auto ef =
classFactory.createEnrichmentFront( enrFrontName.c_str() );
112 assert(i==0 || i==1);
113 ef->initializeFrom(efIr);
116 OOFEM_ERROR(
"Failed to create enrichment front (%s)", enrFrontName.c_str() );
127 std :: string propLawName;
136 OOFEM_ERROR(
"Failed to create propagation law (%s)", propLawName.c_str() );
155void GeometryBasedEI :: postInitialize()
161void GeometryBasedEI :: updateDofIdPool()
178 auto eiRec = std::make_unique<DynamicInputRecord>();
180 FEMComponent :: giveInputRecord(* eiRec);
195 auto efRec = std::unique_ptr<DynamicInputRecord>();
200 auto geoRec = std::unique_ptr<DynamicInputRecord>();
207 auto efrRecStart = std::unique_ptr<DynamicInputRecord>();
211 auto efrRecEnd = std::unique_ptr<DynamicInputRecord>();
218 auto plRec = std::unique_ptr<DynamicInputRecord>();
224void GeometryBasedEI :: updateGeometry()
242 TipInfo tipInfoStart, tipInfoEnd;
255 for (
int elNum: elList ) {
259 double minSignPhi = 1, maxSignPhi = -1;
260 double minPhi = std :: numeric_limits< double > :: max();
261 double maxPhi = std :: numeric_limits< double > :: min();
266 for (
int elNodeInd = 1; elNodeInd <= nElNodes; elNodeInd++ ) {
269 double levelSetNormalNode = 0.0;
271 minSignPhi = std :: min(
sgn(minSignPhi),
sgn(levelSetNormalNode) );
272 maxSignPhi = std :: max(
sgn(maxSignPhi),
sgn(levelSetNormalNode) );
274 minPhi = std :: min(minPhi, levelSetNormalNode);
275 maxPhi = std :: max(maxPhi, levelSetNormalNode);
283 int numEdgeIntersec = 0;
290 for (
int edgeIndex = 1; edgeIndex <= numEdges; edgeIndex++ ) {
293 int niLoc = bNodes.
at(1);
296 int njLoc = bNodes.
at(2);
300 double levelSetNormalNodeI = 0.0;
301 double levelSetNormalNodeJ = 0.0;
303 if ( levelSetNormalNodeI * levelSetNormalNodeJ <
mLevelSetTol ) {
308 double tangDist = 0.0, arcPos = 0.0;
312 pos.
add(0.5 * ( 1.0 - xi ), posI);
313 pos.
add(0.5 * ( 1.0 + xi ), posJ);
318 double gamma = tangDist;
328 if ( numEdgeIntersec >= 1 ) {
330 for (
int elNodeInd = 1; elNodeInd <= nElNodes; elNodeInd++ ) {
362 std :: list< int >nodeList;
365 for (
int nodeNum: nodeList ) {
378 double gamma = 0.0, arcPos = -1.0;
386void GeometryBasedEI :: evaluateEnrFuncInNode(std :: vector< double > &oEnrFunc,
const Node &iNode)
const
388 double levelSetGP = 0.0;
396 double tangDist = 0.0, minDistArcPos = 0.0;
397 mpBasicGeometry->computeTangentialSignDist(tangDist, globalCoord, minDistArcPos);
405 const EfInput efInput(globalCoord, levelSetGP, nodeInd, edGlobalCoord, minDistArcPos, localTangDir);
408 if ( nodeInd == -1 ) {
410 oEnrFunc.resize(1, 0.0);
411 mpEnrichmentFunc->evaluateEnrFuncAt(oEnrFunc [ 0 ], globalCoord, levelSetGP);
415 switch ( res->second ) {
420 oEnrFunc.resize(1, 0.0);
421 mpEnrichmentFunc->evaluateEnrFuncAt(oEnrFunc [ 0 ], globalCoord, levelSetGP);
435 printf(
"In EnrichmentItem :: evaluateEnrFuncAt: mNodeEnrMarkerMap not found for iNodeInd %d\n", nodeInd);
440void GeometryBasedEI :: evaluateEnrFuncAt(std :: vector< double > &oEnrFunc,
const FloatArray &iGlobalCoord,
const FloatArray &iLocalCoord,
int iNodeInd,
const Element &iEl)
const
450 double levelSetGP = 0.0;
456 double tangDist = 0.0, minDistArcPos = 0.0;
458 iGlobalCoord [ 0 ], iGlobalCoord [ 1 ]
460 mpBasicGeometry->computeTangentialSignDist(tangDist, globalCoord, minDistArcPos);
468 const EfInput efInput(iGlobalCoord, levelSetGP, iNodeInd, edGlobalCoord, minDistArcPos, localTangDir);
471 if ( iNodeInd == -1 ) {
473 oEnrFunc.resize(1, 0.0);
474 mpEnrichmentFunc->evaluateEnrFuncAt(oEnrFunc [ 0 ], iGlobalCoord, levelSetGP);
478 switch ( res->second ) {
483 oEnrFunc.resize(1, 0.0);
484 mpEnrichmentFunc->evaluateEnrFuncAt(oEnrFunc [ 0 ], iGlobalCoord, levelSetGP);
498 printf(
"In EnrichmentItem :: evaluateEnrFuncAt: mNodeEnrMarkerMap not found for iNodeInd %d\n", iNodeInd);
503void GeometryBasedEI :: evaluateEnrFuncDerivAt(std :: vector< FloatArray > &oEnrFuncDeriv,
const FloatArray &iGlobalCoord,
const FloatArray &iLocalCoord,
int iNodeInd,
const Element &iEl)
const
509 interp->
evaldNdx(dNdx, iLocalCoord, geomWrapper);
510 interp->
evalN(
N, iLocalCoord, geomWrapper);
519 double levelSetGP = 0.0;
526 double tangDist = 0.0, minDistArcPos = 0.0;
527 mpBasicGeometry->computeTangentialSignDist(tangDist, iGlobalCoord, minDistArcPos);
535 const EfInput efInput(iGlobalCoord, levelSetGP, iNodeInd, edGlobalCoord, minDistArcPos, localTangDir);
537 switch ( res->second ) {
541 oEnrFuncDeriv.resize(1);
542 mpEnrichmentFunc->evaluateEnrFuncDerivAt(oEnrFuncDeriv [ 0 ], iGlobalCoord, levelSetGP, gradLevelSetGP);
556 printf(
"In EnrichmentItem :: evaluateEnrFuncDerivAt: mNodeEnrMarkerMap not found for iNodeInd %d\n", iNodeInd);
560void GeometryBasedEI :: evaluateEnrFuncJumps(std :: vector< double > &oEnrFuncJumps,
int iNodeInd,
GaussPoint &iGP,
bool iGPLivesOnCurrentCrack)
const
562 double normalSignDist = 0.0;
580 switch ( res->second ) {
584 oEnrFuncJumps.resize(1);
588 mpEnrichmentFrontStart->evaluateEnrFuncJumps(oEnrFuncJumps, iGP, iNodeInd, iGPLivesOnCurrentCrack, normalSignDist);
591 mpEnrichmentFrontEnd->evaluateEnrFuncJumps(oEnrFuncJumps, iGP, iNodeInd, iGPLivesOnCurrentCrack, normalSignDist);
594 mpEnrichmentFrontStart->evaluateEnrFuncJumps(oEnrFuncJumps, iGP, iNodeInd, iGPLivesOnCurrentCrack, normalSignDist);
595 mpEnrichmentFrontEnd->evaluateEnrFuncJumps(oEnrFuncJumps, iGP, iNodeInd, iGPLivesOnCurrentCrack, normalSignDist);
599 printf(
"In EnrichmentItem :: evaluateEnrFuncDerivAt: evaluateEnrFuncJumps not found for iNodeInd %d\n", iNodeInd);
603void GeometryBasedEI :: computeIntersectionPoints(std :: vector< FloatArray > &oIntersectionPoints, std :: vector< int > &oIntersectedEdgeInd,
Element *element, std :: vector< double > &oMinDistArcPos)
const
615 for (
int edgeIndex = 1; edgeIndex <= numEdges; edgeIndex++ ) {
618 int nsLoc = bNodes.
at(1);
620 int neLoc = bNodes.at(2);
632 const double gammaRelTol = 1.0e-2;
641 double tangDist = 0.0, arcPos = 0.0;
645 pos.
add(0.5 * ( 1.0 - xi ), posI);
646 pos.
add(0.5 * ( 1.0 + xi ), posJ);
649 double gamma = tangDist;
653 if ( gamma > -gammaRelTol * sqrt(edgeLength2) ) {
666 bool alreadyFound =
false;
668 int numPointsOld = oIntersectionPoints.size();
669 for (
int k = 1; k <= numPointsOld; k++ ) {
670 double dist =
distance(ps, oIntersectionPoints [ k - 1 ]);
678 if ( !alreadyFound ) {
679 oIntersectionPoints.push_back(ps);
681 double arcPos = 0.0, tangDist = 0.0;
683 oMinDistArcPos.push_back(arcPos);
685 oIntersectedEdgeInd.push_back(edgeIndex);
688 alreadyFound =
false;
690 numPointsOld = oIntersectionPoints.size();
691 for (
int k = 1; k <= numPointsOld; k++ ) {
692 double dist =
distance(pe, oIntersectionPoints [ k - 1 ]);
700 if ( !alreadyFound ) {
701 oIntersectionPoints.push_back(pe);
703 double arcPos = 0.0, tangDist = 0.0;
705 oMinDistArcPos.push_back(arcPos);
707 oIntersectedEdgeInd.push_back(edgeIndex);
715 for (
int i = 1; i <= 2; i++ ) {
716 ( p.
at(i) ) = 0.5 * ( 1.0 - xi ) * ( ( ps.at(i) ) ) + 0.5 * ( 1.0 + xi ) * ( ( pe.at(i) ) );
724 bool alreadyFound =
false;
727 int numPointsOld = oIntersectionPoints.size();
728 for (
int k = 1; k <= numPointsOld; k++ ) {
729 double dist =
distance(p, oIntersectionPoints [ k - 1 ]);
737 if ( !alreadyFound ) {
738 oIntersectionPoints.push_back(p);
740 double arcPos = 0.0, tangDist = 0.0;
742 oMinDistArcPos.push_back(arcPos);
744 oIntersectedEdgeInd.push_back(edgeIndex);
753void GeometryBasedEI :: computeIntersectionPoints(std :: vector< FloatArray > &oIntersectionPoints, std :: vector< int > &oIntersectedEdgeInd,
Element *element,
const Triangle &iTri, std :: vector< double > &oMinDistArcPos)
const
760 const int numEdges = 3;
762 for (
int edgeIndex = 1; edgeIndex <= numEdges; edgeIndex++ ) {
766 switch ( edgeIndex ) {
798 double phiS = 0.0, phiE = 0.0;
799 double gammaS = 0.0, gammaE = 0.0;
801 bool levelSetDefinedInAllNodes =
true;
802 for (
int i = 1; i <= Ns.
giveSize(); i++ ) {
803 double phiSNode = 0.0;
805 phiS += Ns.
at(i) * phiSNode;
807 levelSetDefinedInAllNodes =
false;
810 double gammaSNode = 0.0;
812 gammaS += Ns.
at(i) * gammaSNode;
814 levelSetDefinedInAllNodes =
false;
817 double phiENode = 0.0;
819 phiE += Ne.
at(i) * phiENode;
821 levelSetDefinedInAllNodes =
false;
824 double gammaENode = 0.0;
826 gammaE += Ne.
at(i) * gammaENode;
828 levelSetDefinedInAllNodes =
false;
832 if ( phiS * phiE <
mLevelSetTol2 && levelSetDefinedInAllNodes ) {
836 double gamma = 0.5 * ( 1.0 - xi ) * gammaS + 0.5 * ( 1.0 + xi ) * gammaE;
852 bool alreadyFound =
false;
854 int numPointsOld = oIntersectionPoints.size();
855 for (
int k = 1; k <= numPointsOld; k++ ) {
856 double dist =
distance(ps, oIntersectionPoints [ k - 1 ]);
864 if ( !alreadyFound ) {
865 oIntersectionPoints.push_back(ps);
867 double arcPos = 0.0, tangDist = 0.0;
869 oMinDistArcPos.push_back(arcPos);
871 oIntersectedEdgeInd.push_back(edgeIndex);
874 alreadyFound =
false;
876 numPointsOld = oIntersectionPoints.size();
877 for (
int k = 1; k <= numPointsOld; k++ ) {
878 double dist =
distance(pe, oIntersectionPoints [ k - 1 ]);
886 if ( !alreadyFound ) {
887 oIntersectionPoints.push_back(pe);
889 double arcPos = 0.0, tangDist = 0.0;
891 oMinDistArcPos.push_back(arcPos);
893 oIntersectedEdgeInd.push_back(edgeIndex);
903 for (
int i = 1; i <= nDim; i++ ) {
904 ( p.
at(i) ) = 0.5 * ( 1.0 - xi ) * ( ( ps.
at(i) ) ) + 0.5 * ( 1.0 + xi ) * ( ( pe.
at(i) ) );
912 bool alreadyFound =
false;
915 int numPointsOld = oIntersectionPoints.size();
916 for (
int k = 1; k <= numPointsOld; k++ ) {
917 double dist =
distance(p, oIntersectionPoints [ k - 1 ]);
925 if ( !alreadyFound ) {
926 oIntersectionPoints.push_back(p);
928 double arcPos = 0.0, tangDist = 0.0;
931 oMinDistArcPos.push_back(arcPos);
933 oIntersectedEdgeInd.push_back(edgeIndex);
941void GeometryBasedEI :: writeVtkDebug()
const
945 TimeStep *tStep =
domain->giveEngngModel()->giveCurrentStep(
false);
952void GeometryBasedEI :: giveSubPolygon(std :: vector< FloatArray > &oPoints,
const double &iXiStart,
const double &iXiEnd)
const
957void GeometryBasedEI :: propagateFronts(
bool &oFrontsHavePropagated)
959 oFrontsHavePropagated =
false;
970 oFrontsHavePropagated =
true;
982 oFrontsHavePropagated =
true;
987 if ( mpEnrichmentDomain->getVtkDebug() ) {
988 int tStepInd = this->
domain->giveEngngModel()->giveCurrentStep()->giveNumber();
990 EnrichmentDomain_BG *enrDomBG =
dynamic_cast< EnrichmentDomain_BG *
>( mpEnrichmentDomain );
992 if ( enrDomBG != NULL ) {
1009 TipInfo tipInfoStart, tipInfoEnd;
1013 std :: vector< TipInfo >tipInfos = {
1014 tipInfoStart, tipInfoEnd
1017 double minDist2 = std :: numeric_limits< double > :: max();
1018 size_t minIndex = 0;
1019 bool foundTip =
false;
1021 for (
size_t i = 0; i < tipInfos.size(); i++ ) {
1023 if ( d2 < minDist2 ) {
1034 const FloatArray &globCoord = tipInfos [ minIndex ].mGlobalCoord;
1040 oCoord = tipInfos [ minIndex ].mGlobalCoord;
1041 oArcPos = tipInfos [ minIndex ].mArcPos;
1046void GeometryBasedEI :: giveBoundingSphere(
FloatArray &oCenter,
double &oRadius)
1056 if (
domain->giveNumberOfSpatialDimensions() == 2 ) {
1058 double meanArea =
domain->giveArea() /
domain->giveNumberOfElements();
1059 double meanLength = sqrt(meanArea);
1062 oRadius =
max(oRadius, meanLength);
const FloatArray & giveVertex(int n) const
GroupRecords giveGroupRecords(const std::shared_ptr< InputRecord > &ir, InputFieldType ift, const std::string &name, InputRecordType irType, bool optional)
static constexpr const char * InputRecordTags[]
InputRecord * giveChildRecord(const std::shared_ptr< InputRecord > &ir, InputFieldType ift, const std::string &name, InputRecordType irType, bool optional)
Return pointer to subrecord of given type (must be exactly one); if not present, returns nullptr.
int giveGlobalNumber() const
double giveCoordinate(int i) const
const FloatArray & giveCoordinates() const
void insertInputRecord(InputRecordType type, std::unique_ptr< InputRecord > record)
Node * giveNode(int i) const
virtual FEInterpolation * giveInterpolation() const
virtual int giveNumberOfNodes() const
const IntArray & giveDofManArray() const
DofManager * giveDofManager(int i) const
virtual bool computeLocalCoordinates(FloatArray &answer, const FloatArray &gcoords)
virtual Element_Geometry_Type giveGeometryType() const =0
bool mLevelSetsNeedUpdate
static const double mLevelSetRelTol
static const double mLevelSetTol
int mEnrFrontIndex
mEnrFrontIndex: nonzero if an enrichment front is present, zero otherwise.
virtual void evalLevelSetNormal(double &oLevelSet, const FloatArray &iGlobalCoord, const FloatArray &iN, const IntArray &iNodeInd) const =0
std::unique_ptr< EnrichmentFront > mpEnrichmentFrontEnd
std ::unordered_map< int, NodeEnrichmentType > mNodeEnrMarkerMap
bool evalLevelSetTangInNode(double &oLevelSet, int iNodeInd, const FloatArray &iGlobalCoord) const
std::unique_ptr< EnrichmentFront > mpEnrichmentFrontStart
virtual int giveDofPoolSize() const
std::unique_ptr< EnrichmentFunction > mpEnrichmentFunc
int mPropLawIndex
mPropLawIndex: nonzero if a propagation law is present, zero otherwise.
std::shared_ptr< InputRecord > thisIr
std ::unordered_map< int, double > mLevelSetTangDirMap
std ::unordered_map< int, double > mLevelSetNormalDirMap
virtual void evalGradLevelSetNormal(FloatArray &oGradLevelSet, const FloatArray &iGlobalCoord, const FloatMatrix &idNdX, const IntArray &iNodeInd) const =0
std::unique_ptr< PropagationLaw > mpPropagationLaw
bool isElementEnriched(const Element *element) const
static double calcXiZeroLevel(const double &iQ1, const double &iQ2)
EnrichmentItem(int n, XfemManager *xm, Domain *aDomain)
Constructor / destructor.
bool evalLevelSetNormalInNode(double &oLevelSet, int iNodeInd, const FloatArray &iGlobalCoord) const
virtual void createEnrichedDofs()
bool mInheritBoundaryConditions
const double mLevelSetTol2
bool mInheritOrderedBoundaryConditions
virtual IntArray boundaryGiveNodes(int boundary, const Element_Geometry_Type) const =0
virtual int giveNumberOfEdges(const Element_Geometry_Type) const
virtual void evalN(FloatArray &answer, const FloatArray &lcoords, const FEICellGeometry &cellgeo) const =0
virtual double evaldNdx(FloatMatrix &answer, const FloatArray &lcoords, const FEICellGeometry &cellgeo) const =0
Domain * giveDomain() const
Domain * domain
Link to domain object, useful for communicating with other FEM components.
int number
Component number.
Index giveSize() const
Returns the size of receiver.
void resizeWithValues(Index s, std::size_t allocChunk=0)
void zero()
Zeroes all coefficients of receiver.
void add(const FloatArray &src)
const FloatArray & giveGlobalCoordinates()
const FloatArray & giveNaturalCoordinates() const
Returns coordinate array of receiver.
void evaluateEnrFuncAt(std ::vector< double > &oEnrFunc, const FloatArray &iGlobalCoord, const FloatArray &iLocalCoord, int iNodeInd, const Element &iEl) const override
void updateGeometry() override
void giveBoundingSphere(FloatArray &oCenter, double &oRadius) override
std ::unique_ptr< BasicGeometry > mpBasicGeometry
void updateLevelSets(XfemManager &ixFemMan)
void updateNodeEnrMarker(XfemManager &ixFemMan) override
void evaluateEnrFuncDerivAt(std ::vector< FloatArray > &oEnrFuncDeriv, const FloatArray &iGlobalCoord, const FloatArray &iLocalCoord, int iNodeInd, const Element &iEl) const override
void printVTK(int iTStepIndex, int iLineIndex) override
virtual Element * giveElementContainingPoint(const FloatArray &coords, const IntArray *regionList=nullptr)=0
virtual void giveAllNodesWithinBox(nodeContainerType &nodeList, const FloatArray &coords, const double radius)=0
virtual void giveAllElementsWithNodesWithinBox(elementContainerType &elemSet, const FloatArray &coords, const double radius)
int giveNumber()
Returns receiver's number.
#define _IFT_EnrichmentItem_inheritorderedbc
#define _IFT_EnrichmentItem_front
#define _IFT_EnrichmentItem_inheritbc
#define _IFT_EnrichmentItem_propagationlaw
static FloatArray Vec2(const double &a, const double &b)
@ NodeEnr_START_AND_END_TIP
FloatArrayF< N > max(const FloatArrayF< N > &a, const FloatArrayF< N > &b)
double sgn(double i)
Returns the signum of given value (if value is < 0 returns -1, otherwise returns 1).
ClassFactory & classFactory
double distance(const FloatArray &x, const FloatArray &y)
double distance_square(const FloatArray &x, const FloatArray &y)
double mPropagationLength
FloatArray mPropagationDir