private bool IsCutElement(XContinuumElement2D element) { var polygon = ConvexPolygon2D.CreateUnsafe(element.Nodes); // Look at each segment foreach (var crackSegment in Segments) { var segment = new LineSegment2D(crackSegment.Start, crackSegment.End); CartesianPoint intersectionPoint; foreach (var edge in polygon.Edges) { LineSegment2D.SegmentSegmentPosition position = segment.IntersectionWith(edge, out intersectionPoint); if (position == LineSegment2D.SegmentSegmentPosition.Intersecting) { // TODO: Perhaps the element should not be flagged as a Heaviside element, if the segment passes // through 1 node only. To detect this, check if the intersection point coincides with an element // node. If it does store it and go to the next edge. If a second intersection point (that does // not coincide with the stored one) is found then it is a Heaviside element. return(true); } else if (position == LineSegment2D.SegmentSegmentPosition.Overlapping) { return(true); } } } // Look at the vertices // (if a segment is entirely inside an element, it will not be caught by checking the segment itself) bool previousVertexOnEdge = false; LinkedListNode <CartesianPoint> currentNode = Vertices.First.Next; LinkedListNode <CartesianPoint> lastNode = Vertices.Last; while (currentNode != lastNode) { PolygonPointPosition position = polygon.FindRelativePositionOfPoint(currentNode.Value); if (position == PolygonPointPosition.Inside) { return(true); } else if (position == PolygonPointPosition.OnEdge || position == PolygonPointPosition.OnVertex) { if (previousVertexOnEdge) { return(true); } else { previousVertexOnEdge = true; } } else { previousVertexOnEdge = false; } currentNode = currentNode.Next; } return(false); }
private ElementEnrichmentType CharacterizeElementEnrichment(XContinuumElement2D element) { var polygon = ConvexPolygon2D.CreateUnsafe(element.Nodes); int tipIndex = Vertices.Count - 1; // Check tip element PolygonPointPosition tipPosition = polygon.FindRelativePositionOfPoint(Vertices[tipIndex]); if (tipPosition == PolygonPointPosition.Inside || tipPosition == PolygonPointPosition.OnEdge || tipPosition == PolygonPointPosition.OnVertex) { PolygonPointPosition previousVertexPos = polygon.FindRelativePositionOfPoint(Vertices[tipIndex - 1]); if (previousVertexPos == PolygonPointPosition.Inside) { // Problem with blending elements, if the tip element is also enriched with Heaviside. What happens // after the crack tip? Based on the LSM, the signed distance of the blending element after the // crack tip should have a positive and negative region, however that element is not split by the // crack and thus should not have discontinuity in the displacement field. var builder = new StringBuilder(); builder.Append("Crack tip "); builder.Append(Vertices[Vertices.Count - 1].ToString()); builder.Append(" and kink point "); builder.Append(Vertices[Vertices.Count - 2].ToString()); builder.Append(" inside the same element with nodes: "); foreach (var node in element.Nodes) { builder.Append(node.ToString()); builder.Append(' '); } throw new ArgumentException(builder.ToString()); //return ElementEnrichmentType.Both; } else { return(ElementEnrichmentType.Tip); } } // Look at the other vertices // (if a segment is inside an element, it will not be caught by checking the segment itself) bool previousVertexOnEdge = false; for (int v = 0; v < tipIndex; ++v) { PolygonPointPosition position = polygon.FindRelativePositionOfPoint(Vertices[v]); if (position == PolygonPointPosition.Inside) { return(ElementEnrichmentType.Heaviside); } else if (position == PolygonPointPosition.OnEdge || position == PolygonPointPosition.OnVertex) { if (previousVertexOnEdge) { return(ElementEnrichmentType.Heaviside); } else { previousVertexOnEdge = true; } } else { previousVertexOnEdge = false; } } // Look at each segment foreach (var crackSegment in Segments) { var segment = new LineSegment2D(crackSegment.Start, crackSegment.End); CartesianPoint intersectionPoint; foreach (var edge in polygon.Edges) { LineSegment2D.SegmentSegmentPosition position = segment.IntersectionWith(edge, out intersectionPoint); if (position == LineSegment2D.SegmentSegmentPosition.Intersecting) { // TODO: Perhaps the element should not be flagged as a Heaviside element, if the segment passes // through 1 node only. To detect this, check if the intersection point coincides with an element // node. If it does store it and go to the next edge. If a second intersection point (that does // not coincide with the stored one) is found then it is a Heaviside element. return(ElementEnrichmentType.Heaviside); } else if (position == LineSegment2D.SegmentSegmentPosition.Overlapping) { return(ElementEnrichmentType.Heaviside); } } } // Then it must be a standard element return(ElementEnrichmentType.Standard); }