88 OOFEM_ERROR(
"failed to create enrichment function (%s)", name.c_str() );
97 OOFEM_ERROR(
"unknown geometry domain (%s)", name.c_str() );
107 std :: string enrFrontNameStart, enrFrontNameEnd;
116 OOFEM_ERROR(
"Failed to create enrichment front (%s)", enrFrontNameStart.c_str() );
126 OOFEM_ERROR(
"Failed to create enrichment front (%s)", enrFrontNameEnd.c_str() );
135 std :: string propLawName;
144 OOFEM_ERROR(
"Failed to create propagation law (%s)", propLawName.c_str() );
244 TipInfo tipInfoStart, tipInfoEnd;
257 for (
int elNum: elList ) {
261 double minSignPhi = 1, maxSignPhi = -1;
268 for (
int elNodeInd = 1; elNodeInd <= nElNodes; elNodeInd++ ) {
271 double levelSetNormalNode = 0.0;
276 minPhi =
std :: min(minPhi, levelSetNormalNode);
277 maxPhi =
std :: max(maxPhi, levelSetNormalNode);
285 int numEdgeIntersec = 0;
292 for (
int edgeIndex = 1; edgeIndex <= numEdges; edgeIndex++ ) {
296 int niLoc = bNodes.
at(1);
299 int njLoc = bNodes.
at(2);
303 double levelSetNormalNodeI = 0.0;
304 double levelSetNormalNodeJ = 0.0;
306 if ( levelSetNormalNodeI * levelSetNormalNodeJ <
mLevelSetTol ) {
311 double tangDist = 0.0, arcPos = 0.0;
315 pos.
add(0.5 * ( 1.0 - xi ), posI);
316 pos.
add(0.5 * ( 1.0 + xi ), posJ);
321 double gamma = tangDist;
331 if ( numEdgeIntersec >= 1 ) {
333 for (
int elNodeInd = 1; elNodeInd <= nElNodes; elNodeInd++ ) {
365 std :: list< int >nodeList;
368 for (
int nodeNum: nodeList ) {
381 double gamma = 0.0, arcPos = -1.0;
391 double levelSetGP = 0.0;
399 double tangDist = 0.0, minDistArcPos = 0.0;
400 mpBasicGeometry->computeTangentialSignDist(tangDist, globalCoord, minDistArcPos);
408 const EfInput efInput(globalCoord, levelSetGP, nodeInd, edGlobalCoord, minDistArcPos, localTangDir);
411 if ( nodeInd == -1 ) {
413 oEnrFunc.resize(1, 0.0);
418 switch ( res->second ) {
423 oEnrFunc.resize(1, 0.0);
438 printf(
"In EnrichmentItem :: evaluateEnrFuncAt: mNodeEnrMarkerMap not found for iNodeInd %d\n", nodeInd);
453 double levelSetGP = 0.0;
459 double tangDist = 0.0, minDistArcPos = 0.0;
461 iGlobalCoord [ 0 ], iGlobalCoord [ 1 ]
463 mpBasicGeometry->computeTangentialSignDist(tangDist, globalCoord, minDistArcPos);
471 const EfInput efInput(iGlobalCoord, levelSetGP, iNodeInd, edGlobalCoord, minDistArcPos, localTangDir);
474 if ( iNodeInd == -1 ) {
476 oEnrFunc.resize(1, 0.0);
481 switch ( res->second ) {
486 oEnrFunc.resize(1, 0.0);
501 printf(
"In EnrichmentItem :: evaluateEnrFuncAt: mNodeEnrMarkerMap not found for iNodeInd %d\n", iNodeInd);
512 interp->
evaldNdx(dNdx, iLocalCoord, geomWrapper);
513 interp->
evalN(N, iLocalCoord, geomWrapper);
522 double levelSetGP = 0.0;
529 double tangDist = 0.0, minDistArcPos = 0.0;
530 mpBasicGeometry->computeTangentialSignDist(tangDist, iGlobalCoord, minDistArcPos);
538 const EfInput efInput(iGlobalCoord, levelSetGP, iNodeInd, edGlobalCoord, minDistArcPos, localTangDir);
540 switch ( res->second ) {
544 oEnrFuncDeriv.resize(1);
559 printf(
"In EnrichmentItem :: evaluateEnrFuncDerivAt: mNodeEnrMarkerMap not found for iNodeInd %d\n", iNodeInd);
565 double normalSignDist = 0.0;
583 switch ( res->second ) {
587 oEnrFuncJumps.resize(1);
602 printf(
"In EnrichmentItem :: evaluateEnrFuncDerivAt: evaluateEnrFuncJumps not found for iNodeInd %d\n", iNodeInd);
618 for (
int edgeIndex = 1; edgeIndex <= numEdges; edgeIndex++ ) {
622 int nsLoc = bNodes.
at(1);
624 int neLoc = bNodes.
at(2);
636 const double gammaRelTol = 1.0e-2;
645 double tangDist = 0.0, arcPos = 0.0;
649 pos.
add(0.5 * ( 1.0 - xi ), posI);
650 pos.
add(0.5 * ( 1.0 + xi ), posJ);
653 double gamma = tangDist;
657 if ( gamma > -gammaRelTol * sqrt(edgeLength2) ) {
670 bool alreadyFound =
false;
672 int numPointsOld = oIntersectionPoints.size();
673 for (
int k = 1; k <= numPointsOld; k++ ) {
674 double dist = ps.
distance(oIntersectionPoints [ k - 1 ]);
682 if ( !alreadyFound ) {
683 oIntersectionPoints.push_back(ps);
685 double arcPos = 0.0, tangDist = 0.0;
687 oMinDistArcPos.push_back(arcPos);
689 oIntersectedEdgeInd.push_back(edgeIndex);
692 alreadyFound =
false;
694 numPointsOld = oIntersectionPoints.size();
695 for (
int k = 1; k <= numPointsOld; k++ ) {
696 double dist = pe.
distance(oIntersectionPoints [ k - 1 ]);
704 if ( !alreadyFound ) {
705 oIntersectionPoints.push_back(pe);
707 double arcPos = 0.0, tangDist = 0.0;
709 oMinDistArcPos.push_back(arcPos);
711 oIntersectedEdgeInd.push_back(edgeIndex);
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) ) );
729 bool alreadyFound =
false;
732 int numPointsOld = oIntersectionPoints.size();
733 for (
int k = 1; k <= numPointsOld; k++ ) {
734 double dist = p.
distance(oIntersectionPoints [ k - 1 ]);
742 if ( !alreadyFound ) {
743 oIntersectionPoints.push_back(p);
745 double arcPos = 0.0, tangDist = 0.0;
747 oMinDistArcPos.push_back(arcPos);
749 oIntersectedEdgeInd.push_back(edgeIndex);
765 const int numEdges = 3;
767 for (
int edgeIndex = 1; edgeIndex <= numEdges; edgeIndex++ ) {
771 switch ( edgeIndex ) {
803 double phiS = 0.0, phiE = 0.0;
804 double gammaS = 0.0, gammaE = 0.0;
806 bool levelSetDefinedInAllNodes =
true;
807 for (
int i = 1; i <= Ns.
giveSize(); i++ ) {
808 double phiSNode = 0.0;
810 phiS += Ns.
at(i) * phiSNode;
812 levelSetDefinedInAllNodes =
false;
815 double gammaSNode = 0.0;
817 gammaS += Ns.
at(i) * gammaSNode;
819 levelSetDefinedInAllNodes =
false;
822 double phiENode = 0.0;
824 phiE += Ne.
at(i) * phiENode;
826 levelSetDefinedInAllNodes =
false;
829 double gammaENode = 0.0;
831 gammaE += Ne.
at(i) * gammaENode;
833 levelSetDefinedInAllNodes =
false;
837 if ( phiS * phiE <
mLevelSetTol2 && levelSetDefinedInAllNodes ) {
841 double gamma = 0.5 * ( 1.0 - xi ) * gammaS + 0.5 * ( 1.0 + xi ) * gammaE;
857 bool alreadyFound =
false;
859 int numPointsOld = oIntersectionPoints.size();
860 for (
int k = 1; k <= numPointsOld; k++ ) {
861 double dist = ps.
distance(oIntersectionPoints [ k - 1 ]);
869 if ( !alreadyFound ) {
870 oIntersectionPoints.push_back(ps);
872 double arcPos = 0.0, tangDist = 0.0;
874 oMinDistArcPos.push_back(arcPos);
876 oIntersectedEdgeInd.push_back(edgeIndex);
879 alreadyFound =
false;
881 numPointsOld = oIntersectionPoints.size();
882 for (
int k = 1; k <= numPointsOld; k++ ) {
883 double dist = pe.
distance(oIntersectionPoints [ k - 1 ]);
891 if ( !alreadyFound ) {
892 oIntersectionPoints.push_back(pe);
894 double arcPos = 0.0, tangDist = 0.0;
896 oMinDistArcPos.push_back(arcPos);
898 oIntersectedEdgeInd.push_back(edgeIndex);
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) ) );
917 bool alreadyFound =
false;
920 int numPointsOld = oIntersectionPoints.size();
921 for (
int k = 1; k <= numPointsOld; k++ ) {
922 double dist = p.distance(oIntersectionPoints [ k - 1 ]);
930 if ( !alreadyFound ) {
931 oIntersectionPoints.push_back(p);
933 double arcPos = 0.0, tangDist = 0.0;
934 p.resizeWithValues(2);
936 oMinDistArcPos.push_back(arcPos);
938 oIntersectedEdgeInd.push_back(edgeIndex);
964 oFrontsHavePropagated =
false;
975 oFrontsHavePropagated =
true;
987 oFrontsHavePropagated =
true;
992 if ( mpEnrichmentDomain->getVtkDebug() ) {
995 EnrichmentDomain_BG *enrDomBG =
dynamic_cast< EnrichmentDomain_BG *
>( mpEnrichmentDomain );
997 if ( enrDomBG != NULL ) {
1014 TipInfo tipInfoStart, tipInfoEnd;
1018 std :: vector< TipInfo >tipInfos = {
1019 tipInfoStart, tipInfoEnd
1023 size_t minIndex = 0;
1024 bool foundTip =
false;
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);
1038 const FloatArray &globCoord = tipInfos [ minIndex ].mGlobalCoord;
1044 oCoord = tipInfos [ minIndex ].mGlobalCoord;
1045 oArcPos = tipInfos [ minIndex ].mArcPos;
1063 double meanLength = sqrt(meanArea);
1066 oRadius =
max(oRadius, meanLength);
The base class for all spatial localizers.
void evaluateEnrFuncJumps(std::vector< double > &oEnrFuncJumps, int iNodeInd, GaussPoint &iGP, bool iGPLivesOnCurrentCrack) const
int number
Component number.
const FloatArray & giveVertex(int n) const
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)
virtual IRResultType initializeFrom(InputRecord *ir)=0
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
Class representing the implementation of a dynamic data reader for in-code use.
int giveGlobalNumber() const
Domain * domain
Link to domain object, useful for communicating with other FEM components.
const double mLevelSetTol2
#define _IFT_EnrichmentItem_inheritbc
bool mLevelSetsNeedUpdate
double & at(int i)
Coefficient access function.
int max(int i, int j)
Returns bigger value form two given decimals.
virtual void updateNodeEnrMarker(XfemManager &ixFemMan)
double sgn(double i)
Returns the signum of given value (if value is < 0 returns -1, otherwise returns 1) ...
TipInfo gathers useful information about a crack tip, like its position and tangent direction...
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()
EngngModel * giveEngngModel()
Returns engineering model to which receiver is associated.
Abstract base class for all finite elements.
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.
int giveNumberOfElements() const
Returns number of elements in domain.
EnrichmentFunction * createEnrichmentFunction(const char *name, int num, Domain *domain)
Dummy propagation law that does nothing.
int giveNumberOfSpatialDimensions()
Returns number of spatial dimensions.
EnrichmentFront * createEnrichmentFront(const char *name)
virtual void giveInputRecord(DynamicInputRecord &input)
Setups the input record string of receiver.
Class implementing an array of integers.
int & at(int i)
Coefficient access function.
XfemManager * giveXfemManager()
virtual void createEnrichedDofs()
virtual FEInterpolation * giveInterpolation() const
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.
virtual void propagateFronts(bool &oFrontsHavePropagated)
bool mInheritOrderedBoundaryConditions
virtual int giveNumberOfNodes() const
Returns number of nodes of receiver.
double distance(const FloatArray &x) const
Computes the distance between position represented by receiver and position given as parameter...
Class representing a general abstraction for finite element interpolation class.
GeometryBasedEI(int n, XfemManager *xm, Domain *aDomain)
std::unordered_map< int, double > mLevelSetTangDirMap
const IntArray & giveDofManArray() const
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's number.
virtual void printVTK(int iTStepIndex, int iLineIndex)
Element * giveElement(int n)
Service for accessing particular domain fe element.
bool mInheritBoundaryConditions
If newly created enriched dofs should inherit boundary conditions from the node they are introduced i...
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's associated spatial localizer.
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.
std::unordered_map< int, double > mLevelSetNormalDirMap
virtual void giveInputRecord(DynamicInputRecord &input)
Setups the input record string of receiver.
void resizeWithValues(int s, int allocChunk=0)
Checks size of receiver towards requested bounds.
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
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.
virtual void giveInputRecord(DynamicInputRecord &input)=0
const FloatArray & giveGlobalCoordinates()
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.
bool evalLevelSetTangInNode(double &oLevelSet, int iNodeInd, const FloatArray &iGlobalCoord) const
Class representing vector of real numbers.
Implementation of matrix containing floating point numbers.
PropagationLaw * mpPropagationLaw
This class manages the xfem part.
IRResultType
Type defining the return values of InputRecord reading operations.
EnrichmentFront * mpEnrichmentFrontStart
const FloatArray & giveNodeCoordinates() const
As giveCoordinates, but non-virtual and therefore faster (because it can be inlined).
EnrichmentFunction * mpEnrichmentFunc
void zero()
Zeroes all coefficients of receiver.
EnrichmentFront * mpEnrichmentFrontEnd
int mEnrFrontIndex
mEnrFrontIndex: nonzero if an enrichment front is present, zero otherwise.
ClassFactory & classFactory
virtual int giveNumberOfEdges() const
Returns number of edges.
virtual bool computeLocalCoordinates(FloatArray &answer, const FloatArray &gcoords)
Computes the element local coordinates from given global coordinates.
virtual FloatArray * giveCoordinates()
Domain * giveDomain() const
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
virtual void giveInputRecord(DynamicInputRecord &input)=0
virtual void updateGeometry()
virtual TimeStep * giveCurrentStep(bool force=false)
Returns current time step.
#define _IFT_EnrichmentItem_inheritorderedbc
int giveSize() const
Returns the size of receiver.
PropagationLaw * createPropagationLaw(const char *name)
virtual double giveCoordinate(int i)
Node * giveNode(int n)
Service for accessing particular domain node.
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
static const double mLevelSetTol
Class implementing node in finite element mesh.
Node * giveNode(int i) const
Returns reference to the i-th node of element.
Class representing integration point in finite element program.
void insertInputRecord(InputRecordType type, InputRecord *record)
Main purpose of this class it the possibility to add new input records in code.
virtual ~GeometryBasedEI()
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.
virtual void appendInputRecords(DynamicDataReader &oDR)
void add(const FloatArray &src)
Adds array src to receiver.
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.
void resize(int s)
Resizes receiver towards requested size.