예제 #1
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);
        }
예제 #2
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);
        }
예제 #3
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);
        }
예제 #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);
        }
예제 #5
0
        public Table <INode, IDofType, double> CalculateBodyLoad(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]);
                var jacdet   = jacobian.DirectDeterminant;

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

            return(loadTable);
        }
        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);
        }
예제 #7
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));
        }
예제 #8
0
        public double CalculateVolume()
        {
            //TODO: Linear elements can use the more efficient rules for volume of polygons. Therefore this method should be
            //      delegated to the interpolation.
            //TODO: A different integration rule should be used for integrating constant functions. For linear elements there
            //      is only 1 Gauss point (most probably), therefore the computational cost could be the same as using the
            //      polygonal formulas.
            double volume = 0.0;
            IReadOnlyList <Matrix> shapeGradientsNatural =
                Interpolation.EvaluateNaturalGradientsAtGaussPoints(QuadratureForStiffness);

            for (int gp = 0; gp < QuadratureForStiffness.IntegrationPoints.Count; ++gp)
            {
                var jacobian = new IsoparametricJacobian3D(Nodes, shapeGradientsNatural[gp]);
                volume += jacobian.DirectDeterminant * QuadratureForStiffness.IntegrationPoints[gp].Weight;                 //TODO: this is used by all methods that integrate. I should cache it.
            }
            return(volume);
        }
예제 #9
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);
        }
예제 #10
0
        public Matrix BuildConsistentMassMatrix()
        {
            int numberOfDofs = 3 * Nodes.Count;
            var mass         = Matrix.CreateZero(numberOfDofs, numberOfDofs);
            IReadOnlyList <double[]> shapeFunctions =
                Interpolation.EvaluateFunctionsAtGaussPoints(QuadratureForConsistentMass);
            IReadOnlyList <Matrix> shapeGradientsNatural =
                Interpolation.EvaluateNaturalGradientsAtGaussPoints(QuadratureForConsistentMass);

            for (int gp = 0; gp < QuadratureForConsistentMass.IntegrationPoints.Count; ++gp)
            {
                Matrix shapeFunctionMatrix = BuildShapeFunctionMatrix(shapeFunctions[gp]);
                Matrix partial             = shapeFunctionMatrix.MultiplyRight(shapeFunctionMatrix, true, false);
                var    jacobian            = new IsoparametricJacobian3D(Nodes, shapeGradientsNatural[gp]);
                double dA = jacobian.DirectDeterminant * QuadratureForConsistentMass.IntegrationPoints[gp].Weight;
                mass.AxpyIntoThis(partial, dA);
            }
            mass.ScaleIntoThis(dynamicProperties.Density);
            return(mass);
        }
예제 #11
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());
        }
예제 #12
0
        public Matrix BuildCapacityMatrix()
        {
            int numDofs  = Nodes.Count;
            var capacity = Matrix.CreateZero(numDofs, numDofs);
            IReadOnlyList <double[]> shapeFunctions =
                Interpolation.EvaluateFunctionsAtGaussPoints(QuadratureForConsistentMass);
            IReadOnlyList <Matrix> shapeGradientsNatural =
                Interpolation.EvaluateNaturalGradientsAtGaussPoints(QuadratureForConsistentMass);

            for (int gp = 0; gp < QuadratureForConsistentMass.IntegrationPoints.Count; ++gp)
            {
                Vector shapeFunctionMatrix = BuildShapeFunctionMatrix(shapeFunctions[gp]);
                Matrix partial             = shapeFunctionMatrix.TensorProduct(shapeFunctionMatrix);
                var    jacobian            = new IsoparametricJacobian3D(Nodes, shapeGradientsNatural[gp]);
                double dA = jacobian.DirectDeterminant * QuadratureForConsistentMass.IntegrationPoints[gp].Weight;
                capacity.AxpyIntoThis(partial, dA * material.CapacityCoeff);
            }

            //WARNING: the following needs to change for non uniform density. Perhaps the integration order too.
            return(capacity);
        }
예제 #13
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);
        }
예제 #14
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));
        }
예제 #15
0
        public Matrix BuildConvectionMatrix()
        {
            int numDofs    = Nodes.Count;
            var convection = Matrix.CreateZero(numDofs, numDofs);
            IReadOnlyList <double[]> shapeFunctions =
                Interpolation.EvaluateFunctionsAtGaussPoints(QuadratureForConsistentMass);
            IReadOnlyList <Matrix> shapeGradientsNatural =
                Interpolation.EvaluateNaturalGradientsAtGaussPoints(QuadratureForConsistentMass);

            for (int gp = 0; gp < QuadratureForConsistentMass.IntegrationPoints.Count; ++gp)
            {
                Matrix shapeFunctionMatrix = BuildShapeFunctionMatrix(shapeFunctions[gp]);
                Matrix partial             = shapeFunctionMatrix.Transpose() * shapeFunctionMatrix;
                var    jacobian            = new IsoparametricJacobian3D(Nodes, shapeGradientsNatural[gp]);
                double dA = jacobian.DirectDeterminant * QuadratureForConsistentMass.IntegrationPoints[gp].Weight;
                convection.AxpyIntoThis(partial, dA);
            }

            //WARNING: the following needs to change for non uniform density. Perhaps the integration order too.
            convection.Scale(thermalMaterial.ThermalConvection);
            return(convection);
        }
예제 #16
0
        public Matrix BuildLumpedMassMatrix()
        {
            int numberOfDofs = 3 * Nodes.Count;
            var lumpedMass   = Matrix.CreateZero(numberOfDofs, numberOfDofs);
            IReadOnlyList <Matrix> shapeGradientsNatural =
                Interpolation.EvaluateNaturalGradientsAtGaussPoints(QuadratureForConsistentMass);

            double area = 0;

            for (int gp = 0; gp < QuadratureForConsistentMass.IntegrationPoints.Count; ++gp)
            {
                var jacobian = new IsoparametricJacobian3D(Nodes, shapeGradientsNatural[gp]);
                area += jacobian.DirectDeterminant * QuadratureForConsistentMass.IntegrationPoints[gp].Weight;
            }

            double nodalMass = area * dynamicProperties.Density / Nodes.Count;

            for (int i = 0; i < numberOfDofs; i++)
            {
                lumpedMass[i, i] = nodalMass;
            }

            return(lumpedMass);
        }