Esempio n. 1
0
        private static Tensor2D ComputeStrainTensor(Matrix2by2 displacementGradient)
        {
            double exx = displacementGradient[0, 0];
            double eyy = displacementGradient[1, 1];
            double exy = 0.5 * (displacementGradient[0, 1] + displacementGradient[1, 0]);

            return(new Tensor2D(exx, eyy, exy));
        }
Esempio n. 2
0
        private void ComputeInteractionIntegrals(XContinuumElement2D element, Vector standardNodalDisplacements,
                                                 Vector enrichedNodalDisplacements, double[] nodalWeights, TipCoordinateSystem tipSystem,
                                                 out double integralMode1, out double integralMode2)
        {
            integralMode1 = 0.0;
            integralMode2 = 0.0;
            foreach (GaussPoint naturalGP in element.JintegralStrategy.GenerateIntegrationPoints(element))
            {
                // Nomenclature: global = global cartesian system, natural = element natural system,
                // local = tip local cartesian system

                EvalInterpolation2D evaluatedInterpolation =
                    element.Interpolation.EvaluateAllAt(element.Nodes, naturalGP);
                CartesianPoint globalGP     = evaluatedInterpolation.TransformPointNaturalToGlobalCartesian();
                Matrix         constitutive =
                    element.Material.CalculateConstitutiveMatrixAt(naturalGP, evaluatedInterpolation);

                // State 1
                Matrix2by2 globalDisplacementGradState1 = element.CalculateDisplacementFieldGradient(
                    naturalGP, evaluatedInterpolation, standardNodalDisplacements, enrichedNodalDisplacements);
                Tensor2D   globalStressState1          = element.CalculateStressTensor(globalDisplacementGradState1, constitutive);
                Matrix2by2 localDisplacementGradState1 = tipSystem.
                                                         TransformVectorFieldDerivativesGlobalCartesianToLocalCartesian(globalDisplacementGradState1);
                Tensor2D localStressTensorState1 = tipSystem.
                                                   TransformTensorGlobalCartesianToLocalCartesian(globalStressState1);

                // Weight Function
                // TODO: There should be a method InterpolateScalarGradient(double[] nodalValues) in EvaluatedInterpolation
                // TODO: Rewrite this as a shapeGradients (matrix) * nodalWeights (vector) operation.
                var globalWeightGradient = Vector2.CreateZero();
                for (int nodeIdx = 0; nodeIdx < element.Nodes.Count; ++nodeIdx)
                {
                    globalWeightGradient.AxpyIntoThis(
                        evaluatedInterpolation.ShapeGradientsCartesian.GetRow(nodeIdx), // Previously: GetGlobalCartesianDerivativesOf(element.Nodes[nodeIdx])
                        nodalWeights[nodeIdx]);
                }
                Vector2 localWeightGradient = tipSystem.
                                              TransformScalarFieldDerivativesGlobalCartesianToLocalCartesian(globalWeightGradient);

                // State 2
                // TODO: XContinuumElement shouldn't have to pass tipCoordinate system to auxiliaryStates.
                // It would be better to have CrackTip handle this and the coordinate transformations. That would also
                // obey LoD, but a lot of wrapper methods would be required.
                AuxiliaryStatesTensors auxiliary = auxiliaryStatesStrategy.ComputeTensorsAt(globalGP, tipSystem);

                // Interaction integrals
                double integrandMode1 = ComputeJIntegrand(localWeightGradient, localDisplacementGradState1,
                                                          localStressTensorState1, auxiliary.DisplacementGradientMode1,
                                                          auxiliary.StrainTensorMode1, auxiliary.StressTensorMode1);
                double integrandMode2 = ComputeJIntegrand(localWeightGradient, localDisplacementGradState1,
                                                          localStressTensorState1, auxiliary.DisplacementGradientMode2,
                                                          auxiliary.StrainTensorMode2, auxiliary.StressTensorMode2);

                integralMode1 += integrandMode1 * evaluatedInterpolation.Jacobian.DirectDeterminant * naturalGP.Weight;
                integralMode2 += integrandMode2 * evaluatedInterpolation.Jacobian.DirectDeterminant * naturalGP.Weight;
            }
        }
Esempio n. 3
0
 public AuxiliaryStatesTensors(Matrix2by2 displacementGradientMode1, Matrix2by2 displacementGradientMode2,
                               Tensor2D strainTensorMode1, Tensor2D strainTensorMode2,
                               Tensor2D stressTensorMode1, Tensor2D stressTensorMode2)
 {
     this.DisplacementGradientMode1 = displacementGradientMode1;
     this.DisplacementGradientMode2 = displacementGradientMode2;
     this.StrainTensorMode1         = strainTensorMode1;
     this.StrainTensorMode2         = strainTensorMode2;
     this.StressTensorMode1         = stressTensorMode1;
     this.StressTensorMode2         = stressTensorMode2;
 }
Esempio n. 4
0
        public Tensor2D EvaluateAt(XContinuumElement2D element, NaturalPoint point,
                                   Vector standardDisplacements, Vector enrichedDisplacements)
        {
            EvalInterpolation2D evaluatedInterpolation = element.Interpolation.EvaluateAllAt(element.Nodes, point);
            Matrix2by2          displacementGradient   = element.CalculateDisplacementFieldGradient(
                point, evaluatedInterpolation, standardDisplacements, enrichedDisplacements);
            Matrix constitutive =
                element.Material.CalculateConstitutiveMatrixAt(point, evaluatedInterpolation);

            return(element.CalculateStressTensor(displacementGradient, constitutive));
        }
Esempio n. 5
0
        public Tensor2D EvaluateAt(XContinuumElement2D element, NaturalPoint point,
                                   Vector standardDisplacements, Vector enrichedDisplacements)
        {
            EvalInterpolation2D evaluatedInterpolation = element.Interpolation.EvaluateAllAt(element.Nodes, point);
            Matrix2by2          displacementGradient   = element.CalculateDisplacementFieldGradient(
                point, evaluatedInterpolation, standardDisplacements, enrichedDisplacements);

            double strainXX = displacementGradient[0, 0];
            double strainYY = displacementGradient[1, 1];
            double strainXY = 0.5 * (displacementGradient[0, 1] + displacementGradient[1, 0]);

            return(new Tensor2D(strainXX, strainYY, strainXY));
        }
Esempio n. 6
0
        private void ComputeDisplacementDerivatives(TipJacobians polarJacobians, CommonValues val,
                                                    out Matrix2by2 displacementGradientMode1, out Matrix2by2 displacementGradientMode2)
        {
            // Temporary values and derivatives of the differentiated quantities. See documentation for their derivation.
            double E   = material.HomogeneousYoungModulus;
            double v   = material.HomogeneousPoissonRatio;
            double vEq = material.HomogeneousEquivalentPoissonRatio;
            double k   = (3.0 - vEq) / (1.0 + vEq);
            double a   = (1.0 + v) / (E * Math.Sqrt(2.0 * Math.PI));
            double b   = val.sqrtR;
            double b_r = 0.5 / val.sqrtR;

            // Mode 1
            {
                // Temporary values that differ between the 2 modes
                double c1       = val.cosThetaOver2 * (k - val.cosTheta);
                double c2       = val.sinThetaOver2 * (k - val.cosTheta);
                double c1_theta = -0.5 * c2 + val.cosThetaOver2 * val.sinTheta;
                double c2_theta = 0.5 * c1 + val.sinThetaOver2 * val.sinTheta;

                // The vector field derivatives w.r.t. to the local polar coordinates.
                // The vector components refer to the local cartesian system though.
                var polarGradient = Matrix2by2.CreateFromArray(
                    new double[, ] {
                    { a *b_r *c1, a *b *c1_theta }, { a *b_r *c2, a *b *c2_theta }
                });
                // The vector field derivatives w.r.t. to the local cartesian coordinates.
                displacementGradientMode1 =
                    polarJacobians.TransformVectorFieldDerivativesLocalPolarToLocalCartesian(polarGradient);
            }

            // Mode 2
            {
                double paren1   = 2.0 + k + val.cosTheta;
                double paren2   = 2.0 - k - val.cosTheta;
                double c1       = val.sinThetaOver2 * paren1;
                double c2       = val.cosThetaOver2 * paren2;
                double c1_theta = 0.5 * val.cosThetaOver2 * paren1 - val.sinThetaOver2 * val.sinTheta;
                double c2_theta = -0.5 * val.sinThetaOver2 * paren2 + val.cosThetaOver2 * val.sinTheta;

                // The vector field derivatives w.r.t. to the local polar coordinates.
                // The vector components refer to the local cartesian system though.
                var polarGradient = Matrix2by2.CreateFromArray(
                    new double[, ] {
                    { a *b_r *c1, a *b *c1_theta }, { a *b_r *c2, a *b *c2_theta }
                });
                // The vector field derivatives w.r.t. to the local cartesian coordinates.
                displacementGradientMode2 =
                    polarJacobians.TransformVectorFieldDerivativesLocalPolarToLocalCartesian(polarGradient);
            }
        }
        /// <summary>
        ///
        /// </summary>
        /// <param name="tipCoordinates">Coordinates of the crack tip in the global cartesian system.</param>
        /// <param name="tipRotationAngle">Counter-clockwise angle from the O-x axis of the global cartesian system to
        ///     the T-x1 axis of the local corrdinate system of the tip (T being the tip point)</param>
        public TipCoordinateSystem(CartesianPoint tipCoordinates, double tipRotationAngle)
        {
            this.RotationAngle = tipRotationAngle;

            double cosa = Math.Cos(tipRotationAngle);
            double sina = Math.Sin(tipRotationAngle);

            RotationMatrixGlobalToLocal = Matrix2by2.CreateFromArray(new double[, ] {
                { cosa, sina }, { -sina, cosa }
            });
            TransposeRotationMatrixGlobalToLocal        = RotationMatrixGlobalToLocal.Transpose();
            localCoordinatesOfGlobalOrigin              = -1 * (RotationMatrixGlobalToLocal * Vector2.Create(tipCoordinates.X, tipCoordinates.Y));
            DeterminantOfJacobianGlobalToLocalCartesian = 1.0; // det = (cosa)^2 +(sina)^2 = 1
        }
Esempio n. 8
0
        public TipJacobians(TipCoordinateSystem tipSystem, PolarPoint2D polarCoordinates)
        {
            this.tipSystem = tipSystem;

            double r        = polarCoordinates.R;
            double cosTheta = Math.Cos(polarCoordinates.Theta);
            double sinTheta = Math.Sin(polarCoordinates.Theta);

            inverseJacobianPolarToLocal = Matrix2by2.CreateFromArray(new double[, ]
            {
                { cosTheta, sinTheta }, { -sinTheta / r, cosTheta / r }
            });

            inverseJacobianPolarToGlobal = inverseJacobianPolarToLocal * tipSystem.RotationMatrixGlobalToLocal;
        }
Esempio n. 9
0
        private static double ComputeJIntegrand(Vector2 weightGrad, Matrix2by2 displGrad1, Tensor2D stress1,
                                                Matrix2by2 displGrad2, Tensor2D strain2, Tensor2D stress2)
        {
            // Unrolled to greatly reduce mistakes. Alternatively Einstein notation products could be implementated
            // in Tensor2D (like the tensor-tensor multiplication is), but still some parts would have to be unrolled.
            // Perhaps vector (and scalar) gradients should also be accessed by component and derivative variable.

            double strainEnergy = stress1.MultiplyColon(strain2);
            double parenthesis0 = stress1.XX * displGrad2[0, 0] + stress1.XY * displGrad2[1, 0]
                                  + stress2.XX * displGrad1[0, 0] + stress2.XY * displGrad1[1, 0] - strainEnergy;
            double parenthesis1 = stress1.XY * displGrad2[0, 0] + stress1.YY * displGrad2[1, 0]
                                  + stress2.XY * displGrad1[0, 0] + stress2.YY * displGrad1[1, 0];

            return(parenthesis0 * weightGrad[0] + parenthesis1 * weightGrad[1]);
        }
Esempio n. 10
0
        private (Tensor2D strain, Tensor2D stress) ComputeStrainStress(XContinuumElement2D element, NaturalPoint gaussPoint,
                                                                       EvalInterpolation2D evaluatedInterpolation, Vector standardNodalDisplacements,
                                                                       Vector enrichedNodalDisplacements)
        {
            Matrix constitutive =
                element.Material.CalculateConstitutiveMatrixAt(gaussPoint, evaluatedInterpolation);
            Matrix2by2 displacementGradient = element.CalculateDisplacementFieldGradient(gaussPoint, evaluatedInterpolation,
                                                                                         standardNodalDisplacements, enrichedNodalDisplacements);

            double strainXX       = displacementGradient[0, 0];
            double strainYY       = displacementGradient[1, 1];
            double strainXYtimes2 = displacementGradient[0, 1] + displacementGradient[1, 0];

            double stressXX = constitutive[0, 0] * strainXX + constitutive[0, 1] * strainYY;
            double stressYY = constitutive[1, 0] * strainXX + constitutive[1, 1] * strainYY;
            double stressXY = constitutive[2, 2] * strainXYtimes2;

            return(new Tensor2D(strainXX, strainYY, 0.5 * strainXYtimes2), new Tensor2D(stressXX, stressYY, stressXY));
        }
Esempio n. 11
0
        // Computes stresses directly at the nodes. The other approach is to compute them at Gauss points and then extrapolate
        private IReadOnlyDictionary <XNode, Tensor2D> ComputeNodalStressesOfElement(XContinuumElement2D element,
                                                                                    Vector freeDisplacements, Vector constrainedDisplacements)
        {
            Vector standardDisplacements = dofOrderer.ExtractDisplacementVectorOfElementFromGlobal(element,
                                                                                                   freeDisplacements, constrainedDisplacements);
            Vector enrichedDisplacements =
                dofOrderer.ExtractEnrichedDisplacementsOfElementFromGlobal(element, freeDisplacements);

            IReadOnlyList <NaturalPoint> naturalNodes = element.Interpolation.NodalNaturalCoordinates;
            var nodalStresses = new Dictionary <XNode, Tensor2D>();

            for (int i = 0; i < element.Nodes.Count; ++i)
            {
                EvalInterpolation2D evaluatedInterpolation =
                    element.Interpolation.EvaluateAllAt(element.Nodes, naturalNodes[i]);
                Matrix2by2 displacementGradient = element.CalculateDisplacementFieldGradient(
                    naturalNodes[i], evaluatedInterpolation, standardDisplacements, enrichedDisplacements);
                Matrix constitutive =
                    element.Material.CalculateConstitutiveMatrixAt(naturalNodes[i], evaluatedInterpolation);
                nodalStresses[element.Nodes[i]] = element.CalculateStressTensor(displacementGradient, constitutive);
            }

            return(nodalStresses);
        }
Esempio n. 12
0
 /// <summary>
 /// Attention: The input vector field is differentiated w.r.t. the polar cartesian system coordinates.
 /// The output vector field is differentiated w.r.t. the local cartesian system coordinates. However the
 /// representations of both vector fields (aka the coordinates of the vectors) are in the local cartesian
 /// coordinate system.
 /// </summary>
 /// <param name="gradient">A 2x2 matrix, for which: Row i is the gradient of the ith component of the vector
 ///     field, thus:    gradient = [Fr,r Fr,theta; Ftheta,r Ftheta,theta],
 ///     where Fi,j is the derivative of component i w.r.t. coordinate j</param>
 /// <returns></returns>
 public Matrix2by2 TransformVectorFieldDerivativesLocalPolarToLocalCartesian(Matrix2by2 gradient)
 {
     return(gradient * inverseJacobianPolarToLocal);
 }
 /// <summary>
 ///
 /// </summary>
 /// <param name="gradient">A 2x2 matrix, for which: Row i is the gradient of the ith component of the vector
 ///     field, thus:    gradient = [Fx,x Fx,y; Fy,x Fy,y],
 ///     where Fi,j is the derivative of component i w.r.t. coordinate j</param>
 /// <returns></returns>
 public Matrix2by2 TransformVectorFieldDerivativesGlobalCartesianToLocalCartesian(Matrix2by2 gradient)
 {
     return(RotationMatrixGlobalToLocal * (gradient * TransposeRotationMatrixGlobalToLocal));
 }