Пример #1
0
        public Matrix BuildMassTransportConductivityMatrix()
        {
            int numDofs    = Nodes.Count;
            var convection = Matrix.CreateZero(numDofs, numDofs);
            IReadOnlyList <double[]> shapeFunctions =
                Interpolation.EvaluateFunctionsAtGaussPoints(QuadratureForStiffness);
            IReadOnlyList <Matrix> shapeGradientsNatural =
                Interpolation.EvaluateNaturalGradientsAtGaussPoints(QuadratureForStiffness);

            for (int gp = 0; gp < QuadratureForStiffness.IntegrationPoints.Count; ++gp)
            {
                var    jacobian                = new IsoparametricJacobian3D(Nodes, shapeGradientsNatural[gp]);
                Vector shapeFunctionMatrix     = BuildShapeFunctionMatrix(shapeFunctions[gp]);
                Matrix shapeGradientsCartesian =
                    jacobian.TransformNaturalDerivativesToCartesian(shapeGradientsNatural[gp]);
                Matrix deformation  = BuildDeformationMatrix(shapeGradientsCartesian);
                Vector deformationX = deformation.GetRow(0);
                Vector deformationY = deformation.GetRow(1);
                Vector deformationZ = deformation.GetRow(2);
                Matrix partialK     = shapeFunctionMatrix.TensorProduct(deformationX) * material.ConvectionCoeff[0] +
                                      shapeFunctionMatrix.TensorProduct(deformationY) * material.ConvectionCoeff[1] +
                                      shapeFunctionMatrix.TensorProduct(deformationZ) * material.ConvectionCoeff[2];
                double dA = jacobian.DirectDeterminant * QuadratureForStiffness.IntegrationPoints[gp].Weight;
                convection.AxpyIntoThis(partialK, dA);
            }

            //WARNING: the following needs to change for non uniform density. Perhaps the integration order too.
            //convection.Scale(1);
            return(convection);
        }
Пример #2
0
        public Matrix BuildDiffusionConductivityMatrix()
        {
            int numDofs      = Nodes.Count;
            var conductivity = Matrix.CreateZero(numDofs, numDofs);
            IReadOnlyList <Matrix> shapeGradientsNatural =
                Interpolation.EvaluateNaturalGradientsAtGaussPoints(QuadratureForStiffness);

            for (int gp = 0; gp < QuadratureForStiffness.IntegrationPoints.Count; ++gp)
            {
                // Calculate the necessary quantities for the integration
                var    jacobian = new IsoparametricJacobian3D(Nodes, shapeGradientsNatural[gp]);
                Matrix shapeGradientsCartesian =
                    jacobian.TransformNaturalDerivativesToCartesian(shapeGradientsNatural[gp]);
                Matrix deformation = BuildDeformationMatrix(shapeGradientsCartesian);

                // Contribution of this gauss point to the element stiffness matrix
                Matrix partialK = deformation.Transpose() * deformation;
                //Matrix partialΚ = deformation.Transpose() * (constitutive * deformation);
                //partialK.Scale(materialsAtGaussPoints[gaussPoint].ThermalConductivity);

                double dA = jacobian.DirectDeterminant * QuadratureForStiffness.IntegrationPoints[gp].Weight; //TODO: this is used by all methods that integrate. I should cache it.
                conductivity.AxpyIntoThis(partialK, dA * material.DiffusionCoeff);
                //conductivity.AxpyIntoThis(partialK, dA * 1);
            }

            //conductivity.Scale(1);
            return(conductivity);
        }
Пример #3
0
        public IReadOnlyList <Matrix> BuildSecondSpaceDerivativeMatrix()
        {
            int numDofs = Nodes.Count;
            var secondDerivativeMatrix = new List <Matrix>();

            for (int i = 0; i < 3; i++)
            {
                secondDerivativeMatrix.Add(Matrix.CreateZero(numDofs, numDofs));
            }
            IReadOnlyList <Matrix> shapeGradientsNatural =
                Interpolation.EvaluateNaturalGradientsAtGaussPoints(QuadratureForStiffness);

            for (int gp = 0; gp < QuadratureForStiffness.IntegrationPoints.Count; ++gp)
            {
                var    jacobian = new IsoparametricJacobian3D(Nodes, shapeGradientsNatural[gp]);
                Matrix shapeGradientsCartesian =
                    jacobian.TransformNaturalDerivativesToCartesian(shapeGradientsNatural[gp]);
                Matrix deformation  = BuildDeformationMatrix(shapeGradientsCartesian);
                Vector deformationX = deformation.GetRow(0);
                Vector deformationY = deformation.GetRow(1);
                Vector deformationZ = deformation.GetRow(2);
                Matrix partialKX    = deformationX.TensorProduct(deformationX);
                Matrix partialKY    = deformationY.TensorProduct(deformationY);
                Matrix partialKZ    = deformationZ.TensorProduct(deformationZ);
                double dA           = jacobian.DirectDeterminant * QuadratureForStiffness.IntegrationPoints[gp].Weight;
                secondDerivativeMatrix[0].AxpyIntoThis(partialKX, -dA);
                secondDerivativeMatrix[1].AxpyIntoThis(partialKY, -dA);
                secondDerivativeMatrix[2].AxpyIntoThis(partialKZ, -dA);
            }

            //WARNING: the following needs to change for non uniform density. Perhaps the integration order too.
            //convection.Scale(1);
            return(secondDerivativeMatrix);
        }
Пример #4
0
        public IReadOnlyList <Matrix> BuildFirstSpaceDerivativeMatrix()
        {
            int numDofs = Nodes.Count;
            var firstDerivativeMatrix = new List <Matrix>();

            for (int i = 0; i < 3; i++)
            {
                firstDerivativeMatrix.Add(Matrix.CreateZero(numDofs, numDofs));
            }
            IReadOnlyList <double[]> shapeFunctions =
                Interpolation.EvaluateFunctionsAtGaussPoints(QuadratureForStiffness);
            IReadOnlyList <Matrix> shapeGradientsNatural =
                Interpolation.EvaluateNaturalGradientsAtGaussPoints(QuadratureForStiffness);

            for (int gp = 0; gp < QuadratureForStiffness.IntegrationPoints.Count; ++gp)
            {
                Vector shapeFunctionMatrix     = BuildShapeFunctionMatrix(shapeFunctions[gp]);
                var    jacobian                = new IsoparametricJacobian3D(Nodes, shapeGradientsNatural[gp]);
                Matrix shapeGradientsCartesian =
                    jacobian.TransformNaturalDerivativesToCartesian(shapeGradientsNatural[gp]);
                Matrix deformation  = BuildDeformationMatrix(shapeGradientsCartesian);
                Vector deformationX = deformation.GetRow(0);
                Vector deformationY = deformation.GetRow(1);
                Vector deformationZ = deformation.GetRow(2);
                Matrix partialKX    = shapeFunctionMatrix.TensorProduct(deformationX);
                Matrix partialKY    = shapeFunctionMatrix.TensorProduct(deformationY);
                Matrix partialKZ    = shapeFunctionMatrix.TensorProduct(deformationZ);
                double dA           = jacobian.DirectDeterminant * QuadratureForStiffness.IntegrationPoints[gp].Weight;
                firstDerivativeMatrix[0].AxpyIntoThis(partialKX, -dA);
                firstDerivativeMatrix[1].AxpyIntoThis(partialKY, -dA);
                firstDerivativeMatrix[2].AxpyIntoThis(partialKZ, -dA);
            }

            return(firstDerivativeMatrix);
        }
        public Table <INode, IDofType, double> CalculateStabilizingBodyLoad(IIsoparametricInterpolation3D interpolation, IQuadrature3D 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    jacobian = new IsoparametricJacobian3D(nodes, shapeGradientsNatural[gp]);
                Matrix shapeGradientsCartesian =
                    jacobian.TransformNaturalDerivativesToCartesian(shapeGradientsNatural[gp]);
                //TODO: isn't this just the transpose of [dNi/dxj]?
                var deformation = Matrix.CreateZero(3, nodes.Count);
                for (int nodeIdx = 0; nodeIdx < nodes.Count; ++nodeIdx)
                {
                    deformation[0, nodeIdx] = shapeGradientsCartesian[nodeIdx, 0];
                    deformation[1, nodeIdx] = shapeGradientsCartesian[nodeIdx, 1];
                    deformation[2, nodeIdx] = shapeGradientsCartesian[nodeIdx, 2];
                }
                Vector deformationX = deformation.GetRow(0);
                Vector deformationY = deformation.GetRow(1);
                Vector deformationZ = deformation.GetRow(2);
                Vector partialK     = deformationX.Scale(_material.ConvectionCoeff[0]) +
                                      deformationY.Scale(_material.ConvectionCoeff[1]) +
                                      deformationZ.Scale(_material.ConvectionCoeff[2]);
                //loadTable.AxpyIntoThis(partialK, dA);

                var weightFactor = integration.IntegrationPoints[gp].Weight;
                for (int indexNode = 0; indexNode < nodes.Count; indexNode++)
                {
                    var node   = nodes[indexNode];
                    var valueX = -0.5 * _load * partialK[indexNode] * jacobian.DirectDeterminant *
                                 weightFactor;
                    if (loadTable.Contains(node, _dofType))
                    {
                        loadTable[node, _dofType] += valueX;
                    }
                    else
                    {
                        loadTable.TryAdd(node, _dofType, valueX);
                    }
                }
            }

            return(loadTable);
        }
Пример #6
0
        public Tuple <double[], double[]> CalculateStresses(IElement element, double[] localDisplacements,
                                                            double[] localdDisplacements)
        {
            int numberOfDofs = 3 * Nodes.Count;
            var Forces       = Vector.CreateZero(numberOfDofs);
            IReadOnlyList <Matrix> shapeGradientsNatural =
                Interpolation.EvaluateNaturalGradientsAtGaussPoints(QuadratureForStiffness);

            //double[] strains = new double[6];
            //for (int gp = 0; gp < QuadratureForStiffness.IntegrationPoints.Count; ++gp)
            //{
            //	strains = new double[6];
            //	var jacobian = new IsoparametricJacobian3D(Nodes, shapeGradientsNatural[gp]);
            //	Matrix shapeGradientsCartesian =
            //		jacobian.TransformNaturalDerivativesToCartesian(shapeGradientsNatural[gp]);
            //	Matrix deformation = BuildDeformationMatrix(shapeGradientsCartesian);
            //	strains = deformation.Multiply(localDisplacements);
            //	materialsAtGaussPoints[gp].UpdateMaterial(strains);
            //}

            //double[] strains = new double[6];
            double[] strainsVecMinusLastConvergedValue = new double[6];
            for (int gpo = 0; gpo < QuadratureForStiffness.IntegrationPoints.Count; ++gpo)
            {
                //strainsVec[gpo] = new double[6];
                var    jacobian = new IsoparametricJacobian3D(Nodes, shapeGradientsNatural[gpo]);
                Matrix shapeGradientsCartesian =
                    jacobian.TransformNaturalDerivativesToCartesian(shapeGradientsNatural[gpo]);
                Matrix deformation = BuildDeformationMatrix(shapeGradientsCartesian);
                strainsVec[gpo] = deformation.Multiply(localDisplacements);
                strainsVecMinusLastConvergedValue = new double[6]
                {
                    strainsVec[gpo][0] - strainsVecLastConverged[gpo][0],
                    strainsVec[gpo][1] - strainsVecLastConverged[gpo][1],
                    strainsVec[gpo][2] - strainsVecLastConverged[gpo][2],
                    strainsVec[gpo][3] - strainsVecLastConverged[gpo][3],
                    strainsVec[gpo][4] - strainsVecLastConverged[gpo][4],
                    strainsVec[gpo][5] - strainsVecLastConverged[gpo][5]
                };
                materialsAtGaussPoints[gpo].UpdateMaterial(strainsVecMinusLastConvergedValue);
                //To update with total strain simplY = materialsAtGaussPoints[npoint].UpdateMaterial(strainsVec[npoint]);
            }


            return(new Tuple <double[], double[]>(strainsVec[materialsAtGaussPoints.Count - 1], materialsAtGaussPoints[materialsAtGaussPoints.Count - 1].Stresses));
        }
Пример #7
0
        public EvalInterpolation3D(IReadOnlyList <Node> elementNodes, double[] shapeFunctions, Matrix shapeGradientsNatural,
                                   IsoparametricJacobian3D jacobian)
        {
            int numNodes = elementNodes.Count;

#if DEBUG
            if ((shapeFunctions.Length != numNodes) || (shapeGradientsNatural.NumRows != numNodes))
            {
                throw new ArgumentException($"There are {numNodes} nodes, but {ShapeFunctions.Length} shape functions"
                                            + $" and {shapeGradientsNatural.NumRows} natural shape derivatives.");
            }
#endif
            this.elementNodes          = elementNodes;
            this.ShapeFunctions        = shapeFunctions;
            this.ShapeGradientsNatural = shapeGradientsNatural;
            this.Jacobian = jacobian;
            this.ShapeGradientsCartesian = jacobian.TransformNaturalDerivativesToCartesian(shapeGradientsNatural);
        }
Пример #8
0
        public double[] CalculateForces(IElement element, double[] localTotalDisplacements, double[] localDisplacements)
        {
            int numberOfDofs = 3 * Nodes.Count;
            var Forces       = Vector.CreateZero(numberOfDofs);
            IReadOnlyList <Matrix> shapeGradientsNatural =
                Interpolation.EvaluateNaturalGradientsAtGaussPoints(QuadratureForStiffness);

            for (int gp = 0; gp < QuadratureForStiffness.IntegrationPoints.Count; ++gp)
            {
                Vector Stresses = Vector.CreateFromArray(materialsAtGaussPoints[gp].Stresses);
                var    jacobian = new IsoparametricJacobian3D(Nodes, shapeGradientsNatural[gp]);
                Matrix shapeGradientsCartesian =
                    jacobian.TransformNaturalDerivativesToCartesian(shapeGradientsNatural[gp]);
                Matrix deformation = BuildDeformationMatrix(shapeGradientsCartesian);
                Vector gpForces    = deformation.Transpose() * (Stresses);
                double dA          = jacobian.DirectDeterminant * QuadratureForStiffness.IntegrationPoints[gp].Weight;
                gpForces.ScaleIntoThis(dA);
                Forces.AddIntoThis(gpForces);
            }
            return(Forces.CopyToArray());
        }
Пример #9
0
        UpdateStrainStressesAtGaussPoints(double[] localDisplacements)
        {
            int numberOfGPs = QuadratureForStiffness.IntegrationPoints.Count;
            var strains     = new double[numberOfGPs][];
            var stresses    = new double[numberOfGPs][];
            IReadOnlyList <Matrix> shapeGradientsNatural =
                Interpolation.EvaluateNaturalGradientsAtGaussPoints(QuadratureForStiffness);

            for (int gp = 0; gp < numberOfGPs; gp++)
            {
                IMatrixView constitutive             = materialsAtGaussPoints[gp].ConstitutiveMatrix;
                var         jacobian                 = new IsoparametricJacobian3D(Nodes, shapeGradientsNatural[gp]);
                Matrix      shapeGrandientsCartesian =
                    jacobian.TransformNaturalDerivativesToCartesian(shapeGradientsNatural[gp]);
                Matrix deformation = BuildDeformationMatrix(shapeGrandientsCartesian);

                strains[gp]  = deformation.Multiply(localDisplacements);
                stresses[gp] = constitutive.Multiply(strains[gp]);
            }

            return(strains, stresses);
        }
Пример #10
0
        public IMatrix BuildStiffnessMatrix()
        {
            int numberOfDofs = 3 * Nodes.Count;
            var stiffness    = Matrix.CreateZero(numberOfDofs, numberOfDofs);
            IReadOnlyList <Matrix> shapeGradientsNatural =
                Interpolation.EvaluateNaturalGradientsAtGaussPoints(QuadratureForStiffness);

            for (int gp = 0; gp < QuadratureForStiffness.IntegrationPoints.Count; ++gp)
            {
                IMatrixView constitutive            = materialsAtGaussPoints[gp].ConstitutiveMatrix;
                var         jacobian                = new IsoparametricJacobian3D(Nodes, shapeGradientsNatural[gp]);
                Matrix      shapeGradientsCartesian =
                    jacobian.TransformNaturalDerivativesToCartesian(shapeGradientsNatural[gp]);
                Matrix deformation = BuildDeformationMatrix(shapeGradientsCartesian);

                Matrix partial = deformation.ThisTransposeTimesOtherTimesThis(constitutive);
                double dA      = jacobian.DirectDeterminant * QuadratureForStiffness.IntegrationPoints[gp].Weight;
                stiffness.AxpyIntoThis(partial, dA);
            }

            return(DofEnumerator.GetTransformedMatrix(stiffness));
        }