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); }
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); }
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); }
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); }
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)); }
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); }
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()); }
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); }
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)); }