/// <summary> /// Calculates a tensor quantity at the nodes of a finite element by extrapolating its known values at the integration /// points. /// </summary> /// <param name="tensorsAtGaussPoints">Their order must be the same as the order of integration points defined by /// <see cref="Quadrature"/>.</param> /// <param name="interpolation">Defines the natural coordinates of the finite element's nodes.</param> /// <returns></returns> public IReadOnlyList <double[]> ExtrapolateTensorFromGaussPointsToNodes( IReadOnlyList <double[]> tensorsAtGaussPoints, IIsoparametricInterpolation3D interpolation) { double[][] nodalExtrapolationFunctions = EvaluateExtrapolationFunctionsAtNodes(interpolation); IReadOnlyList <NaturalPoint> nodes = interpolation.NodalNaturalCoordinates; var nodalTensors = new double[nodes.Count][]; for (int i = 0; i < nodes.Count; i++) { var tensor = new double[6]; for (int gp = 0; gp < Quadrature.IntegrationPoints.Count; gp++) { tensor[0] += nodalExtrapolationFunctions[i][gp] * tensorsAtGaussPoints[gp][0]; tensor[1] += nodalExtrapolationFunctions[i][gp] * tensorsAtGaussPoints[gp][1]; tensor[2] += nodalExtrapolationFunctions[i][gp] * tensorsAtGaussPoints[gp][2]; tensor[3] += nodalExtrapolationFunctions[i][gp] * tensorsAtGaussPoints[gp][3]; tensor[4] += nodalExtrapolationFunctions[i][gp] * tensorsAtGaussPoints[gp][4]; tensor[5] += nodalExtrapolationFunctions[i][gp] * tensorsAtGaussPoints[gp][5]; } nodalTensors[i] = tensor; } return(nodalTensors); }
public ContinuumElement3D(IReadOnlyList <Node> nodes, IIsoparametricInterpolation3D interpolation, IQuadrature3D quadratureForStiffness, IQuadrature3D quadratureForMass, IGaussPointExtrapolation3D gaussPointExtrapolation, IReadOnlyList <IContinuumMaterial3D> materialsAtGaussPoints, IDynamicMaterial dynamicProperties) { this.dynamicProperties = dynamicProperties; this.materialsAtGaussPoints = materialsAtGaussPoints; this.GaussPointExtrapolation = gaussPointExtrapolation; this.Nodes = nodes; this.Interpolation = interpolation; this.QuadratureForConsistentMass = quadratureForMass; //this.nGaussPoints = quadratureForStiffness.IntegrationPoints.Count; this.QuadratureForStiffness = quadratureForStiffness; //materialsAtGaussPoints = new IContinuumMaterial3D[nGaussPoints]; //for (int i = 0; i < nGaussPoints; i++) // materialsAtGaussPoints[i] = (IContinuumMaterial3D)material.Clone(); dofTypes = new IDofType[nodes.Count][]; for (int i = 0; i < nodes.Count; i++) { dofTypes[i] = new IDofType[] { StructuralDof.TranslationX, StructuralDof.TranslationY, StructuralDof.TranslationZ }; } strainsVec = new double[materialsAtGaussPoints.Count][]; strainsVecLastConverged = new double[materialsAtGaussPoints.Count][]; for (int gpoint = 0; gpoint < materialsAtGaussPoints.Count; gpoint++) { strainsVec[gpoint] = new double[6]; strainsVecLastConverged[gpoint] = new double[6]; } }
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 ContinuumElement3DNonLinear(IReadOnlyList <Node> nodes, IIsoparametricInterpolation3D interpolation, IQuadrature3D quadratureForStiffness, IQuadrature3D quadratureForMass, IGaussPointExtrapolation3D gaussPointExtrapolation, IContinuumMaterial3D material, IDynamicMaterial dynamicProperties) { this.dynamicProperties = dynamicProperties; this.Interpolation = interpolation; this.QuadratureForConsistentMass = quadratureForMass; this.nGaussPoints = quadratureForStiffness.IntegrationPoints.Count; this.QuadratureForStiffness = quadratureForStiffness; this.Nodes = nodes; materialsAtGaussPoints = new IContinuumMaterial3D[nGaussPoints]; for (int i = 0; i < nGaussPoints; i++) { materialsAtGaussPoints[i] = (IContinuumMaterial3D)material.Clone(); } dofTypes = new IDofType[nodes.Count][]; for (int i = 0; i < nodes.Count; i++) { dofTypes[i] = new IDofType[] { StructuralDof.TranslationX, StructuralDof.TranslationY, StructuralDof.TranslationZ }; } }
public BodyLoadElement(IBodyLoad bodyLoad, IIsoparametricInterpolation3D interpolation3D, IQuadrature3D quadrature3D, IReadOnlyList <Node> nodes) { _bodyLoad = bodyLoad; _interpolation = interpolation3D; _quadrature = quadrature3D; _nodes = nodes; }
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); }
private static void TestPartitionOfUnity(IIsoparametricInterpolation3D interpolation) { double tolerance = 1e-10; NaturalPoint[] points = pointGenerators[interpolation](); for (int p = 0; p < points.Length; p++) { double[] shapeFunctions = interpolation.EvaluateFunctionsAt(points[p]); double sum = 0.0; for (int f = 0; f < interpolation.NumFunctions; f++) { sum += shapeFunctions[f]; } Assert.True(Utilities.AreValuesEqual(1.0, sum, tolerance)); } }
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 jacobianMatrix = Matrix.CreateZero(3, 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; jacobianMatrix[2, 0] += shapeGradientsNatural[gp][indexNode, 2] * nodes[indexNode].X; jacobianMatrix[2, 1] += shapeGradientsNatural[gp][indexNode, 2] * nodes[indexNode].Y; jacobianMatrix[2, 2] += shapeGradientsNatural[gp][indexNode, 2] * nodes[indexNode].Z; } var jacdet = jacobianMatrix.CalcDeterminant(); var weightFactor = integration.IntegrationPoints[gp].Weight; for (int indexNode = 0; indexNode < nodes.Count; indexNode++) { var node = nodes[indexNode]; var valueX = _acceleration * shapeFunctionNatural[gp][indexNode] * jacdet * weightFactor * _density; if (loadTable.Contains(node, _dofType)) { loadTable[node, _dofType] += valueX; } else { loadTable.TryAdd(node, _dofType, valueX); } } } return(loadTable); }
private double[][] EvaluateExtrapolationFunctionsAtNodes(IIsoparametricInterpolation3D interpolation) { bool isCached = cachedExtrapolationFunctionsAtNodes.TryGetValue(interpolation, out double[][] nodalExtrapolationFunctions); if (!isCached) { IReadOnlyList <NaturalPoint> nodes = interpolation.NodalNaturalCoordinates; nodalExtrapolationFunctions = new double[nodes.Count][]; for (int i = 0; i < nodes.Count; i++) { nodalExtrapolationFunctions[i] = EvaluateExtrapolationFunctionsAt(nodes[i]); } cachedExtrapolationFunctionsAtNodes.Add(interpolation, nodalExtrapolationFunctions); } return(nodalExtrapolationFunctions); }
public ConvectionDiffusionElement3D(IReadOnlyList <Node> nodes, IIsoparametricInterpolation3D interpolation, IQuadrature3D quadratureForStiffness, IQuadrature3D quadratureForMass, IGaussPointExtrapolation3D gaussPointExtrapolation, ConvectionDiffusionMaterial material) { this.material = material; this.GaussPointExtrapolation = gaussPointExtrapolation; this.Nodes = nodes; this.Interpolation = interpolation; this.QuadratureForConsistentMass = quadratureForMass; this.QuadratureForStiffness = quadratureForStiffness; dofTypes = new IDofType[nodes.Count][]; for (int i = 0; i < interpolation.NumFunctions; ++i) { dofTypes[i] = new IDofType[] { ThermalDof.Temperature } } ; }
/// <summary> /// Calculates a scalar quantity at the nodes of a finite element by extrapolating its known values at the integration /// points. /// </summary> /// <param name="scalarsAtGaussPoints">Their order must be the same as the order of integration points defined by /// <see cref="Quadrature"/>.</param> /// <param name="interpolation">Defines the natural coordinates of the finite element's nodes.</param> /// <returns></returns> public IReadOnlyList <double> ExtrapolateScalarFromGaussPointsToNodes(IReadOnlyList <double> scalarsAtGaussPoints, IIsoparametricInterpolation3D interpolation) { double[][] nodalExtrapolationFunctions = EvaluateExtrapolationFunctionsAtNodes(interpolation); IReadOnlyList <NaturalPoint> nodes = interpolation.NodalNaturalCoordinates; var nodalScalars = new double[nodes.Count]; for (int i = 0; i < nodes.Count; i++) { double scalar = 0; for (int gp = 0; gp < Quadrature.IntegrationPoints.Count; gp++) { scalar += nodalExtrapolationFunctions[i][gp] * scalarsAtGaussPoints[gp]; } nodalScalars[i] = scalar; } return(nodalScalars); }
private static void TestValuesAtNodes(IIsoparametricInterpolation3D interpolation) { double tolerance = 1e-10; for (int n = 0; n < interpolation.NodalNaturalCoordinates.Count; n++) { double[] shapeFunctions = interpolation.EvaluateFunctionsAt(interpolation.NodalNaturalCoordinates[n]); for (int f = 0; f < interpolation.NumFunctions; f++) { if (f == n) { Assert.True(Utilities.AreValuesEqual(1.0, shapeFunctions[f], tolerance)); } else { Assert.True(Utilities.AreValuesEqual(0.0, shapeFunctions[f], tolerance)); } } } }
public ContinuumElement3D(IReadOnlyList <Node> nodes, IIsoparametricInterpolation3D interpolation, IQuadrature3D quadratureForStiffness, IQuadrature3D quadratureForMass, IGaussPointExtrapolation3D gaussPointExtrapolation, IReadOnlyList <ElasticMaterial3D> materialsAtGaussPoints, DynamicMaterial dynamicProperties) { this.dynamicProperties = dynamicProperties; this.materialsAtGaussPoints = materialsAtGaussPoints; this.GaussPointExtrapolation = gaussPointExtrapolation; this.Nodes = nodes; this.Interpolation = interpolation; this.QuadratureForConsistentMass = quadratureForMass; this.QuadratureForStiffness = quadratureForStiffness; dofTypes = new IDofType[nodes.Count][]; for (int i = 0; i < nodes.Count; i++) { dofTypes[i] = new IDofType[] { StructuralDof.TranslationX, StructuralDof.TranslationY, StructuralDof.TranslationZ }; } }
public ContinuumElement3DNonLinearDefGrad(IReadOnlyList <Node> nodes, IContinuumMaterial3DDefGrad material, IQuadrature3D quadratureForStiffness, IIsoparametricInterpolation3D interpolation) { this.nGaussPoints = quadratureForStiffness.IntegrationPoints.Count; this.QuadratureForStiffness = quadratureForStiffness; this.Interpolation = interpolation; materialsAtGaussPoints = new IContinuumMaterial3DDefGrad[nGaussPoints]; for (int i = 0; i < nGaussPoints; i++) { materialsAtGaussPoints[i] = (IContinuumMaterial3DDefGrad)material.Clone(); } dofTypes = new IDofType[nodes.Count][]; for (int i = 0; i < nodes.Count; i++) { dofTypes[i] = new IDofType[] { StructuralDof.TranslationX, StructuralDof.TranslationY, StructuralDof.TranslationZ }; } }
public Table <INode, IDofType, double> CalculateStabilizingBodyLoad(IIsoparametricInterpolation3D interpolation, IQuadrature3D integration, IReadOnlyList <Node> nodes) { throw new NotImplementedException(); }