public bool IsInside(CartesianPoint point)
            {
                // Shapes
                var rectHull    = new Rectangular2DBoundary(0.0, bottomWidth, 0.0, totalHeight);
                var leftVoid    = new Rectangular2DBoundary(0.0, voidRectWidth, flangeHeight, totalHeight);
                var rightVoid   = new Rectangular2DBoundary(bottomWidth - voidRectWidth, bottomWidth, flangeHeight, totalHeight);
                var leftCircle  = new Circle2D(new CartesianPoint(leftCenterX, centerY), radius);
                var rightCircle = new Circle2D(new CartesianPoint(rightCenterX, centerY), radius);

                if (rectHull.IsInside(point))
                {
                    if (leftVoid.IsInside(point)) // Over flange, left of web
                    {
                        if ((point.X > leftCenterX) && (point.Y < centerY))
                        {
                            if (leftCircle.FindRelativePositionOfPoint(point) == CirclePointPosition.Outside)
                            {
                                return(true); // Inside left fillet
                            }
                            else
                            {
                                return(false);
                            }
                        }
                        else
                        {
                            return(false);
                        }
                    }
                    else if (rightVoid.IsInside(point)) // Over flange, right of web
                    {
                        if ((point.X < leftCenterX) && (point.Y < centerY))
                        {
                            if (leftCircle.FindRelativePositionOfPoint(point) == CirclePointPosition.Outside)
                            {
                                return(true); // Inside right fillet
                            }
                            else
                            {
                                return(false);
                            }
                        }
                        else
                        {
                            return(false);
                        }
                    }
                    else
                    {
                        return(true); // Inside the flange or the web
                    }
                }
                else
                {
                    return(false);
                }
            }
Beispiel #2
0
        /// <summary>
        /// If a fixed enrichment area is applied, all nodes inside a circle around the tip are enriched with tip
        /// functions. They can still be enriched with Heaviside functions, if they do not belong to the tip
        /// element(s).
        /// </summary>
        /// <param name="tipNodes"></param>
        /// <param name="tipElement"></param>
        private void ApplyFixedEnrichmentArea(CartesianPoint crackTip, XContinuumElement2D tipElement,
                                              HashSet <XNode> tipNodes, IEnrichmentItem2D tipEnrichments)
        {
            if (enrichmentRadiusOverElementSize > 0)
            {
                var    outline        = ConvexPolygon2D.CreateUnsafe(tipElement.Nodes);
                double elementArea    = outline.ComputeArea();
                double radius         = enrichmentRadiusOverElementSize * Math.Sqrt(elementArea);
                var    enrichmentArea = new Circle2D(crackTip, radius);

                foreach (var element in Mesh.FindElementsInsideCircle(enrichmentArea, tipElement))
                {
                    bool completelyInside = true;
                    foreach (var node in element.Nodes)
                    {
                        CirclePointPosition position = enrichmentArea.FindRelativePositionOfPoint(node);
                        if ((position == CirclePointPosition.Inside) || (position == CirclePointPosition.On))
                        {
                            tipNodes.Add(node);
                        }
                        else
                        {
                            completelyInside = false;
                        }
                    }

                    if (completelyInside)
                    {
                        element.EnrichmentItems.Add(tipEnrichments);
                    }
                }
            }
        }
Beispiel #3
0
        private IReadOnlyDictionary <XContinuumElement2D, double[]> FindJintegralElementsAndNodalWeights(
            CartesianPoint crackTip, TipCoordinateSystem tipSystem, IReadOnlyList <XContinuumElement2D> tipElements)
        {
            Circle2D outerContour =
                new Circle2D(crackTip, ComputeRadiusOfJintegralOuterContour(tipSystem, tipElements));
            IReadOnlyList <XContinuumElement2D> intersectedElements =
                mesh.FindElementsIntersectedByCircle(outerContour, tipElements[0]);

            var elementsAndWeights = new Dictionary <XContinuumElement2D, double[]>();

            foreach (var element in intersectedElements)
            {
                // The relative position of the circle and the nodes was already calculated when checking the
                // circle-element intersection, but that method should be decoupled from assigning the nodal
                // weights, even at the cost of some duplicate operations. What could be done more efficiently is
                // caching the nodes and weights already processed by previous elements, but even then the cost of
                // processing each node will be increased by the lookup.
                double[] nodalWeights = new double[element.Nodes.Count];
                for (int nodeIdx = 0; nodeIdx < element.Nodes.Count; ++nodeIdx)
                {
                    CirclePointPosition pos = outerContour.FindRelativePositionOfPoint((CartesianPoint)element.Nodes[nodeIdx]);
                    if (pos == CirclePointPosition.Outside)
                    {
                        nodalWeights[nodeIdx] = 0.0;
                    }
                    else // Node lies inside or exactly on the circle
                    {
                        nodalWeights[nodeIdx] = 1.0;
                    }
                }
                elementsAndWeights.Add(element, nodalWeights);
            }
            return(elementsAndWeights);
        }
        public IReadOnlyList <TNode> FindNodesInsideCircle(Circle2D circle,
                                                           bool findBoundaryNodes = true, TElement startingElement = null)
        {
            var selectedNodes = new List <TNode>();

            foreach (TNode node in Nodes) // O(nodesCount)
            {
                CirclePointPosition relativePosition = circle.FindRelativePositionOfPoint(new CartesianPoint(node.X, node.Y));
                if ((relativePosition == CirclePointPosition.Inside) ||
                    (findBoundaryNodes && (relativePosition == CirclePointPosition.On)))
                {
                    selectedNodes.Add(node);
                }
            }
            return(selectedNodes);
        }
        /// <summary>
        /// If a fixed enrichment area is applied, all nodes inside a circle around the tip are enriched with tip
        /// functions. They can still be enriched with Heaviside functions, if they do not belong to the tip
        /// element(s).
        /// </summary>
        /// <param name="tipElement"></param>
        private void ApplyFixedEnrichmentArea(XContinuumElement2D tipElement)
        {
            if (tipEnrichmentAreaRadius > 0)
            {
                var enrichmentArea = new Circle2D(crackTip, tipEnrichmentAreaRadius);
                foreach (var element in Mesh.FindElementsInsideCircle(enrichmentArea, tipElement))
                {
                    bool completelyInside = true;
                    foreach (var node in element.Nodes)
                    {
                        CirclePointPosition position = enrichmentArea.FindRelativePositionOfPoint(node);
                        if ((position == CirclePointPosition.Inside) || (position == CirclePointPosition.On))
                        {
                            crackTipNodesNew.Add(node);
                        }
                        else
                        {
                            completelyInside = false;
                        }
                    }

                    //TODO: I tried an alternative approach, ie elements access their enrichments from their nodes.
                    //      My original thought that this approach (storing enrichments in elements, unless they are standard /
                    //      blending) wouldn't work for blending elements, was incorrect, as elements with 0 enrichments
                    //      were then examined and separated into standard / blending.
                    if (completelyInside)
                    {
                        element.EnrichmentItems.Add(CrackTipEnrichments);
                    }
                }

                #region alternatively

                /* // If there wasn't a need to enrich the elements, this is more performant
                 * foreach (var node in mesh.FindNodesInsideCircle(enrichmentArea, true, tipElement))
                 * {
                 *  tipNodes.Add(node); // Nodes of tip element(s) will not be included twice
                 * } */
                #endregion
            }
        }
            public bool IsInside(CartesianPoint point)
            {
                // Shapes
                var rectHull    = new Rectangular2DBoundary(minX, maxX, minY, maxY);
                var leftCircle  = new Circle2D(new CartesianPoint(leftHoleX, leftHoleY), holeRadius);
                var rightCircle = new Circle2D(new CartesianPoint(rightHoleX, rightHoleY), holeRadius);

                // Intrnal points lie inside the rectangle, but outside the circular holes.
                if (rectHull.IsInside(point))
                {
                    if (leftCircle.FindRelativePositionOfPoint(point) == CirclePointPosition.Outside)
                    {
                        return(true);
                    }
                    if (rightCircle.FindRelativePositionOfPoint(point) == CirclePointPosition.Outside)
                    {
                        return(true);
                    }
                }
                return(false);
            }
Beispiel #7
0
        /// <summary>
        /// If a fixed enrichment area is applied, all nodes inside a circle around the tip are enriched with tip
        /// functions. They can still be enriched with Heaviside functions, if they do not belong to the tip
        /// element(s).
        /// </summary>
        /// <param name="tipNodes"></param>
        /// <param name="tipElement"></param>
        private void ApplyFixedEnrichmentArea(HashSet <XNode> tipNodes, XContinuumElement2D tipElement)
        {
            if (tipEnrichmentAreaRadius > 0)
            {
                var enrichmentArea = new Circle2D(crackTip, tipEnrichmentAreaRadius);
                foreach (var element in Mesh.FindElementsInsideCircle(enrichmentArea, tipElement))
                {
                    bool completelyInside = true;
                    foreach (var node in element.Nodes)
                    {
                        CirclePointPosition position = enrichmentArea.FindRelativePositionOfPoint(node);
                        if ((position == CirclePointPosition.Inside) || (position == CirclePointPosition.On))
                        {
                            tipNodes.Add(node);
                        }
                        else
                        {
                            completelyInside = false;
                        }
                    }
                    if (completelyInside)
                    {
                        element.EnrichmentItems.Add(CrackTipEnrichments);
                    }
                }

                #region alternatively

                /* // If there wasn't a need to enrich the elements, this is more performant
                 * foreach (var node in mesh.FindNodesInsideCircle(enrichmentArea, true, tipElement))
                 * {
                 *  tipNodes.Add(node); // Nodes of tip element(s) will not be included twice
                 * } */
                #endregion
            }
        }