public void Multiply(Vector lhs, Vector rhs)
 {
     rhs.Clear(); //TODO: perhaps this should be done outside.
     foreach (var keyFactor in matrixManagers)
     {
         int id = keyFactor.Key;
         IFeti1SubdomainMatrixManager matrixManager = keyFactor.Value;
         SignedBooleanMatrixColMajor  B             = lagrangeEnumerator.BooleanMatrices[id];
         Vector FBx  = matrixManager.MultiplyInverseKffTimes(B.Multiply(lhs, true));
         Vector BFBx = B.Multiply(FBx, false);
         rhs.AddIntoThis(BFBx);
     }
 }
示例#2
0
        //TODO: This can be moved to a base class. Only the S matrix is different for these preconditioners.
        //      Other ones might be different though.
        public void SolveLinearSystem(Vector rhs, Vector lhs)
        {
            lhs.Clear(); //TODO: this should be avoided
            foreach (int s in subdomainIDs)
            {
                IFetiSubdomainMatrixManager matrixManager = matrixManagers[s];
                IMappingMatrix Bpb = preconditioningBoundarySignedBooleanMatrices[s];

                // inv(F) * y = Bpb * Kbb * Bpb^T * y
                Vector temp = Bpb.Multiply(rhs, true);
                temp = matrixManager.MultiplyKbbTimes(temp);
                Vector subdomainContribution = Bpb.Multiply(temp);
                lhs.AddIntoThis(subdomainContribution);
            }
        }
示例#3
0
        public void MultiplyFIrr(Vector lhs, Vector rhs)
        {
            Preconditions.CheckMultiplicationDimensions(Order, lhs.Length);
            Preconditions.CheckSystemSolutionDimensions(Order, rhs.Length);

            // FIrr[s] * x = sum_over_s( Br[s] * (inv(Krr[s]) * (Br[s]^T * x)) )
            rhs.Clear();
            foreach (int s in Br.Keys)
            {
                IFetiDPSubdomainMatrixManager matrices = matrixManagers[s];
                Vector temp = Br[s].Multiply(lhs, true);
                temp = matrices.MultiplyInverseKrrTimes(temp);
                temp = Br[s].Multiply(temp);
                rhs.AddIntoThis(temp);
            }
        }
        public (Vector lagrangeMultipliers, Vector cornerDisplacements) SolveInterfaceProblem(FetiDPFlexibilityMatrix flexibility,
                                                                                              IFetiPreconditioner preconditioner, IFetiDPCoarseProblemSolver coarseProblemSolver,
                                                                                              Vector globalFcStar, Vector dr, double globalForcesNorm, SolverLogger logger)
        {
            int systemOrder = flexibility.Order;

            // Matrix, preconditioner & rhs
            var    pcgMatrix         = new InterfaceProblemMatrix(flexibility, coarseProblemSolver);
            var    pcgPreconditioner = new InterfaceProblemPreconditioner(preconditioner);
            Vector pcgRhs            = CreateInterfaceProblemRhs(flexibility, coarseProblemSolver, globalFcStar, dr);

            // Solve the interface problem using PCG algorithm
            var pcgBuilder = new PcgAlgorithm.Builder();

            pcgBuilder.MaxIterationsProvider = maxIterationsProvider;
            pcgBuilder.ResidualTolerance     = pcgConvergenceTolerance;
            pcgBuilder.Convergence           = pcgConvergenceStrategyFactory.CreateConvergenceStrategy(globalForcesNorm);
            PcgAlgorithm        pcg       = pcgBuilder.Build(); //TODO: perhaps use the pcg from the previous analysis if it has reorthogonalization.
            var                 lagranges = Vector.CreateZero(systemOrder);
            IterativeStatistics stats     = pcg.Solve(pcgMatrix, pcgPreconditioner, pcgRhs, lagranges, true,
                                                      () => Vector.CreateZero(systemOrder));

            // Log statistics about PCG execution
            if (!stats.HasConverged)
            {
                throw new IterativeSolverNotConvergedException(FetiDPSolver.name + " did not converge to a solution. PCG"
                                                               + $" algorithm run for {stats.NumIterationsRequired} iterations and the residual norm ratio was"
                                                               + $" {stats.ResidualNormRatioEstimation}");
            }
            logger.LogIterativeAlgorithm(stats.NumIterationsRequired, stats.ResidualNormRatioEstimation);

            // Calculate corner displacements: uc = inv(KccStar) * (fcStar + FIrc^T * lagranges)
            Vector uc = flexibility.MultiplyTransposedFIrc(lagranges);

            uc.AddIntoThis(globalFcStar);
            uc = coarseProblemSolver.MultiplyInverseCoarseProblemMatrixTimes(uc);

            return(lagranges, uc);
        }
        private double[,] CalculateBendingDeformationMatrix(double[] surfaceBasisVector3, ShapeTSplines2DFromBezierExtraction tsplines, int j,
                                                            double[] surfaceBasisVector2, double[] surfaceBasisVectorDerivative1, double[] surfaceBasisVector1, double J1,
                                                            double[] surfaceBasisVectorDerivative2, double[] surfaceBasisVectorDerivative12, ControlPoint[] elementControlPoints)
        {
            var Bbending = new double[3, elementControlPoints.Length * 3];
            var s1       = Vector.CreateFromArray(surfaceBasisVector1);
            var s2       = Vector.CreateFromArray(surfaceBasisVector2);
            var s3       = Vector.CreateFromArray(surfaceBasisVector3);
            var s11      = Vector.CreateFromArray(surfaceBasisVectorDerivative1);
            var s22      = Vector.CreateFromArray(surfaceBasisVectorDerivative2);
            var s12      = Vector.CreateFromArray(surfaceBasisVectorDerivative12);

            for (int column = 0; column < elementControlPoints.Length * 3; column += 3)
            {
                #region BI1

                var BI1 = s3.CrossProduct(s3);
                BI1.ScaleIntoThis(tsplines.TSplineDerivativeValuesHeta[column / 3, j]);
                var auxVector = s2.CrossProduct(s3);
                auxVector.ScaleIntoThis(tsplines.TSplineDerivativeValuesKsi[column / 3, j]);
                BI1.AddIntoThis(auxVector);
                BI1.ScaleIntoThis(s3.DotProduct(s11));
                auxVector = s1.CrossProduct(s11);
                auxVector.ScaleIntoThis(tsplines.TSplineDerivativeValuesHeta[column / 3, j]);
                BI1.AddIntoThis(auxVector);
                BI1.ScaleIntoThis(1 / J1);
                auxVector[0] = surfaceBasisVector3[0];
                auxVector[1] = surfaceBasisVector3[1];
                auxVector[2] = surfaceBasisVector3[2];
                auxVector.ScaleIntoThis(-tsplines.TSplineSecondDerivativesValueKsi[column / 3, j]);
                BI1.AddIntoThis(auxVector);

                #endregion BI1

                #region BI2

                IVector BI2 = s3.CrossProduct(s3);
                BI2.ScaleIntoThis(tsplines.TSplineDerivativeValuesHeta[column / 3, j]);
                auxVector = s2.CrossProduct(s3);
                auxVector.ScaleIntoThis(tsplines.TSplineDerivativeValuesKsi[column / 3, j]);
                BI2.AddIntoThis(auxVector);
                BI2.ScaleIntoThis(s3.DotProduct(s22));
                auxVector = s1.CrossProduct(s22);
                auxVector.ScaleIntoThis(tsplines.TSplineDerivativeValuesHeta[column / 3, j]);
                BI2.AddIntoThis(auxVector);
                auxVector = s22.CrossProduct(s2);
                auxVector.ScaleIntoThis(tsplines.TSplineDerivativeValuesKsi[column / 3, j]);
                BI2.AddIntoThis(auxVector);
                BI2.ScaleIntoThis(1 / J1);
                auxVector[0] = surfaceBasisVector3[0];
                auxVector[1] = surfaceBasisVector3[1];
                auxVector[2] = surfaceBasisVector3[2];
                auxVector.ScaleIntoThis(-tsplines.TSplineSecondDerivativesValueHeta[column / 3, j]);
                BI2.AddIntoThis(auxVector);

                #endregion BI2

                #region BI3

                Vector BI3 = s3.CrossProduct(s3);
                BI3.ScaleIntoThis(tsplines.TSplineDerivativeValuesHeta[column / 3, j]);
                auxVector = s2.CrossProduct(s3);
                auxVector.ScaleIntoThis(tsplines.TSplineDerivativeValuesKsi[column / 3, j]);
                BI3.AddIntoThis(auxVector);
                BI3.ScaleIntoThis(s3.DotProduct(s12));
                auxVector = s1.CrossProduct(s12);
                auxVector.ScaleIntoThis(tsplines.TSplineDerivativeValuesHeta[column / 3, j]);
                BI3.AddIntoThis(auxVector);
                auxVector = s22.CrossProduct(s2);
                auxVector.ScaleIntoThis(tsplines.TSplineDerivativeValuesKsi[column / 3, j]);
                BI3.AddIntoThis(auxVector);
                BI3.ScaleIntoThis(1 / J1);
                auxVector[0] = surfaceBasisVector3[0];
                auxVector[1] = surfaceBasisVector3[1];
                auxVector[2] = surfaceBasisVector3[2];
                auxVector.ScaleIntoThis(-tsplines.TSplineSecondDerivativesValueKsiHeta[column / 3, j]);
                BI3.AddIntoThis(auxVector);

                #endregion BI3

                Bbending[0, column]     = BI1[0];
                Bbending[0, column + 1] = BI1[1];
                Bbending[0, column + 2] = BI1[2];

                Bbending[1, column]     = BI2[0];
                Bbending[1, column + 1] = BI2[1];
                Bbending[1, column + 2] = BI2[2];

                Bbending[2, column]     = 2 * BI3[0];
                Bbending[2, column + 1] = 2 * BI3[1];
                Bbending[2, column + 2] = 2 * BI3[2];
            }

            return(Bbending);
        }
示例#6
0
        private Matrix CalculateBendingDeformationMatrix(Vector surfaceBasisVector3, Nurbs2D nurbs, int j,
                                                         Vector surfaceBasisVector2, Vector surfaceBasisVectorDerivative1, Vector surfaceBasisVector1, double J1,
                                                         Vector surfaceBasisVectorDerivative2, Vector surfaceBasisVectorDerivative12, NurbsKirchhoffLoveShellElement element)
        {
            var    elementControlPoints = element.ControlPoints.ToArray();
            Matrix Bbending             = Matrix.CreateZero(3, elementControlPoints.Length * 3);

            for (int column = 0; column < elementControlPoints.Length * 3; column += 3)
            {
                #region BI1

                var BI1 = surfaceBasisVector3.CrossProduct(surfaceBasisVector3);
                BI1.ScaleIntoThis(nurbs.NurbsDerivativeValuesHeta[column / 3, j]);
                var auxVector = surfaceBasisVector2.CrossProduct(surfaceBasisVector3);
                auxVector.ScaleIntoThis(nurbs.NurbsDerivativeValuesKsi[column / 3, j]);
                BI1.AddIntoThis(auxVector);
                BI1.ScaleIntoThis(surfaceBasisVector3.DotProduct(surfaceBasisVectorDerivative1));
                auxVector = surfaceBasisVector1.CrossProduct(surfaceBasisVectorDerivative1);
                auxVector.ScaleIntoThis(nurbs.NurbsDerivativeValuesHeta[column / 3, j]);
                BI1.AddIntoThis(auxVector);
                BI1.ScaleIntoThis(1 / J1);
                auxVector[0] = surfaceBasisVector3[0];
                auxVector[1] = surfaceBasisVector3[1];
                auxVector[2] = surfaceBasisVector3[2];
                auxVector.ScaleIntoThis(-nurbs.NurbsSecondDerivativeValueKsi[column / 3, j]);
                BI1.AddIntoThis(auxVector);

                #endregion BI1

                #region BI2

                Vector BI2 = surfaceBasisVector3.CrossProduct(surfaceBasisVector3);
                BI2.ScaleIntoThis(nurbs.NurbsDerivativeValuesHeta[column / 3, j]);
                auxVector = surfaceBasisVector2.CrossProduct(surfaceBasisVector3);
                auxVector.ScaleIntoThis(nurbs.NurbsDerivativeValuesKsi[column / 3, j]);
                BI2.AddIntoThis(auxVector);
                BI2.ScaleIntoThis(surfaceBasisVector3.DotProduct(surfaceBasisVectorDerivative2));
                auxVector = surfaceBasisVector1.CrossProduct(surfaceBasisVectorDerivative2);
                auxVector.ScaleIntoThis(nurbs.NurbsDerivativeValuesHeta[column / 3, j]);
                BI2.AddIntoThis(auxVector);
                auxVector = surfaceBasisVectorDerivative2.CrossProduct(surfaceBasisVector2);
                auxVector.ScaleIntoThis(nurbs.NurbsDerivativeValuesKsi[column / 3, j]);
                BI2.AddIntoThis(auxVector);
                BI2.ScaleIntoThis(1 / J1);
                auxVector[0] = surfaceBasisVector3[0];
                auxVector[1] = surfaceBasisVector3[1];
                auxVector[2] = surfaceBasisVector3[2];
                auxVector.ScaleIntoThis(-nurbs.NurbsSecondDerivativeValueHeta[column / 3, j]);
                BI2.AddIntoThis(auxVector);

                #endregion BI2

                #region BI3

                Vector BI3 = surfaceBasisVector3.CrossProduct(surfaceBasisVector3);
                BI3.ScaleIntoThis(nurbs.NurbsDerivativeValuesHeta[column / 3, j]);
                auxVector = surfaceBasisVector2.CrossProduct(surfaceBasisVector3);
                auxVector.ScaleIntoThis(nurbs.NurbsDerivativeValuesKsi[column / 3, j]);
                BI3.AddIntoThis(auxVector);
                BI3.ScaleIntoThis(surfaceBasisVector3.DotProduct(surfaceBasisVectorDerivative12));
                auxVector = surfaceBasisVector1.CrossProduct(surfaceBasisVectorDerivative12);
                auxVector.ScaleIntoThis(nurbs.NurbsDerivativeValuesHeta[column / 3, j]);
                BI3.AddIntoThis(auxVector);
                auxVector = surfaceBasisVectorDerivative2.CrossProduct(surfaceBasisVector2);
                auxVector.ScaleIntoThis(nurbs.NurbsDerivativeValuesKsi[column / 3, j]);
                BI3.AddIntoThis(auxVector);
                BI3.ScaleIntoThis(1 / J1);
                auxVector[0] = surfaceBasisVector3[0];
                auxVector[1] = surfaceBasisVector3[1];
                auxVector[2] = surfaceBasisVector3[2];
                auxVector.ScaleIntoThis(-nurbs.NurbsSecondDerivativeValueKsiHeta[column / 3, j]);
                BI3.AddIntoThis(auxVector);

                #endregion BI3

                Bbending[0, column]     = BI1[0];
                Bbending[0, column + 1] = BI1[1];
                Bbending[0, column + 2] = BI1[2];

                Bbending[1, column]     = BI2[0];
                Bbending[1, column + 1] = BI2[1];
                Bbending[1, column + 2] = BI2[2];

                Bbending[2, column]     = 2 * BI3[0];
                Bbending[2, column + 1] = 2 * BI3[1];
                Bbending[2, column + 2] = 2 * BI3[2];
            }

            return(Bbending);
        }