public void InitializeGeometry(CartesianPoint crackMouth, CartesianPoint crackTip)
        {
            this.crackMouth = crackMouth;
            crackPath.Add(crackMouth);
            var segment = new DirectedSegment2D(crackMouth, crackTip);

            double tangentX     = crackTip.X - crackMouth.X;
            double tangentY     = crackTip.Y - crackMouth.Y;
            double length       = Math.Sqrt(tangentX * tangentX + tangentY * tangentY);
            double tangentSlope = Math.Atan2(tangentY, tangentX);

            this.crackTip = crackTip;
            crackPath.Add(crackTip);
            tipSystem = new TipCoordinateSystem(crackTip, tangentSlope);
            CrackTipEnrichments.TipSystem = tipSystem;

            tangentX /= length;
            tangentY /= length;

            foreach (XNode node in Mesh.Nodes)
            {
                levelSetsBody[node] = segment.SignedDistanceOf(node);
                levelSetsTip[node]  = (node.X - crackTip.X) * tangentX + (node.Y - crackTip.Y) * tangentY;
            }

            if (LevelSetLogger != null)
            {
                LevelSetLogger.InitialLog();                         //TODO: handle this with a NullLogger.
            }
        }
Ejemplo n.º 2
0
        public void UpdateGeometry(double localGrowthAngle, double growthLength)
        {
            double globalGrowthAngle = MathUtilities.WrapAngle(localGrowthAngle + tipSystem.RotationAngle);
            double dx     = growthLength * Math.Cos(globalGrowthAngle);
            double dy     = growthLength * Math.Sin(globalGrowthAngle);
            double unitDx = dx / growthLength;
            double unitDy = dy / growthLength;

            var oldTip = crackTip;
            var newTip = new CartesianPoint(oldTip.X + dx, oldTip.Y + dy);

            crackTip  = newTip;
            tipSystem = new TipCoordinateSystem(newTip, globalGrowthAngle);

            var newSegment = new DirectedSegment2D(oldTip, newTip);

            foreach (XNode node in Mesh.Nodes)
            {
                // Rotate the ALL tip level sets towards the new tip and then advance them
                double rotatedTipLevelSet = (node.X - crackTip.X) * unitDx + (node.Y - crackTip.Y) * unitDy;
                levelSetsTip[node] = rotatedTipLevelSet - newSegment.Length;

                if (rotatedTipLevelSet > 0.0) // Only some body level sets are updated (See Stolarska 2001)
                {
                    levelSetsBody[node] = newSegment.SignedDistanceOf(node);
                }
            }
        }
Ejemplo n.º 3
0
        public HashSet <XNode> Update(CartesianPoint oldTip, double localGrowthAngle, double growthLength, double dx, double dy,
                                      IReadOnlyList <XNode> allNodes, ISet <XNode> crackBodyNodesAll,
                                      Dictionary <XNode, double> levelSetsBody, Dictionary <XNode, double> levelSetsTip)
        {
            double unitDx     = dx / growthLength;
            double unitDy     = dy / growthLength;
            var    newTip     = new CartesianPoint(oldTip.X + dx, oldTip.Y + dy);
            var    newSegment = new DirectedSegment2D(oldTip, newTip);

            var crackBodyNodesModified = new HashSet <XNode>();

            foreach (XNode node in allNodes)
            {
                // Rotate the ALL tip level sets towards the new tip and then advance them
                double rotatedTipLevelSet = (node.X - oldTip.X) * unitDx + (node.Y - oldTip.Y) * unitDy;
                levelSetsTip[node] = rotatedTipLevelSet - growthLength;

                // Only some body level sets are updated (See Stolarska 2001)
                // WARNING: this is quite dangerous. If the crack turns/kinks sufficiently over its whole history, then nodes far
                // alway from the tip that should remain unchanged, will get different level sets. A new formula is needed to
                // avoid messing them up. In a narrow band approach, it may be possible to limit the level set update in nodes
                // near to the old tip the new tip or the inbetween segment.
                if (rotatedTipLevelSet > 0.0)
                {
                    levelSetsBody[node] = newSegment.SignedDistanceOf(node);
                    if (crackBodyNodesAll.Contains(node))
                    {
                        crackBodyNodesModified.Add(node);
                    }
                }
            }

            if (crackBodyNodesModified.Count != 0)
            {
                Console.WriteLine("There are nodes that were previously enriched with Heaviside, but now their level set"
                                  + " changes. For 1st order LSM, this usually indicates that the crack has turned sufficiently towards"
                                  + " its original geometry. In that case, the body level set of these nodes is computed from the crack"
                                  + " extension far away from their position and is thus incorrect. These nodes are: ");
                foreach (var node in crackBodyNodesModified)
                {
                    Console.WriteLine(node);
                }
                Console.WriteLine();
            }
            return(crackBodyNodesModified);
        }
Ejemplo n.º 4
0
        public void InitializeGeometry(CartesianPoint crackMouth, CartesianPoint crackTip)
        {
            CrackMouth = crackMouth;
            var segment = new DirectedSegment2D(crackMouth, crackTip);

            double tangentX     = crackTip.X - crackMouth.X;
            double tangentY     = crackTip.Y - crackMouth.Y;
            double length       = Math.Sqrt(tangentX * tangentX + tangentY * tangentY);
            double tangentSlope = Math.Atan2(tangentY, tangentX);

            this.crackTip = crackTip;
            tipSystem     = new TipCoordinateSystem(crackTip, tangentSlope);

            tangentX /= length;
            tangentY /= length;

            foreach (XNode node in Mesh.Nodes)
            {
                levelSetsBody[node] = segment.SignedDistanceOf(node);
                levelSetsTip[node]  = (node.X - crackTip.X) * tangentX + (node.Y - crackTip.Y) * tangentY;
            }
        }