Esempio n. 1
0
 public SurfaceLoadElement(ISurfaceLoad surfaceLoad, IIsoparametricInterpolation2D isoparametricInterpolation2D,
                           IQuadrature2D quadrature2D, IReadOnlyList <Node> nodes)
 {
     this.surfaceLoad = surfaceLoad;
     this.isoparametricInterpolation2D = isoparametricInterpolation2D;
     this.quadrature2D = quadrature2D;
     this.nodes        = nodes;
 }
        /// <summary>
        /// See <see cref="IGaussPointExtrapolation2D.ExtrapolateTensorFromGaussPointsToNodes(
        /// IReadOnlyList{Tensor2D}, IIsoparametricInterpolation2D)"/>
        /// </summary>
        public IReadOnlyList <Tensor2D> ExtrapolateTensorFromGaussPointsToNodes(IReadOnlyList <Tensor2D> tensorsAtGaussPoints,
                                                                                IIsoparametricInterpolation2D interpolation)
        {
            var nodalTensors = new Tensor2D[interpolation.NumFunctions];

            for (int i = 0; i < nodalTensors.Length; ++i)
            {
                nodalTensors[i] = tensorsAtGaussPoints[0];
            }
            return(nodalTensors);
        }
        /// <summary>
        /// See <see cref="IGaussPointExtrapolation2D.ExtrapolateScalarFromGaussPointsToNodes(
        /// IReadOnlyList{double}, IIsoparametricInterpolation2D)"/>
        /// </summary>
        public IReadOnlyList <double> ExtrapolateScalarFromGaussPointsToNodes(IReadOnlyList <double> scalarsAtGaussPoints,
                                                                              IIsoparametricInterpolation2D interpolation)
        {
            var nodalScalars = new double[interpolation.NumFunctions];

            for (int i = 0; i < nodalScalars.Length; ++i)
            {
                nodalScalars[i] = scalarsAtGaussPoints[0];
            }
            return(nodalScalars);
        }
        private static void TestPartitionOfUnity(IIsoparametricInterpolation2D interpolation)
        {
            double tolerance = 1e-10;

            NaturalPoint[] points = pointGenerators[interpolation]();
            for (int p = 0; p < points.Length; ++p)
            {
                double[] shapeFuncs = interpolation.EvaluateFunctionsAt(points[p]);
                double   sum        = 0.0;
                for (int f = 0; f < interpolation.NumFunctions; ++f)
                {
                    sum += shapeFuncs[f];
                }
                Assert.True(Utilities.AreValuesEqual(1.0, sum, tolerance));
            }
        }
        private double[][] EvaluateExtrapolationFunctionsAtNodes(IIsoparametricInterpolation2D 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);
        }
        /// <summary>
        /// See <see cref="IGaussPointExtrapolation2D.ExtrapolateScalarFromGaussPointsToNodes(
        /// IReadOnlyList{double}, IIsoparametricInterpolation2D)"/>
        /// </summary>
        public IReadOnlyList <double> ExtrapolateScalarFromGaussPointsToNodes(IReadOnlyList <double> scalarsAtGaussPoints,
                                                                              IIsoparametricInterpolation2D interpolation)
        {
            double[][] nodalExtrapolationFunctions = EvaluateExtrapolationFunctionsAtNodes(interpolation);
            IReadOnlyList <NaturalPoint> nodes     = interpolation.NodalNaturalCoordinates;
            var nodalScalars = new double[nodes.Count];

            for (int i = 0; i < nodes.Count; ++i)
            {
                //nodalScalars[i] = ExtrapolateScalarFromGaussPoints(scalarsAtGaussPoints, nodes[i]); // for debugging
                double scalar = 0;
                for (int gp = 0; gp < Quadrature.IntegrationPoints.Count; ++gp)
                {
                    scalar += nodalExtrapolationFunctions[i][gp] * scalarsAtGaussPoints[gp];
                }
                nodalScalars[i] = scalar;
            }
            return(nodalScalars);
        }
        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 };
            }
        }
        private static void TestValuesAtNodes(IIsoparametricInterpolation2D interpolation)
        {
            double tolerance = 1e-10;

            for (int n = 0; n < interpolation.NodalNaturalCoordinates.Count; ++n)
            {
                double[] shapeFuncs = interpolation.EvaluateFunctionsAt(interpolation.NodalNaturalCoordinates[n]);
                for (int f = 0; f < interpolation.NumFunctions; ++f)
                {
                    if (f == n)
                    {
                        Assert.True(Utilities.AreValuesEqual(1.0, shapeFuncs[f], tolerance));
                    }
                    else
                    {
                        Assert.True(Utilities.AreValuesEqual(0.0, shapeFuncs[f], tolerance));
                    }
                }
            }
        }
Esempio n. 9
0
        //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 }
            }
            ;
        }
        /// <summary>
        /// See <see cref="IGaussPointExtrapolation2D.ExtrapolateVectorFromGaussPointsToNodes(
        /// IReadOnlyList{double[]}, IIsoparametricInterpolation2D)"/>
        /// </summary>
        public IReadOnlyList <double[]> ExtrapolateVectorFromGaussPointsToNodes(IReadOnlyList <double[]> vectorsAtGaussPoints,
                                                                                IIsoparametricInterpolation2D interpolation)
        {
            double[][] nodalExtrapolationFunctions = EvaluateExtrapolationFunctionsAtNodes(interpolation);
            IReadOnlyList <NaturalPoint> nodes     = interpolation.NodalNaturalCoordinates;
            var nodalVectors = new double[nodes.Count][];

            for (int i = 0; i < nodes.Count; ++i)
            {
                //nodalVectors[i] = ExtrapolateVectorFromGaussPoints(tensorsAtGaussPoints, nodes[i]); // for debugging
                var vector = new double[2];
                for (int gp = 0; gp < Quadrature.IntegrationPoints.Count; ++gp)
                {
                    vector[0] += nodalExtrapolationFunctions[i][gp] * vectorsAtGaussPoints[gp][0];
                    vector[1] += nodalExtrapolationFunctions[i][gp] * vectorsAtGaussPoints[gp][1];
                }
                nodalVectors[i] = vector;
            }
            return(nodalVectors);
        }
Esempio n. 11
0
        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);
        }
        /// <summary>
        /// See <see cref="IGaussPointExtrapolation2D.ExtrapolateTensorFromGaussPointsToNodes(
        /// IReadOnlyList{Tensor2D}, IIsoparametricInterpolation2D)"/>
        /// </summary>
        public IReadOnlyList <Tensor2D> ExtrapolateTensorFromGaussPointsToNodes(IReadOnlyList <Tensor2D> tensorsAtGaussPoints,
                                                                                IIsoparametricInterpolation2D interpolation)
        {
            double[][] nodalExtrapolationFunctions = EvaluateExtrapolationFunctionsAtNodes(interpolation);
            IReadOnlyList <NaturalPoint> nodes     = interpolation.NodalNaturalCoordinates;
            var nodalTensors = new Tensor2D[nodes.Count];

            for (int i = 0; i < nodes.Count; ++i)
            {
                //nodalTensors[i] = ExtrapolateVectorFromGaussPoints(tensorsAtGaussPoints, nodes[i]); // for debugging
                var tensor = new double[3];
                for (int gp = 0; gp < Quadrature.IntegrationPoints.Count; ++gp)
                {
                    tensor[0] += nodalExtrapolationFunctions[i][gp] * tensorsAtGaussPoints[gp].XX;
                    tensor[1] += nodalExtrapolationFunctions[i][gp] * tensorsAtGaussPoints[gp].YY;
                    tensor[2] += nodalExtrapolationFunctions[i][gp] * tensorsAtGaussPoints[gp].XY;
                }
                nodalTensors[i] = new Tensor2D(tensor[0], tensor[1], tensor[2]);
            }
            return(nodalTensors);
        }
        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>();
        }
Esempio n. 14
0
        public void WriteOutputData(IDofOrderer dofOrderer, Vector freeDisplacements, Vector constrainedDisplacements, int step)
        {
            // TODO: guess initial capacities from previous steps or from the model
            var allPoints     = new List <VtkPoint>();
            var allCells      = new List <VtkCell>();
            var displacements = new List <double[]>();
            var strains       = new List <Tensor2D>();
            var stresses      = new List <Tensor2D>();
            int pointCounter  = 0;

            foreach (XContinuumElement2D element in model.Elements)
            {
                Vector standardDisplacements = dofOrderer.ExtractDisplacementVectorOfElementFromGlobal(element,
                                                                                                       freeDisplacements, constrainedDisplacements);
                Vector enrichedDisplacements =
                    dofOrderer.ExtractEnrichedDisplacementsOfElementFromGlobal(element, freeDisplacements);
                bool mustTriangulate = MustBeTriangulated(element, out ISingleCrack intersectingCrack);

                if (!mustTriangulate)
                {
                    // Mesh
                    var cellPoints = new VtkPoint[element.Nodes.Count];
                    for (int p = 0; p < cellPoints.Length; ++p)
                    {
                        cellPoints[p] = new VtkPoint(pointCounter++, element.Nodes[p]);
                        allPoints.Add(cellPoints[p]);
                    }
                    allCells.Add(new VtkCell(element.CellType, cellPoints));

                    // Displacements
                    for (int p = 0; p < cellPoints.Length; ++p)
                    {
                        displacements.Add(new double[] { standardDisplacements[2 * p], standardDisplacements[2 * p + 1] });
                    }

                    // Strains and stresses at Gauss points of element
                    // WARNING: do not use the quadrature object, since GPs are sorted differently.
                    IReadOnlyList <GaussPoint> gaussPoints = element.GaussPointExtrapolation.Quadrature.IntegrationPoints;
                    var strainsAtGPs  = new Tensor2D[gaussPoints.Count];
                    var stressesAtGPs = new Tensor2D[gaussPoints.Count];
                    for (int gp = 0; gp < gaussPoints.Count; ++gp)
                    {
                        EvalInterpolation2D evalInterpol =
                            element.Interpolation.EvaluateAllAt(element.Nodes, gaussPoints[gp]);
                        (Tensor2D strain, Tensor2D stress) = ComputeStrainStress(element, gaussPoints[gp],
                                                                                 evalInterpol, standardDisplacements, enrichedDisplacements);
                        strainsAtGPs[gp]  = strain;
                        stressesAtGPs[gp] = stress;
                    }

                    // Extrapolate strains and stresses to element nodes. This is exact, since the element is not enriched
                    IReadOnlyList <Tensor2D> strainsAtNodes = element.GaussPointExtrapolation.
                                                              ExtrapolateTensorFromGaussPointsToNodes(strainsAtGPs, element.Interpolation);
                    IReadOnlyList <Tensor2D> stressesAtNodes = element.GaussPointExtrapolation.
                                                               ExtrapolateTensorFromGaussPointsToNodes(stressesAtGPs, element.Interpolation);
                    for (int p = 0; p < cellPoints.Length; ++p)
                    {
                        strains.Add(strainsAtNodes[p]);
                        stresses.Add(stressesAtNodes[p]);
                    }
                }
                else
                {
                    // Triangulate and then operate on each triangle
                    SortedSet <CartesianPoint> triangleVertices            = intersectingCrack.FindTriangleVertices(element);
                    IReadOnlyList <Triangle2D <CartesianPoint> > triangles = triangulator.CreateMesh(triangleVertices);

                    foreach (Triangle2D <CartesianPoint> triangle in triangles)
                    {
                        // Mesh
                        int numTriangleNodes = 3;
                        var cellPoints       = new VtkPoint[numTriangleNodes];
                        for (int p = 0; p < numTriangleNodes; ++p)
                        {
                            CartesianPoint point = triangle.Vertices[p];
                            cellPoints[p] = new VtkPoint(pointCounter++, point.X, point.Y, point.Z);
                            allPoints.Add(cellPoints[p]);
                        }
                        allCells.Add(new VtkCell(CellType.Tri3, cellPoints));

                        // Displacements, strains and stresses are not defined on the crack, thus they must be evaluated at GPs
                        // and extrapolated to each point of interest. However how should I choose the Gauss points? Here I take
                        // the Gauss points of the subtriangles.
                        IGaussPointExtrapolation2D    extrapolation = ExtrapolationGaussTriangular3Points.UniqueInstance;
                        IIsoparametricInterpolation2D interpolation = InterpolationTri3.UniqueInstance;

                        // Find the Gauss points of the triangle in the natural system of the element
                        IInverseInterpolation2D inverseMapping = element.Interpolation.CreateInverseMappingFor(element.Nodes);
                        var triangleNodesNatural = new NaturalPoint[numTriangleNodes];
                        for (int p = 0; p < numTriangleNodes; ++p)
                        {
                            triangleNodesNatural[p] = inverseMapping.TransformPointCartesianToNatural(cellPoints[p]);
                        }
                        NaturalPoint[] triangleGPsNatural =
                            FindTriangleGPsNatural(triangleNodesNatural, extrapolation.Quadrature.IntegrationPoints);

                        // Find the field values at the Gauss points of the triangle (their coordinates are in the natural
                        // system of the element)
                        var displacementsAtGPs = new double[triangleGPsNatural.Length][];
                        var strainsAtGPs       = new Tensor2D[triangleGPsNatural.Length];
                        var stressesAtGPs      = new Tensor2D[triangleGPsNatural.Length];
                        for (int gp = 0; gp < triangleGPsNatural.Length; ++gp)
                        {
                            EvalInterpolation2D evalInterpol =
                                element.Interpolation.EvaluateAllAt(element.Nodes, triangleGPsNatural[gp]);
                            displacementsAtGPs[gp] = element.CalculateDisplacementField(triangleGPsNatural[gp],
                                                                                        evalInterpol, standardDisplacements, enrichedDisplacements).CopyToArray();
                            (Tensor2D strain, Tensor2D stress) = ComputeStrainStress(element, triangleGPsNatural[gp],
                                                                                     evalInterpol, standardDisplacements, enrichedDisplacements);
                            strainsAtGPs[gp]  = strain;
                            stressesAtGPs[gp] = stress;
                        }

                        // Extrapolate the field values to the triangle nodes. We need their coordinates in the auxiliary
                        // system of the triangle. We could use the inverse interpolation of the triangle to map the natural
                        // (element local) coordinates of the nodes to the auxiliary system of the triangle. Fortunately they
                        // can be accessed by the extrapolation object directly.
                        IReadOnlyList <double[]> displacementsAtTriangleNodes =
                            extrapolation.ExtrapolateVectorFromGaussPointsToNodes(displacementsAtGPs, interpolation);
                        IReadOnlyList <Tensor2D> strainsAtTriangleNodes =
                            extrapolation.ExtrapolateTensorFromGaussPointsToNodes(strainsAtGPs, interpolation);
                        IReadOnlyList <Tensor2D> stressesAtTriangleNodes =
                            extrapolation.ExtrapolateTensorFromGaussPointsToNodes(stressesAtGPs, interpolation);
                        for (int p = 0; p < numTriangleNodes; ++p)
                        {
                            displacements.Add(displacementsAtTriangleNodes[p]);
                            strains.Add(strainsAtTriangleNodes[p]);
                            stresses.Add(stressesAtTriangleNodes[p]);
                        }
                    }
                }
            }

            using (var writer = new VtkFileWriter($"{pathNoExtension}_{step}.vtk"))
            {
                writer.WriteMesh(allPoints, allCells);
                writer.WriteVector2DField("displacement", displacements);
                writer.WriteTensor2DField("strain", strains);
                writer.WriteTensor2DField("stress", stresses);
            }
        }
Esempio n. 15
0
        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);
        }
Esempio n. 16
0
        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);
        }