Пример #1
0
        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);
        }
Пример #2
0
        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);
        }