internal static void CheckNullSpace(IMatrixView unfactorizedMatrix, IReadOnlyList <double[]> nullSpaceBasis,
                                            double tolerance)
        {
            var comparer = new MatrixComparer(tolerance);

            // Check that each vector belongs to the nullspace
            int order = unfactorizedMatrix.NumColumns;
            //var zeroVector = Vector.CreateZero(order);
            int nullity         = nullSpaceBasis.Count;
            var nullSpaceMatrix = Matrix.CreateZero(order, nullity);

            for (int j = 0; j < nullity; ++j)
            {
                var x = Vector.CreateFromArray(nullSpaceBasis[j]);
                nullSpaceMatrix.SetSubcolumn(j, x);

                // Check that each vector belongs to the nullspace
                IVector Ax     = unfactorizedMatrix.Multiply(x);
                double  normAx = Ax.Norm2() / Ax.Length;
                //comparer.AssertEqual(0.0, normAx);
            }

            // Check that the vectors are independent.
            // TODO: perhaps this should be included in the LinearAlgebra project, not just for tests.
            (Matrix rref, List <int> independentCols) = nullSpaceMatrix.ReducedRowEchelonForm(tolerance);
            for (int j = 0; j < nullity; ++j)
            {
                Assert.Contains(j, independentCols);
            }
        }
        private (double compliance, Vector sensitivities) ObjectiveFunction(Vector densities)
        {
            // FEM analysis. Use the material property (e.g Young modulus) for the current element densities.
            IVectorView materialProperties = densities.DoToAllEntries(materialInterpolation.CalcMaterialProperty);

            fem.UpdateModelAndAnalyze(materialProperties);

            // Objective function and sensitivity analysis
            int    numElements   = fem.NumElements;
            int    numLoadCases  = fem.NumLoadCases;
            double compliance    = 0.0;
            var    sensitivities = Vector.CreateZero(numElements);

            for (int e = 0; e < numElements; ++e)
            {
                IMatrixView stiffness        = fem.GetElementStiffnessForUnitMaterial(e);
                double      complianceCoeff  = materialProperties[e];
                double      sensitivityCoeff = -materialInterpolation.CalcMaterialPropertyDerivative(densities[e]);
                for (int load = 0; load < numLoadCases; ++load)
                {
                    // If K0(e) is the element's stiffness matrix for E = 1 and E(x(e)) is the Young modulus for its current
                    // density:
                    // Compliance: c += E(x(e)) * ( U(e)^T * K0(e) * U(e) )
                    // Sensitivity: dc(e) -= dE(x(e))/dx(e) * (  U(e)^T * K0(e) * U(e) ),
                    Vector displacements  = fem.GetElementDisplacements(e, load);
                    double unitCompliance = stiffness.Multiply(displacements).DotProduct(displacements);
                    compliance       += complianceCoeff * unitCompliance;
                    sensitivities[e] += sensitivityCoeff * unitCompliance;
                }
            }

            // Filter the densities and sensitivities
            //TODO: is it correct to modify the densities? They should be controlled by the optimization algorithm
            filter.FilterSensitivities(densities, ref sensitivities);

            if (Logger != null)
            {
                Logger.Log(compliance);
            }
            return(compliance, sensitivities);
        }
Exemplo n.º 3
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);
        }