コード例 #1
0
        private static void TestConsistentMass0()
        {
            IQuadrature2D quadratureForMass = TriangleQuadratureSymmetricGaussian.Order4Points6;

            var materialsAtGaussPoints = new List <ElasticMaterial2D>();

            foreach (GaussPoint gaussPoint in quadratureForMass.IntegrationPoints)
            {
                materialsAtGaussPoints.Add(material0.Clone());
            }
            var tri6 = new ContinuumElement2D(thickness, nodeSet0, InterpolationTri6.UniqueInstance,
                                              TriangleQuadratureSymmetricGaussian.Order2Points3, quadratureForMass,
                                              ExtrapolationGaussTriangular3Points.UniqueInstance,
                                              materialsAtGaussPoints, dynamicMaterial);

            IMatrix M         = tri6.BuildConsistentMassMatrix();
            Matrix  expectedM = Matrix.CreateFromArray(new double[, ]
            {
                { 11.83599396, 0, -1.829621484, 0, -1.968668415, 0, 0.702983761, 0, -6.922261694, 0, 0.623796095, 0, },
                { 0, 11.83599396, 0, -1.829621484, 0, -1.968668415, 0, 0.702983761, 0, -6.922261694, 0, 0.623796095, },
                { -1.829621484, 0, 9.926994738, 0, -1.638252825, 0, -0.618678599, 0, -0.46271906, 0, -7.392556104, 0, },
                { 0, -1.829621484, 0, 9.926994738, 0, -1.638252825, 0, -0.618678599, 0, -0.46271906, 0, -7.392556104, },
                { -1.968668415, 0, -1.638252825, 0, 10.74103411, 0, -7.234180772, 0, 9.35E-02, 0, -0.141678539, 0, },
                { 0, -1.968668415, 0, -1.638252825, 0, 10.74103411, 0, -7.234180772, 0, 9.35E-02, 0, -0.141678539, },
                { 0.702983761, 0, -0.618678599, 0, -7.234180772, 0, 57.86118359, 0, 28.31288493, 0, 29.25347375, 0, },
                { 0, 0.702983761, 0, -0.618678599, 0, -7.234180772, 0, 57.86118359, 0, 28.31288493, 0, 29.25347375, },
                { -6.922261694, 0, -0.46271906, 0, 9.35E-02, 0, 28.31288493, 0, 56.00999156, 0, 28.6296356, 0, },
                { 0, -6.922261694, 0, -0.46271906, 0, 9.35E-02, 0, 28.31288493, 0, 56.00999156, 0, 28.6296356, },
                { 0.623796095, 0, -7.392556104, 0, -0.141678539, 0, 29.25347375, 0, 28.6296356, 0, 58.49121809, 0, },
                { 0, 0.623796095, 0, -7.392556104, 0, -0.141678539, 0, 29.25347375, 0, 28.6296356, 0, 58.49121809, }
            }); // from Abaqus

            Assert.True(M.Equals(expectedM, 1e-3));
        }
コード例 #2
0
 public SurfaceLoadElement(ISurfaceLoad surfaceLoad, IIsoparametricInterpolation2D isoparametricInterpolation2D,
                           IQuadrature2D quadrature2D, IReadOnlyList <Node> nodes)
 {
     this.surfaceLoad = surfaceLoad;
     this.isoparametricInterpolation2D = isoparametricInterpolation2D;
     this.quadrature2D = quadrature2D;
     this.nodes        = nodes;
 }
コード例 #3
0
 public CohesiveShell8ToHexa20(ICohesiveZoneMaterial3D material, IQuadrature2D quadratureForStiffness)
 {
     this.QuadratureForStiffness = quadratureForStiffness;
     this.nGaussPoints           = quadratureForStiffness.IntegrationPoints.Count;
     materialsAtGaussPoints      = new ICohesiveZoneMaterial3D[nGaussPoints];
     for (int i = 0; i < nGaussPoints; i++)
     {
         materialsAtGaussPoints[i] = material.Clone();
     }
 }
コード例 #4
0
        public IReadOnlyList <Matrix> EvaluateN3ShapeFunctionsReorganized(IQuadrature2D quadrature)
        {
            bool isCached = cachedN3AtGPs.TryGetValue(quadrature,
                                                      out IReadOnlyList <Matrix> N3AtGPs);

            if (isCached)
            {
                return(N3AtGPs);
            }
            else
            {
                IReadOnlyList <double[]> N1 = EvaluateFunctionsAtGaussPoints(quadrature);
                N3AtGPs = GetN3ShapeFunctionsReorganized(quadrature, N1);
                cachedN3AtGPs.Add(quadrature, N3AtGPs);
                return(N3AtGPs);
            }
        }
コード例 #5
0
        //private readonly Dictionary<GaussPoint, ThermalMaterial> materialsAtGaussPoints;


        public ThermalElement2D(double thickness, IReadOnlyList <Node> nodes, IIsoparametricInterpolation2D interpolation,
                                IQuadrature2D quadratureForStiffness, IQuadrature2D quadratureForConsistentMass,
                                IGaussPointExtrapolation2D gaussPointExtrapolation,
                                ThermalMaterial material)
        {
            this.material = material;
            this.GaussPointExtrapolation = gaussPointExtrapolation;
            this.Nodes         = nodes;
            this.Interpolation = interpolation;
            this.QuadratureForConsistentMass = quadratureForConsistentMass;
            this.QuadratureForStiffness      = quadratureForStiffness;
            this.Thickness = thickness;

            dofTypes = new IDofType[nodes.Count][];
            for (int i = 0; i < interpolation.NumFunctions; ++i)
            {
                dofTypes[i] = new IDofType[] { ThermalDof.Temperature }
            }
            ;
        }
コード例 #6
0
        public ContinuumElement2D(double thickness, IReadOnlyList <Node> nodes, IIsoparametricInterpolation2D interpolation,
                                  IQuadrature2D quadratureForStiffness, IQuadrature2D quadratureForConsistentMass,
                                  IGaussPointExtrapolation2D gaussPointExtrapolation,
                                  IReadOnlyList <ElasticMaterial2D> materialsAtGaussPoints, DynamicMaterial dynamicProperties)
        {
            this.dynamicProperties       = dynamicProperties;
            this.materialsAtGaussPoints  = materialsAtGaussPoints;
            this.GaussPointExtrapolation = gaussPointExtrapolation;
            this.Nodes         = nodes;
            this.Interpolation = interpolation;
            this.QuadratureForConsistentMass = quadratureForConsistentMass;
            this.QuadratureForStiffness      = quadratureForStiffness;
            this.Thickness = thickness;

            dofTypes = new IDofType[nodes.Count][];
            for (int i = 0; i < nodes.Count; ++i)
            {
                dofTypes[i] = new IDofType[] { StructuralDof.TranslationX, StructuralDof.TranslationY };
            }
        }
コード例 #7
0
        /// <summary>
        /// See <see cref="IIsoparametricInterpolation2D.EvaluateFunctionsAtGaussPoints(IQuadrature2D)"/>.
        /// </summary>
        public IReadOnlyList <double[]> EvaluateFunctionsAtGaussPoints(IQuadrature2D quadrature)
        {
            bool isCached = cachedFunctionsAtGPs.TryGetValue(quadrature,
                                                             out IReadOnlyList <double[]> shapeFunctionsAtGPs);

            if (isCached)
            {
                return(shapeFunctionsAtGPs);
            }
            else
            {
                int numGPs = quadrature.IntegrationPoints.Count;
                var shapeFunctionsAtGPsArray = new double[numGPs][];
                for (int gp = 0; gp < numGPs; ++gp)
                {
                    GaussPoint gaussPoint = quadrature.IntegrationPoints[gp];
                    shapeFunctionsAtGPsArray[gp] = EvaluateAt(gaussPoint.Xi, gaussPoint.Eta);
                }
                cachedFunctionsAtGPs.Add(quadrature, shapeFunctionsAtGPsArray);
                return(shapeFunctionsAtGPsArray);
            }
        }
コード例 #8
0
        /// <summary>
        /// See <see cref="IIsoparametricInterpolation2D.EvaluateNaturalGradientsAtGaussPoints(IQuadrature2D)"/>.
        /// </summary>
        /// <param name="quadrature"></param>
        public IReadOnlyList <Matrix> EvaluateNaturalGradientsAtGaussPoints(IQuadrature2D quadrature)
        {
            bool isCached = cachedNaturalGradientsAtGPs.TryGetValue(quadrature,
                                                                    out IReadOnlyList <Matrix> naturalGradientsAtGPs);

            if (isCached)
            {
                return(naturalGradientsAtGPs);
            }
            else
            {
                int numGPs = quadrature.IntegrationPoints.Count;
                var naturalGradientsAtGPsArray = new Matrix[numGPs];
                for (int gp = 0; gp < numGPs; ++gp)
                {
                    GaussPoint gaussPoint = quadrature.IntegrationPoints[gp];
                    naturalGradientsAtGPsArray[gp] = EvaluateGradientsAt(gaussPoint.Xi, gaussPoint.Eta);
                }
                cachedNaturalGradientsAtGPs.Add(quadrature, naturalGradientsAtGPsArray);
                return(naturalGradientsAtGPsArray);
            }
        }
コード例 #9
0
        private static void TestConsistentMass0()
        {
            IQuadrature2D quadratureForMass = GaussLegendre2D.GetQuadratureWithOrder(3, 3);

            var materialsAtGaussPoints = new List <ElasticMaterial2D>();

            foreach (GaussPoint gaussPoint in quadratureForMass.IntegrationPoints)
            {
                materialsAtGaussPoints.Add(material0.Clone());
            }
            var quad8 = new ContinuumElement2D(thickness, nodeSet0, InterpolationQuad8.UniqueInstance,
                                               GaussLegendre2D.GetQuadratureWithOrder(3, 3), quadratureForMass,
                                               ExtrapolationGaussLegendre3x3.UniqueInstance,
                                               materialsAtGaussPoints, dynamicMaterial);

            IMatrix M         = quad8.BuildConsistentMassMatrix();
            Matrix  expectedM = Matrix.CreateFromArray(new double[, ]
            {
                { 9.115245555556, 0.000000000000, 1.881383333333, 0.000000000000, 3.914882222222, 0.000000000000, 2.417800000000, 0.000000000000, -7.376906666667, 0.000000000000, -11.056637777778, 0.000000000000, -9.104604444445, 0.000000000000, -7.444940000000, 0.000000000000 },
                { 0.000000000000, 9.115245555556, 0.000000000000, 1.881383333333, 0.000000000000, 3.914882222222, 0.000000000000, 2.417800000000, 0.000000000000, -7.376906666667, 0.000000000000, -11.056637777778, 0.000000000000, -9.104604444445, 0.000000000000, -7.444940000000 },
                { 1.881383333333, 0.000000000000, 9.727545555556, 0.000000000000, 2.239866666667, 0.000000000000, 3.841615555556, 0.000000000000, -6.727973333334, 0.000000000000, -6.701806666667, 0.000000000000, -9.031337777778, 0.000000000000, -11.077571111111, 0.000000000000 },
                { 0.000000000000, 1.881383333333, 0.000000000000, 9.727545555556, 0.000000000000, 2.239866666667, 0.000000000000, 3.841615555556, 0.000000000000, -6.727973333334, 0.000000000000, -6.701806666667, 0.000000000000, -9.031337777778, 0.000000000000, -11.077571111111 },
                { 3.914882222222, 0.000000000000, 2.239866666667, 0.000000000000, 7.681312222222, 0.000000000000, 2.776283333333, 0.000000000000, -11.082804444445, 0.000000000000, -8.784673333334, 0.000000000000, -6.832640000000, 0.000000000000, -11.150837777778, 0.000000000000 },
                { 0.000000000000, 3.914882222222, 0.000000000000, 2.239866666667, 0.000000000000, 7.681312222222, 0.000000000000, 2.776283333333, 0.000000000000, -11.082804444445, 0.000000000000, -8.784673333334, 0.000000000000, -6.832640000000, 0.000000000000, -11.150837777778 },
                { 2.417800000000, 0.000000000000, 3.841615555556, 0.000000000000, 2.776283333333, 0.000000000000, 7.581878888889, 0.000000000000, -11.009537777778, 0.000000000000, -10.983371111111, 0.000000000000, -6.895440000000, 0.000000000000, -8.941673333334, 0.000000000000 },
                { 0.000000000000, 2.417800000000, 0.000000000000, 3.841615555556, 0.000000000000, 2.776283333333, 0.000000000000, 7.581878888889, 0.000000000000, -11.009537777778, 0.000000000000, -10.983371111111, 0.000000000000, -6.895440000000, 0.000000000000, -8.941673333334 },
                { -7.376906666667, 0.000000000000, -6.727973333334, 0.000000000000, -11.082804444445, 0.000000000000, -11.009537777778, 0.000000000000, 45.023413333334, 0.000000000000, 28.692622222223, 0.000000000000, 20.114142222223, 0.000000000000, 28.734488888889, 0.000000000000 },
                { 0.000000000000, -7.376906666667, 0.000000000000, -6.727973333334, 0.000000000000, -11.082804444445, 0.000000000000, -11.009537777778, 0.000000000000, 45.023413333334, 0.000000000000, 28.692622222223, 0.000000000000, 20.114142222223, 0.000000000000, 28.734488888889 },
                { -11.056637777778, 0.000000000000, -6.701806666667, 0.000000000000, -8.784673333334, 0.000000000000, -10.983371111111, 0.000000000000, 28.692622222223, 0.000000000000, 48.215746666667, 0.000000000000, 24.589688888889, 0.000000000000, 22.134208888889, 0.000000000000 },
                { 0.000000000000, -11.056637777778, 0.000000000000, -6.701806666667, 0.000000000000, -8.784673333334, 0.000000000000, -10.983371111111, 0.000000000000, 28.692622222223, 0.000000000000, 48.215746666667, 0.000000000000, 24.589688888889, 0.000000000000, 22.134208888889 },
                { -9.104604444445, 0.000000000000, -9.031337777778, 0.000000000000, -6.832640000000, 0.000000000000, -6.895440000000, 0.000000000000, 20.114142222223, 0.000000000000, 24.589688888889, 0.000000000000, 28.821013333334, 0.000000000000, 24.924622222223, 0.000000000000 },
                { 0.000000000000, -9.104604444445, 0.000000000000, -9.031337777778, 0.000000000000, -6.832640000000, 0.000000000000, -6.895440000000, 0.000000000000, 20.114142222223, 0.000000000000, 24.589688888889, 0.000000000000, 28.821013333334, 0.000000000000, 24.924622222223 },
                { -7.444940000000, 0.000000000000, -11.077571111111, 0.000000000000, -11.150837777778, 0.000000000000, -8.941673333334, 0.000000000000, 28.734488888889, 0.000000000000, 22.134208888889, 0.000000000000, 24.924622222223, 0.000000000000, 49.869480000000, 0.000000000000 },
                { 0.000000000000, -7.444940000000, 0.000000000000, -11.077571111111, 0.000000000000, -11.150837777778, 0.000000000000, -8.941673333334, 0.000000000000, 28.734488888889, 0.000000000000, 22.134208888889, 0.000000000000, 24.924622222223, 0.000000000000, 49.869480000000 }
            }); // from Abaqus

            Assert.True(M.Equals(expectedM, 1e-10));
        }
コード例 #10
0
        private static void TestConsistentMass0()
        {
            // reduced integration rule - bad idea
            IQuadrature2D quadratureForMass      = GaussLegendre2D.GetQuadratureWithOrder(1, 1);
            var           materialsAtGaussPoints = new List <ElasticMaterial2D>();

            foreach (GaussPoint gaussPoint in quadratureForMass.IntegrationPoints)
            {
                materialsAtGaussPoints.Add(material0.Clone());
            }
            var quad4 = new ContinuumElement2D(thickness, nodeSet1, InterpolationQuad4.UniqueInstance,
                                               GaussLegendre2D.GetQuadratureWithOrder(2, 2), quadratureForMass,
                                               ExtrapolationGaussLegendre2x2.UniqueInstance, materialsAtGaussPoints, dynamicMaterial);
            IMatrix M = quad4.BuildConsistentMassMatrix();

            Matrix expectedM = Matrix.CreateFromArray(new double[, ]
            {
                { 1, 0, 1, 0, 1, 0, 1, 0 },
                { 0, 1, 0, 1, 0, 1, 0, 1 },
                { 1, 0, 1, 0, 1, 0, 1, 0 },
                { 0, 1, 0, 1, 0, 1, 0, 1 },
                { 1, 0, 1, 0, 1, 0, 1, 0 },
                { 0, 1, 0, 1, 0, 1, 0, 1 },
                { 1, 0, 1, 0, 1, 0, 1, 0 },
                { 0, 1, 0, 1, 0, 1, 0, 1 }
            });
            double lengthX = nodeSet1[1].X - nodeSet1[0].X;
            double lengthY = nodeSet1[2].Y - nodeSet1[1].Y;

            // For some reason , only half the thickness is used for Quad4 elements, as shown in Fig. 31.9. Therefore the
            // coefficient 1/16 (full thickness) became 1/32 (half thickness). Here 1/16 is used.
            double scalar = dynamicMaterial.Density * thickness * lengthX * lengthY / 16.0;

            expectedM.ScaleIntoThis(scalar);

            Assert.True(M.Equals(expectedM, 1e-10));
        }
コード例 #11
0
        private IReadOnlyList <Matrix> GetN3ShapeFunctionsReorganized(IQuadrature2D quadrature, IReadOnlyList <double[]> N1)
        {
            //TODO reorganize cohesive shell  to use only N1 (not reorganised)

            int nGaussPoints = quadrature.IntegrationPoints.Count;
            var N3           = new Matrix[nGaussPoints]; // shapeFunctionsgpData

            for (int npoint = 0; npoint < nGaussPoints; npoint++)
            {
                double ksi  = quadrature.IntegrationPoints[npoint].Xi;
                double heta = quadrature.IntegrationPoints[npoint].Eta;
                var    N3gp = Matrix.CreateZero(3, 24); //8=nShapeFunctions;

                for (int l = 0; l < 3; l++)
                {
                    for (int m = 0; m < 8; m++)
                    {
                        N3gp[l, l + 3 * m] = N1[npoint][m];
                    }
                }
                N3[npoint] = N3gp;
            }
            return(N3);
        }
コード例 #12
0
        public Table <INode, IDofType, double> CalculateSurfaceLoad(IIsoparametricInterpolation2D interpolation,
                                                                    IQuadrature2D integration, IReadOnlyList <Node> nodes)
        {
            var loadTable = new Table <INode, IDofType, double>();
            IReadOnlyList <Matrix> shapeGradientsNatural =
                interpolation.EvaluateNaturalGradientsAtGaussPoints(integration);
            IReadOnlyList <double[]> shapeFunctionNatural =
                interpolation.EvaluateFunctionsAtGaussPoints(integration);

            for (int gp = 0; gp < integration.IntegrationPoints.Count; gp++)
            {
                var jacobianMatrix = Matrix.CreateZero(2, 3);
                for (int indexNode = 0; indexNode < nodes.Count; indexNode++)
                {
                    jacobianMatrix[0, 0] += shapeGradientsNatural[gp][indexNode, 0] * nodes[indexNode].X;
                    jacobianMatrix[0, 1] += shapeGradientsNatural[gp][indexNode, 0] * nodes[indexNode].Y;
                    jacobianMatrix[0, 2] += shapeGradientsNatural[gp][indexNode, 0] * nodes[indexNode].Z;

                    jacobianMatrix[1, 0] += shapeGradientsNatural[gp][indexNode, 1] * nodes[indexNode].X;
                    jacobianMatrix[1, 1] += shapeGradientsNatural[gp][indexNode, 1] * nodes[indexNode].Y;
                    jacobianMatrix[1, 2] += shapeGradientsNatural[gp][indexNode, 1] * nodes[indexNode].Z;
                }

                var tangentVector1 = jacobianMatrix.GetRow(0);
                var tangentVector2 = jacobianMatrix.GetRow(1);
                var normalVector   = tangentVector1.CrossProduct(tangentVector2);

                Vector surfaceBasisVector1 = Vector.CreateZero(3);
                surfaceBasisVector1[0] = jacobianMatrix[0, 0];
                surfaceBasisVector1[1] = jacobianMatrix[0, 1];
                surfaceBasisVector1[2] = jacobianMatrix[0, 2];

                Vector surfaceBasisVector2 = Vector.CreateZero(3);
                surfaceBasisVector2[0] = jacobianMatrix[1, 0];
                surfaceBasisVector2[1] = jacobianMatrix[1, 1];
                surfaceBasisVector2[2] = jacobianMatrix[1, 2];

                Vector surfaceBasisVector3 = surfaceBasisVector1.CrossProduct(surfaceBasisVector2);
                var    jacdet = surfaceBasisVector3.Norm2();

                var weightFactor = integration.IntegrationPoints[gp].Weight;
                for (int indexNode = 0; indexNode < nodes.Count; indexNode++)
                {
                    var node   = nodes[indexNode];
                    var valueX = _loadX * shapeFunctionNatural[gp][indexNode] * jacdet *
                                 weightFactor;
                    var valueY = _loadY * shapeFunctionNatural[gp][indexNode] * jacdet *
                                 weightFactor;
                    var valueZ = _loadZ * shapeFunctionNatural[gp][indexNode] * jacdet *
                                 weightFactor;
                    if (loadTable.Contains(node, StructuralDof.TranslationX))
                    {
                        loadTable[node, StructuralDof.TranslationX] += valueX;
                    }
                    else
                    {
                        loadTable.TryAdd(node, StructuralDof.TranslationX, valueX);
                    }

                    if (loadTable.Contains(node, StructuralDof.TranslationY))
                    {
                        loadTable[node, StructuralDof.TranslationY] += valueY;
                    }
                    else
                    {
                        loadTable.TryAdd(node, StructuralDof.TranslationY, valueY);
                    }

                    if (loadTable.Contains(node, StructuralDof.TranslationZ))
                    {
                        loadTable[node, StructuralDof.TranslationZ] += valueZ;
                    }
                    else
                    {
                        loadTable.TryAdd(node, StructuralDof.TranslationZ, valueZ);
                    }
                }
            }

            return(loadTable);
        }
コード例 #13
0
        /// <summary>
        /// See <see cref="IIsoparametricInterpolation2D.EvaluateAllAtGaussPoints(IReadOnlyList{Node}, IQuadrature2D)"/>.
        /// </summary>
        public IReadOnlyList <EvalInterpolation2D> EvaluateAllAtGaussPoints(IReadOnlyList <Node> nodes, IQuadrature2D quadrature)
        {
            // The shape functions and natural derivatives at each Gauss point are probably cached from previous calls
            IReadOnlyList <double[]> shapeFunctionsAtGPs          = EvaluateFunctionsAtGaussPoints(quadrature);
            IReadOnlyList <Matrix>   naturalShapeDerivativesAtGPs = EvaluateNaturalGradientsAtGaussPoints(quadrature);

            // Calculate the Jacobians and shape derivatives w.r.t. global cartesian coordinates at each Gauss point
            int numGPs = quadrature.IntegrationPoints.Count;
            var interpolationsAtGPs = new EvalInterpolation2D[numGPs];

            for (int gp = 0; gp < numGPs; ++gp)
            {
                interpolationsAtGPs[gp] = new EvalInterpolation2D(nodes, shapeFunctionsAtGPs[gp],
                                                                  naturalShapeDerivativesAtGPs[gp], new IsoparametricJacobian2D(nodes, naturalShapeDerivativesAtGPs[gp]));
            }
            return(interpolationsAtGPs);
        }
コード例 #14
0
 protected GaussPointExtrapolation2DBase(IQuadrature2D quadrature)
 {
     this.cachedExtrapolationFunctionsAtNodes = new Dictionary <IIsoparametricInterpolation2D, double[][]>();
     this.Quadrature = quadrature;
 }
コード例 #15
0
        private readonly IDofType[][] standardDofTypes; //TODO: this should not be stored for each element. Instead store it once for each Quad4, Tri3, etc. Otherwise create it on the fly.

        public XContinuumElement2D(int id, IReadOnlyList <XNode> nodes, IIsoparametricInterpolation2D interpolation,
                                   IGaussPointExtrapolation2D gaussPointExtrapolation, IQuadrature2D standardQuadrature,
                                   IIntegrationStrategy2D <XContinuumElement2D> integrationStrategy,
                                   IIntegrationStrategy2D <XContinuumElement2D> jIntegralStrategy, IMaterialField2D material)
        {
            this.id                      = id;
            this.Nodes                   = nodes;
            this.Interpolation           = interpolation;
            this.GaussPointExtrapolation = gaussPointExtrapolation;
            this.StandardQuadrature      = standardQuadrature;
            this.IntegrationStrategy     = integrationStrategy;
            this.JintegralStrategy       = jIntegralStrategy;
            this.Material                = material;

            this.NumStandardDofs = 2 * nodes.Count;
            standardDofTypes     = new IDofType[nodes.Count][];
            for (int i = 0; i < nodes.Count; ++i)
            {
                standardDofTypes[i] = new IDofType[] { StructuralDof.TranslationX, StructuralDof.TranslationY };
            }

            //OBSOLETE: Elements access their enrichments from nodes now.
            //this.EnrichmentItems = new List<IEnrichmentItem2D>();
        }
コード例 #16
0
        private static void TestConsistentMassParametric(IReadOnlyList <Node> nodeSet, IQuadrature2D quadratureForMass,
                                                         bool reducedQuadrature)
        {
            var materialsAtGaussPoints = new List <IContinuumMaterial2D>();

            foreach (GaussPoint gaussPoint in quadratureForMass.IntegrationPoints)
            {
                materialsAtGaussPoints.Add(material0.Clone());
            }
            var tri3 = new ContinuumElement2D(thickness, nodeSet, InterpolationTri3.UniqueInstance,
                                              TriangleQuadratureSymmetricGaussian.Order1Point1, quadratureForMass,
                                              ExtrapolationGaussTriangular1Point.UniqueInstance,
                                              materialsAtGaussPoints, dynamicMaterial);
            IMatrix M = tri3.BuildConsistentMassMatrix();

            // Reference: http://kis.tu.kielce.pl/mo/COLORADO_FEM/colorado/IFEM.Ch31.pdf, (eq 31.27)
            Matrix expectedM = Matrix.CreateFromArray(new double[, ]
            {
                { 2, 0, 1, 0, 1, 0 },
                { 0, 2, 0, 1, 0, 1 },
                { 1, 0, 2, 0, 1, 0 },
                { 0, 1, 0, 2, 0, 1 },
                { 1, 0, 1, 0, 2, 0 },
                { 0, 1, 0, 1, 0, 2 }
            });
            double area   = CalcTriangleArea(nodeSet);
            double scalar = dynamicMaterial.Density * thickness * area / 12.0;

            expectedM.ScaleIntoThis(scalar);

            if (reducedQuadrature)
            {
                Assert.False(M.Equals(expectedM, 1e-10));
            }
            else
            {
                Assert.True(M.Equals(expectedM, 1e-10));
            }
        }
コード例 #17
0
        public Table <INode, IDofType, double> CalculateSurfaceLoad(IIsoparametricInterpolation2D interpolation, IQuadrature2D integration, IReadOnlyList <Node> nodes)
        {
            int numDofs   = nodes.Count;
            var stiffness = Vector.CreateZero(numDofs);
            IReadOnlyList <double[]> shapeFunctions =
                interpolation.EvaluateFunctionsAtGaussPoints(integration);
            IReadOnlyList <Matrix> shapeGradientsNatural =
                interpolation.EvaluateNaturalGradientsAtGaussPoints(integration);

            for (int gp = 0; gp < integration.IntegrationPoints.Count; ++gp)
            {
                Vector shapeFunctionVector = Vector.CreateFromArray(shapeFunctions[gp]);
                Matrix jacobianMatrix      = Matrix.CreateZero(2, 3);
                for (int k = 0; k < nodes.Count; k++)
                {
                    jacobianMatrix[0, 0] += shapeGradientsNatural[gp][k, 0] * nodes[k].X;
                    jacobianMatrix[0, 1] += shapeGradientsNatural[gp][k, 0] * nodes[k].Y;
                    jacobianMatrix[0, 2] += shapeGradientsNatural[gp][k, 0] * nodes[k].Z;
                    jacobianMatrix[1, 0] += shapeGradientsNatural[gp][k, 1] * nodes[k].X;
                    jacobianMatrix[1, 1] += shapeGradientsNatural[gp][k, 1] * nodes[k].Y;
                    jacobianMatrix[1, 2] += shapeGradientsNatural[gp][k, 1] * nodes[k].Z;
                }
                Vector tangentVector1 = jacobianMatrix.GetRow(0);
                Vector tangentVector2 = jacobianMatrix.GetRow(1);
                Vector normalVector   = tangentVector1.CrossProduct(tangentVector2);

                var jacdet = normalVector.Norm2();

                double dA = jacdet * integration.IntegrationPoints[gp].Weight;
                stiffness.AxpyIntoThis(shapeFunctionVector, dA);
            }
            var appliedDisplacements = Vector.CreateWithValue(nodes.Count, _flux);
            var fluxLoad             = stiffness.DoEntrywise(appliedDisplacements, (stiffi, appi) => stiffi * appi);
            var table = new Table <INode, IDofType, double>();

            for (int i = 0; i < nodes.Count; i++)
            {
                table.TryAdd(nodes[i], ThermalDof.Temperature, fluxLoad[i]);
            }
            return(table);
        }
コード例 #18
0
        public Table <INode, IDofType, double> CalculateSurfaceLoad(IIsoparametricInterpolation2D interpolation, IQuadrature2D integration, IReadOnlyList <Node> nodes)
        {
            //nodes[0].ElementsDictionary.Values.ToList<>
            int    numDofs = nodes.Count;
            double kappaCoef;

            if (numDofs == 4)
            {
                kappaCoef = 100;
            }
            else
            {
                kappaCoef = 1;
            }
            var stiffness = Matrix.CreateZero(numDofs, numDofs);
            IReadOnlyList <double[]> shapeFunctions =
                interpolation.EvaluateFunctionsAtGaussPoints(integration);
            IReadOnlyList <Matrix> shapeGradientsNatural =
                interpolation.EvaluateNaturalGradientsAtGaussPoints(integration);

            double[]     dist          = new double[nodes.Count];
            List <INode> neighborNodes = new List <INode>();

            for (int i = 0; i < nodes.Count; i++)
            {
                neighborNodes.Clear();
                foreach (var element in nodes[i].ElementsDictionary.Values)
                {
                    neighborNodes.AddRange(element.Nodes);
                }
                neighborNodes = neighborNodes.Distinct().ToList();
                neighborNodes.Remove(nodes[i]);
                var minDist = neighborNodes.Select(x => Math.Sqrt(
                                                       Math.Pow(nodes[i].X - x.X, 2) +
                                                       Math.Pow(nodes[i].Y - x.Y, 2) + Math.Pow(nodes[i].Z - x.Z, 2))).Min();
                dist[i] = minDist;
            }
            //double kappa = kappaCoef * _diffusionCoeff / dist.Min();
            //double[] kappa = new double[nodes.Count];
            for (int gp = 0; gp < integration.IntegrationPoints.Count; ++gp)
            {
                //var jacobian = new IsoparametricJacobian3D(Nodes, shapeGradientsNatural[gp]);

                var    shapeFunctionMatrix = Vector.CreateFromArray(shapeFunctions[gp]);
                Matrix jacobianMatrix      = Matrix.CreateZero(2, 3);
                for (int k = 0; k < nodes.Count; k++)
                {
                    //xGaussPoint += shapeFunctionMatrix[gp, k] * this.Nodes[k].X;
                    //yGaussPoint += shapeFunctionMatrix[gp, k] * this.Nodes[k].Y;
                    //zGaussPoint += shapeFunctionMatrix[gp, k] * this.Nodes[k].Z;
                    jacobianMatrix[0, 0] += shapeGradientsNatural[gp][k, 0] * nodes[k].X;
                    jacobianMatrix[0, 1] += shapeGradientsNatural[gp][k, 0] * nodes[k].Y;
                    jacobianMatrix[0, 2] += shapeGradientsNatural[gp][k, 0] * nodes[k].Z;
                    jacobianMatrix[1, 0] += shapeGradientsNatural[gp][k, 1] * nodes[k].X;
                    jacobianMatrix[1, 1] += shapeGradientsNatural[gp][k, 1] * nodes[k].Y;
                    jacobianMatrix[1, 2] += shapeGradientsNatural[gp][k, 1] * nodes[k].Z;
                    //kappa[k] = _diffusionCoeff / .05 / dist[k];
                }
                Vector tangentVector1 = jacobianMatrix.GetRow(0);
                Vector tangentVector2 = jacobianMatrix.GetRow(1);
                Vector normalVector   = tangentVector1.CrossProduct(tangentVector2);
                var    jacdet         = normalVector.Norm2();
                normalVector.ScaleIntoThis(1 / jacdet);
                Matrix jacobianMatrixLeftInverse = jacobianMatrix.Transpose() *
                                                   (jacobianMatrix * jacobianMatrix.Transpose()).Invert();
                Matrix shapeGradientsCartesian = (shapeGradientsNatural[gp]) * jacobianMatrixLeftInverse.Transpose();
                Matrix deformation             = shapeGradientsCartesian.Transpose();
                Vector deformationNormal       = normalVector * deformation;
                //Vector deformationX = deformation.GetRow(0);
                //Vector deformationY = deformation.GetRow(1);
                //Vector deformationZ = deformation.GetRow(2);
                //Matrix partial = kappa * shapeFunctionMatrix.TensorProduct(shapeFunctionMatrix)
                //    -_diffusionCoeff * deformationNormal.TensorProduct(shapeFunctionMatrix);
                double kappa   = _diffusionCoeff / .05;
                Matrix partial = kappa * shapeFunctionMatrix.TensorProduct(shapeFunctionMatrix);

                //Vector surfaceBasisVector1 = Vector.CreateZero(3);
                //surfaceBasisVector1[0] = jacobianMatrix[0, 0];
                //surfaceBasisVector1[1] = jacobianMatrix[0, 1];
                //surfaceBasisVector1[2] = jacobianMatrix[0, 2];

                //Vector surfaceBasisVector2 = Vector.CreateZero(3);
                //surfaceBasisVector2[0] = jacobianMatrix[1, 0];
                //surfaceBasisVector2[1] = jacobianMatrix[1, 1];
                //surfaceBasisVector2[2] = jacobianMatrix[1, 2];

                //Vector surfaceBasisVector3 = surfaceBasisVector1.CrossProduct(surfaceBasisVector2);
                //var jacdet = surfaceBasisVector3.Norm2();

                double dA = jacdet * integration.IntegrationPoints[gp].Weight;
                stiffness.AxpyIntoThis(partial, dA);
            }
            //var appliedDisplacements=Vector.CreateWithValue(nodes.Count, _magnitude);
            var appliedDisplacements = _distribution(nodes);
            var weakDirichletForces  = stiffness * appliedDisplacements;

            var table = new Table <INode, IDofType, double>();

            for (int i = 0; i < nodes.Count; i++)
            {
                table.TryAdd(nodes[i], ThermalDof.Temperature, weakDirichletForces[i]);
            }
            return(table);
        }