Пример #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
        public SortedSet <CartesianPoint> FindTriangleVertices(XContinuumElement2D element)
        {
            var polygon          = ConvexPolygon2D.CreateUnsafe(element.Nodes);
            var triangleVertices = new SortedSet <CartesianPoint>(element.Nodes, pointComparer);
            int nodesCount       = element.Nodes.Count;

            foreach (var vertex in Vertices)
            {
                PolygonPointPosition position = polygon.FindRelativePositionOfPoint(vertex);
                if (position == PolygonPointPosition.Inside || position == PolygonPointPosition.OnEdge ||
                    position == PolygonPointPosition.OnVertex)
                {
                    triangleVertices.Add(vertex);
                }
            }

            foreach (var crackSegment in Segments)
            {
                var segment = new LineSegment2D(crackSegment.Start, crackSegment.End);
                IReadOnlyList <CartesianPoint> intersections = segment.IntersectionWith(polygon);
                foreach (var point in intersections)
                {
                    triangleVertices.Add(point);
                }
            }

            return(triangleVertices);
        }
Пример #3
0
        public NodePosition FindRelativePosition(XNode node)
        {
            PolygonPointPosition pos = polygon.FindRelativePositionOfPoint(node);

            if (pos == PolygonPointPosition.Outside)
            {
                return(NodePosition.External);
            }
            else if ((pos == PolygonPointPosition.OnEdge) || (pos == PolygonPointPosition.OnVertex))
            {
                // On the inter-subdomain part of the polygon's outline
                foreach (var boundary in boundaries)
                {
                    if (boundary.FindRelativePositionOfPoint(node) == LineSegment2D.SegmentPointPosition.PointOnSegment)
                    {
                        return(NodePosition.Boundary);
                    }
                }

                // otherwise
                return(NodePosition.Internal);
            }
            else if (pos == PolygonPointPosition.Inside)
            {
                return(NodePosition.Internal);
            }
            else
            {
                throw new Exception("This code should not have been reached");
            }
        }
Пример #4
0
        public List <XContinuumElement2D> FindElementsThatContains(IEnumerable <XContinuumElement2D> elements,
                                                                   CartesianPoint point)
        {
            var result = new List <XContinuumElement2D>();

            foreach (var element in elements)
            {
                var outline = ConvexPolygon2D.CreateUnsafe(element.Nodes);
                PolygonPointPosition position = outline.FindRelativePositionOfPoint(point);
                if (position == PolygonPointPosition.Inside)
                {
                    result.Add(element);
                    break;
                }
                else if ((position == PolygonPointPosition.OnEdge) || (position == PolygonPointPosition.OnVertex))
                {
                    result.Add(element);
                }
            }

            if (result.Count == 0)
            {
                throw new KeyNotFoundException("No element containing the point " + point + "was found");
            }
            return(result);
        }
Пример #5
0
        // TODO: handle cases where more the point lies on an element edge or node.
        public IReadOnlyList <TElement> FindElementsContainingPoint(CartesianPoint point, TElement startingElement = null)
        {
            var containingElements = new List <TElement>();

            foreach (TElement element in Elements) // O(elementsCount)
            {
                var outline = ConvexPolygon2D.CreateUnsafe(element.Nodes.ToCartesianPoints());
                PolygonPointPosition pos = outline.FindRelativePositionOfPoint(point);
                if ((pos == PolygonPointPosition.Inside) || (pos == PolygonPointPosition.OnEdge) ||
                    (pos == PolygonPointPosition.OnVertex))
                {
                    containingElements.Add(element);
                }
            }
            return(containingElements);
        }
Пример #6
0
        private bool IsTipElement(XContinuumElement2D element, CrackTipPosition tipPosition)
        {
            CartesianPoint crackTip, adjacentVertex;

            if (tipPosition == CrackTipPosition.Start)
            {
                crackTip       = Vertices.First.Value;
                adjacentVertex = Vertices.First.Next.Value;
            }
            else if (tipPosition == CrackTipPosition.End)
            {
                crackTip       = Vertices.Last.Value;
                adjacentVertex = Vertices.Last.Previous.Value;
            }
            else
            {
                throw new ArgumentException("Tip position can be either start or end");
            }

            var polygon = ConvexPolygon2D.CreateUnsafe(element.Nodes);
            PolygonPointPosition relativeTipPos = polygon.FindRelativePositionOfPoint(crackTip);

            if (relativeTipPos == PolygonPointPosition.Inside || relativeTipPos == PolygonPointPosition.OnEdge ||
                relativeTipPos == PolygonPointPosition.OnVertex)
            {
                PolygonPointPosition previousVertexPos = polygon.FindRelativePositionOfPoint(adjacentVertex);
                if (previousVertexPos == PolygonPointPosition.Inside)
                {
                    throw new NotImplementedException("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");
                    //return ElementEnrichmentType.Both;
                }
                return(true);
            }
            return(false);
        }
Пример #7
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);
        }