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)); }
public SurfaceLoadElement(ISurfaceLoad surfaceLoad, IIsoparametricInterpolation2D isoparametricInterpolation2D, IQuadrature2D quadrature2D, IReadOnlyList <Node> nodes) { this.surfaceLoad = surfaceLoad; this.isoparametricInterpolation2D = isoparametricInterpolation2D; this.quadrature2D = quadrature2D; this.nodes = nodes; }
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(); } }
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); } }
//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 } } ; }
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 }; } }
/// <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); } }
/// <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); } }
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)); }
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)); }
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); }
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); }
/// <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); }
protected GaussPointExtrapolation2DBase(IQuadrature2D quadrature) { this.cachedExtrapolationFunctionsAtNodes = new Dictionary <IIsoparametricInterpolation2D, double[][]>(); this.Quadrature = quadrature; }
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>(); }
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)); } }
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); }
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); }