Beispiel #1
0
 /// <summary>
 ///
 /// </summary>
 /// <param name="mesh"></param>
 /// <param name="crack"></param>
 /// <param name="magnificationOfJintegralRadius">The outer countour of the J-integral domain is defined as:
 ///     radius = magnification * sqrt(areaOfElementContainingTip). This parameter is the magnification.
 ///     It should be at least 1.5 (see "Modeling quasi-static crack growth with the extended finite element
 ///     method Part II: Numerical applications, Huang et al, 2003" page 7546). Usually values 2-3 are selected
 ///     (see Ahmed thesis, 2009).</param>
 /// <param name="auxiliaryStatesStrategy"></param>
 /// <param name="sifCalculationStrategy"></param>
 public Propagator(IMesh2D <XNode, XContinuumElement2D> mesh, double magnificationOfJintegralRadius,
                   IAuxiliaryStates auxiliaryStatesStrategy, ISIFCalculator sifCalculationStrategy,
                   ICrackGrowthDirectionLaw2D growthDirectionLaw, ICrackGrowthLengthLaw2D growthLengthLaw)
 {
     this.mesh = mesh;
     this.magnificationOfJintegralRadius = magnificationOfJintegralRadius;
     this.auxiliaryStatesStrategy        = auxiliaryStatesStrategy;
     this.sifCalculationStrategy         = sifCalculationStrategy;
     this.growthDirectionLaw             = growthDirectionLaw;
     this.growthLengthLaw = growthLengthLaw;
     this.Logger          = new PropagationLogger();
 }
        /// <summary>
        /// Given a set of Heaviside enriched nodes, find which of them must not be enriched, in order to avoid the global
        /// stiffness matrix being singular.
        /// </summary>
        /// <param name="mesh"></param>
        /// <param name="heavisideNodes">They will not be altered.</param>
        /// <returns></returns>
        public ISet <XNode> FindHeavisideNodesToRemove(ISingleCrack crack, IMesh2D <XNode, XContinuumElement2D> mesh,
                                                       ISet <XNode> heavisideNodes)
        {
            var processedElements = new Dictionary <XContinuumElement2D, Tuple <double, double> >();
            var nodesToRemove     = new HashSet <XNode>();

            foreach (var node in heavisideNodes)
            {
                double nodePositiveArea = 0.0;
                double nodeNegativeArea = 0.0;

                foreach (var element in mesh.FindElementsWithNode(node))
                {
                    bool alreadyProcessed = processedElements.TryGetValue(element, out Tuple <double, double> elementPosNegAreas);
                    if (!alreadyProcessed)
                    {
                        (double elementPosArea, double elementNegArea) = FindSignedAreasOfElement(crack, element);
                        elementPosNegAreas         = new Tuple <double, double>(elementPosArea, elementNegArea);
                        processedElements[element] = elementPosNegAreas;
                    }
                    nodePositiveArea += elementPosNegAreas.Item1;
                    nodeNegativeArea += elementPosNegAreas.Item2;
                }

                if (crack.SignedDistanceOf(node) >= 0.0)
                {
                    double negativeAreaRatio = nodeNegativeArea / (nodePositiveArea + nodeNegativeArea);
                    if (negativeAreaRatio < relativeAreaTolerance)
                    {
                        nodesToRemove.Add(node);
                    }
                }
                else
                {
                    double positiveAreaRatio = nodePositiveArea / (nodePositiveArea + nodeNegativeArea);
                    if (positiveAreaRatio < relativeAreaTolerance)
                    {
                        nodesToRemove.Add(node);
                    }
                }
            }

            return(nodesToRemove);
        }
 public GuidedPartioner2D(IMesh2D <TNode, TElement> mesh, Dictionary <int, IRegion2D> regions)
 {
     this.mesh    = mesh;
     this.regions = regions;
 }