Esempio n. 1
0
        public override void Solve()
        {
            var watch = new Stopwatch();

            if (linearSystem == null)
            {
                linearSystem.SolutionConcrete = linearSystem.CreateZeroVectorConcrete();
            }
            else
            {
                linearSystem.SolutionConcrete.Clear();
            }

            watch.Start();
            IterativeStatistics stats = gmresAlgorithm.Solve(linearSystem.Matrix, linearSystem.RhsConcrete,
                                                             linearSystem.SolutionConcrete, true, () => linearSystem.CreateZeroVector());

            if (!stats.HasConverged)
            {
                throw new IterativeSolverNotConvergedException("Gmres did not converge");
            }
            watch.Stop();
            Logger.LogTaskDuration("Iterative algorithm", watch.ElapsedMilliseconds);
            Logger.LogIterativeAlgorithm(stats.NumIterationsRequired, stats.ResidualNormRatioEstimation);
            Logger.IncrementAnalysisStep();
        }
Esempio n. 2
0
 private static void TestIndefiniteSystem(LinearAlgebraProviderChoice providers)
 {
     TestSettings.RunMultiproviderTest(providers, delegate()
     {
         (Matrix A, Vector b, Vector xExpected, IPreconditioner M) = DiagonalIndefinite.BuildIndefiniteSystem(20);
         var builder = new CGAlgorithm.Builder();
         builder.ResidualTolerance     = 1E-6;
         builder.MaxIterationsProvider = new PercentageMaxIterationsProvider(1.0);
         var cg                    = builder.Build();
         Vector xComputed          = Vector.CreateZero(A.NumRows);
         IterativeStatistics stats = cg.Solve(A, b, xComputed, true);
         Assert.False(comparer.AreEqual(xExpected, xComputed));
     });
 }
        protected override Matrix InverseSystemMatrixTimesOtherMatrix(IMatrixView otherMatrix)
        {
            //TODO: Use a reorthogonalizetion approach when solving multiple rhs vectors. It would be even better if the CG
            //      algorithm exposed a method for solving for multiple rhs vectors.
            var watch = new Stopwatch();

            // Preconditioning
            if (mustUpdatePreconditioner)
            {
                watch.Start();
                preconditioner = preconditionerFactory.CreatePreconditionerFor(linearSystem.Matrix);
                watch.Stop();
                Logger.LogTaskDuration("Calculating preconditioner", watch.ElapsedMilliseconds);
                watch.Reset();
                mustUpdatePreconditioner = false;
            }

            // Iterative algorithm
            watch.Start();
            int    systemOrder     = linearSystem.Matrix.NumColumns;
            int    numRhs          = otherMatrix.NumColumns;
            var    solutionVectors = Matrix.CreateZero(systemOrder, numRhs);
            Vector solutionVector  = linearSystem.CreateZeroVectorConcrete();

            // Solve each linear system
            for (int j = 0; j < numRhs; ++j)
            {
                if (j != 0)
                {
                    solutionVector.Clear();
                }

                //TODO: we should make sure this is the same type as the vectors used by this solver, otherwise vector operations
                //      in CG will be slow.
                Vector rhsVector = otherMatrix.GetColumn(j);

                IterativeStatistics stats = pcgAlgorithm.Solve(linearSystem.Matrix, preconditioner, rhsVector,
                                                               solutionVector, true, () => linearSystem.CreateZeroVector());

                solutionVectors.SetSubcolumn(j, solutionVector);
            }

            watch.Stop();
            Logger.LogTaskDuration("Iterative algorithm", watch.ElapsedMilliseconds);
            Logger.IncrementAnalysisStep();
            return(solutionVectors);
        }
Esempio n. 4
0
        public Vector CalcLagrangeMultipliers(Feti1FlexibilityMatrix flexibility, IFetiPreconditioner preconditioner,
                                              Feti1Projection projection, Vector disconnectedDisplacements, Vector rigidBodyModesWork, double globalForcesNorm,
                                              SolverLogger logger)
        {
            int               systemOrder       = flexibility.Order;
            PcgMatrix         pcgMatrix         = DefinePcgMatrix(flexibility, projection);
            PcgPreconditioner pcgPreconditioner = DefinePcgPreconditioner(preconditioner, projection);

            // λ0 = Q * G * inv(G^T * Q * G) * e
            Vector lagrangesParticular = projection.CalcParticularLagrangeMultipliers(rigidBodyModesWork);

            // Calculate rhs of the projected interface system: rhs = P^T * (d - F * λ0)
            var r0 = flexibility.Multiply(lagrangesParticular);

            r0.LinearCombinationIntoThis(-1.0, disconnectedDisplacements, 1.0);
            var pcgRhs = Vector.CreateZero(systemOrder);

            projection.ProjectVector(r0, pcgRhs, true);

            // 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();
            var                 lagrangesBar = Vector.CreateZero(systemOrder);
            IterativeStatistics stats        = pcg.Solve(pcgMatrix, pcgPreconditioner, pcgRhs, lagrangesBar, true,
                                                         () => Vector.CreateZero(systemOrder));

            if (!stats.HasConverged)
            {
                throw new IterativeSolverNotConvergedException(Feti1Solver.name + " did not converge to a solution. PCG"
                                                               + $" algorithm run for {stats.NumIterationsRequired} iterations and the residual norm ratio was"
                                                               + $" {stats.ResidualNormRatioEstimation}");
            }

            // Calculate the actual lagrange multipliers from the separation formula: λ = λ0 + P * λbar
            var lagranges = Vector.CreateZero(systemOrder);

            projection.ProjectVector(lagrangesBar, lagranges, false);
            lagranges.AddIntoThis(lagrangesParticular);

            // Log statistics about PCG execution
            logger.LogIterativeAlgorithm(stats.NumIterationsRequired, stats.ResidualNormRatioEstimation);
            return(lagranges);
        }
Esempio n. 5
0
        private static void TestSparseSystem(LinearAlgebraProviderChoice providers)
        {
            TestSettings.RunMultiproviderTest(providers, delegate()
            {
                var A         = Matrix.CreateFromArray(SparsePosDef10by10.Matrix);
                var b         = Vector.CreateFromArray(SparsePosDef10by10.Rhs);
                var xExpected = Vector.CreateFromArray(SparsePosDef10by10.Lhs);

                var builder = new CGAlgorithm.Builder();
                builder.ResidualTolerance     = 1E-7;
                builder.MaxIterationsProvider = new PercentageMaxIterationsProvider(1.0);
                var cg                    = builder.Build();
                var xComputed             = Vector.CreateZero(A.NumRows);
                IterativeStatistics stats = cg.Solve(A, b, xComputed, true);
                comparer.AssertEqual(xExpected, xComputed);
            });
        }
        private static void TestPosDefSparseSystem()
        {
            var A         = Matrix.CreateFromArray(SparsePosDef10by10.Matrix);
            var b         = Vector.CreateFromArray(SparsePosDef10by10.Rhs);
            var xExpected = Vector.CreateFromArray(SparsePosDef10by10.Lhs);

            var builder = new ReorthogonalizedPcg.Builder();

            builder.ResidualTolerance     = 1E-7;
            builder.MaxIterationsProvider = new PercentageMaxIterationsProvider(1.0);
            var    pcg                = builder.Build();
            var    M                  = new JacobiPreconditioner(A.GetDiagonalAsArray());
            Vector xComputed          = Vector.CreateZero(A.NumRows);
            IterativeStatistics stats = pcg.Solve(A, M, b, xComputed, true, () => Vector.CreateZero(b.Length));

            comparer.AssertEqual(xExpected, xComputed);
        }
Esempio n. 7
0
        private static void TestPosDefSparseSystem(LinearAlgebraProviderChoice providers)
        {
            TestSettings.RunMultiproviderTest(providers, delegate()
            {
                var A         = Matrix.CreateFromArray(SparsePosDef10by10.Matrix);
                var b         = Vector.CreateFromArray(SparsePosDef10by10.Rhs);
                var xExpected = Vector.CreateFromArray(SparsePosDef10by10.Lhs);

                var builder = new PcgAlgorithm.Builder();
                builder.ResidualTolerance     = 1E-7;
                builder.MaxIterationsProvider = new PercentageMaxIterationsProvider(1.0);
                var pcg                   = builder.Build();
                var M                     = new JacobiPreconditioner(A.GetDiagonalAsArray());
                Vector xComputed          = Vector.CreateZero(A.NumRows);
                IterativeStatistics stats = pcg.Solve(A, M, b, xComputed, true, () => Vector.CreateZero(b.Length));
                comparer.AssertEqual(xExpected, xComputed);
            });
        }
        private static void TestNearbyProblems(double noiseWidth, int maxIterations, int numRhsVectors)
        {
            int order   = SymmPosDef10by10.Order;
            var A       = Matrix.CreateFromArray(SymmPosDef10by10.Matrix);
            var builder = new ReorthogonalizedPcg.Builder();

            builder.ResidualTolerance     = 1E-6;
            builder.MaxIterationsProvider = new PercentageMaxIterationsProvider(1.0);
            builder.Convergence           = new RhsNormalizedConvergence();
            var pcg = builder.Build();
            var M   = new JacobiPreconditioner(A.GetDiagonalAsArray());

            // Initial run
            Vector x0                  = Vector.CreateWithValue(order, 1);
            Vector x0Expected          = x0.Copy();
            Vector b0                  = A * x0Expected;
            Vector x0Computed          = Vector.CreateZero(A.NumRows);
            IterativeStatistics stats0 = pcg.Solve(A, M, b0, x0Computed, true, () => Vector.CreateZero(order));

            Debug.WriteLine($"Initial run: iterations = {stats0.NumIterationsRequired}");
            comparer.AssertEqual(x0Expected, x0Computed);

            // Subsequent runs
            int seed = 345;

            for (int i = 0; i < numRhsVectors; ++i)
            {
                Vector dx        = Vector.CreateFromArray(RandomMatrices.CreateRandomVector(order, seed));
                Vector xExpected = x0 + noiseWidth * dx;
                Vector b         = A * xExpected;

                pcg.Clear();                 //TODO: preferably do not call this.
                //pcg.ReorthoCache.Clear();

                Vector xComputed          = Vector.CreateZero(A.NumRows);
                IterativeStatistics stats = pcg.Solve(A, M, b, xComputed, true, () => Vector.CreateZero(b.Length));
                Debug.WriteLine($"Subsequent run: iterations = {stats.NumIterationsRequired}");
                comparer.AssertEqual(xExpected, xComputed);
                Assert.InRange(stats.NumIterationsRequired, 1, maxIterations);
            }
        }
        /// <summary>
        /// Solves the linear system with PCG method. If the matrix has been modified, a new preconditioner will be computed.
        /// </summary>
        public override void Solve()
        {
            var watch = new Stopwatch();

            if (linearSystem.SolutionConcrete == null)
            {
                linearSystem.SolutionConcrete = linearSystem.CreateZeroVectorConcrete();
            }
            else
            {
                linearSystem.SolutionConcrete.Clear();
            }

            // Preconditioning
            if (mustUpdatePreconditioner)
            {
                watch.Start();
                preconditioner = preconditionerFactory.CreatePreconditionerFor(linearSystem.Matrix);
                watch.Stop();
                Logger.LogTaskDuration("Calculating preconditioner", watch.ElapsedMilliseconds);
                watch.Reset();
                mustUpdatePreconditioner = false;
            }

            // Iterative algorithm
            watch.Start();
            IterativeStatistics stats = pcgAlgorithm.Solve(linearSystem.Matrix, preconditioner, linearSystem.RhsConcrete,
                                                           linearSystem.SolutionConcrete, true, () => linearSystem.CreateZeroVector()); //TODO: This way, we don't know that x0=0, which will result in an extra b-A*0

            if (!stats.HasConverged)
            {
                throw new IterativeSolverNotConvergedException(Name + " did not converge to a solution. PCG algorithm run for"
                                                               + $" {stats.NumIterationsRequired} iterations and the residual norm ratio was"
                                                               + $" {stats.ResidualNormRatioEstimation}");
            }
            watch.Stop();
            Logger.LogTaskDuration("Iterative algorithm", watch.ElapsedMilliseconds);
            Logger.LogIterativeAlgorithm(stats.NumIterationsRequired, stats.ResidualNormRatioEstimation);
            Logger.IncrementAnalysisStep();
        }
        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);
        }
Esempio n. 11
0
        public Vector CalcLagrangeMultipliers(Feti1FlexibilityMatrix flexibility, IFetiPreconditioner preconditioner,
                                              Feti1Projection projection, Vector disconnectedDisplacements, Vector rigidBodyModesWork, double globalForcesNorm,
                                              SolverLogger logger)
        {
            // PCPG starts from the particular lagrange multipliers: λ0 = Q * G * inv(G^T * Q * G) * e
            Vector lagranges = projection.CalcParticularLagrangeMultipliers(rigidBodyModesWork);
            IFetiPcgConvergence pcpgConvergenceStrategy =
                pcgConvergenceStrategyFactory.CreateConvergenceStrategy(globalForcesNorm);
            var pcpg = new PcpgAlgorithm(maxIterationsProvider, pcpgConvergenceTolerance, pcpgConvergenceStrategy);
            IterativeStatistics stats =
                pcpg.Solve(flexibility, preconditioner, projection, disconnectedDisplacements, lagranges);

            if (!stats.HasConverged)
            {
                throw new IterativeSolverNotConvergedException(Feti1Solver.name + " did not converge to a solution. PCPG"
                                                               + $" algorithm run for {stats.NumIterationsRequired} iterations and the residual norm ratio was"
                                                               + $" {stats.ResidualNormRatioEstimation}");
            }

            // Log statistics about PCG execution
            logger.LogIterativeAlgorithm(stats.NumIterationsRequired, stats.ResidualNormRatioEstimation);
            return(lagranges);
        }
Esempio n. 12
0
        //[Fact]
        private static void InvestigateNoiseStagnation()
        {
            double noiseWidth = 100;

            int order = 100;
            //var A = Matrix.CreateFromArray(MultiDiagonalMatrices.CreateSymmetric(order, new int[] { 0, 1, 5, 7, 12 }));
            var valueOfEachDiagonal = new Dictionary <int, double>();

            valueOfEachDiagonal[0] = 10.0;
            valueOfEachDiagonal[1] = 4.0;
            valueOfEachDiagonal[5] = 3.0;
            var A = Matrix.CreateFromArray(MultiDiagonalMatrices.CreateSymmetric(order, valueOfEachDiagonal));
            var M = new IdentityPreconditioner();
            //var M = new JacobiPreconditioner(A.GetDiagonalAsArray());

            // Method A: Regular PCG
            var pcgBuilder = new PcgAlgorithm.Builder();

            pcgBuilder.ResidualTolerance     = 1E-15;
            pcgBuilder.MaxIterationsProvider = new FixedMaxIterationsProvider(50);
            var pcg = pcgBuilder.Build();

            // Method B: Reorthogonalized PCG, but without keeping direction vectors from previous solutions.
            var pcgReorthoRestartBuilder = new ReorthogonalizedPcg.Builder();

            pcgReorthoRestartBuilder.ResidualTolerance     = 1E-15;
            pcgReorthoRestartBuilder.MaxIterationsProvider = new FixedMaxIterationsProvider(50);
            var pcgReorthoRestart = pcgReorthoRestartBuilder.Build();

            // Method C: Reorthogonalized PCG, where the second solution will reuse direction vectors from the first
            var pcgReorthoBuilder = new ReorthogonalizedPcg.Builder();

            pcgReorthoBuilder.ResidualTolerance     = 1E-15;
            pcgReorthoBuilder.MaxIterationsProvider = new FixedMaxIterationsProvider(50);
            var pcgReortho = pcgReorthoBuilder.Build();

            // Initial rhs
            Vector x0         = Vector.CreateWithValue(order, 1);
            Vector x0Expected = x0.Copy();
            Vector b0         = A * x0Expected;

            Vector xA = Vector.CreateZero(A.NumRows);
            IterativeStatistics statsA = pcg.Solve(A, M, b0, xA, true, () => Vector.CreateZero(order));

            Debug.WriteLine($"Initial run - method A: iterations = {statsA.NumIterationsRequired}");

            Vector xB = Vector.CreateZero(A.NumRows);
            IterativeStatistics statsB = pcgReorthoRestart.Solve(A, M, b0, xB, true, () => Vector.CreateZero(order));

            Debug.WriteLine($"Initial run - method B iterations = {statsB.NumIterationsRequired}");

            Vector xC = Vector.CreateZero(A.NumRows);
            IterativeStatistics statsC = pcgReortho.Solve(A, M, b0, xC, true, () => Vector.CreateZero(order));

            Debug.WriteLine($"Initial run - method C: iterations = {statsC.NumIterationsRequired}");

            // Perturbed rhs
            int    seed = 345;
            Vector dx   = Vector.CreateFromArray(RandomMatrices.CreateRandomVector(order, seed));

            Vector x1Expected = x0 + noiseWidth * dx;
            Vector b1         = A * x1Expected;

            xA     = Vector.CreateZero(A.NumRows);
            statsA = pcg.Solve(A, M, b1, xA, true, () => Vector.CreateZero(order));
            Debug.WriteLine($"2nd run, noise = {noiseWidth} - method A: iterations = {statsA.NumIterationsRequired}");

            xB = Vector.CreateZero(A.NumRows);
            pcgReorthoRestart.ReorthoCache.Clear();
            statsB = pcgReorthoRestart.Solve(A, M, b1, xB, true, () => Vector.CreateZero(order));
            Debug.WriteLine($"2nd run, noise = {noiseWidth} - method B iterations = {statsB.NumIterationsRequired}");

            xC     = Vector.CreateZero(A.NumRows);
            statsC = pcgReortho.Solve(A, M, b1, xC, true, () => Vector.CreateZero(order));
            Debug.WriteLine($"2nd run, noise = {noiseWidth} - method C: iterations = {statsC.NumIterationsRequired}");
        }
Esempio n. 13
0
        //[Fact]
        private static void InvestigatePFetiDPCoarseProblem2D()
        {
            int order = PFetiDPCoarseProblem2D.Order;
            var A     = Matrix.CreateFromArray(PFetiDPCoarseProblem2D.MatrixScc);
            var M     = new IdentityPreconditioner();

            // Method A: Regular PCG
            var pcgBuilder = new PcgAlgorithm.Builder();

            pcgBuilder.ResidualTolerance     = 1E-20;
            pcgBuilder.MaxIterationsProvider = new FixedMaxIterationsProvider(50);
            var pcg = pcgBuilder.Build();

            // Method B: Reorthogonalized PCG, but without keeping direction vectors from previous solutions.
            var pcgReorthoRestartBuilder = new ReorthogonalizedPcg.Builder();

            pcgReorthoRestartBuilder.ResidualTolerance     = 1E-20;
            pcgReorthoRestartBuilder.MaxIterationsProvider = new FixedMaxIterationsProvider(50);
            var pcgReorthoRestart = pcgReorthoRestartBuilder.Build();

            // Method C: Reorthogonalized PCG, where the second solution will reuse direction vectors from the first
            var pcgReorthoBuilder = new ReorthogonalizedPcg.Builder();

            pcgReorthoBuilder.ResidualTolerance     = 1E-20;
            pcgReorthoBuilder.MaxIterationsProvider = new FixedMaxIterationsProvider(50);
            var pcgReortho = pcgReorthoBuilder.Build();

            // Initial rhs
            var b         = Vector.CreateFromArray(PFetiDPCoarseProblem2D.RhsVectors[0]);
            var xExpected = Vector.CreateFromArray(PFetiDPCoarseProblem2D.SolutionVectors[0]);

            Vector xA = Vector.CreateZero(A.NumRows);
            IterativeStatistics statsA = pcg.Solve(A, M, b, xA, true, () => Vector.CreateZero(order));

            Assert.True(xExpected.Equals(xA, 1E-10));
            Debug.WriteLine($"Initial run - method A: iterations = {statsA.NumIterationsRequired}");

            Vector xB = Vector.CreateZero(A.NumRows);
            IterativeStatistics statsB = pcgReorthoRestart.Solve(A, M, b, xB, true, () => Vector.CreateZero(order));

            Assert.True(xExpected.Equals(xB, 1E-10));
            Debug.WriteLine($"Initial run - method B iterations = {statsB.NumIterationsRequired}");

            Vector xC = Vector.CreateZero(A.NumRows);
            IterativeStatistics statsC = pcgReortho.Solve(A, M, b, xC, true, () => Vector.CreateZero(order));

            Assert.True(xExpected.Equals(xC, 1E-10));
            Debug.WriteLine($"Initial run - method C: iterations = {statsC.NumIterationsRequired}");

            // Next rhs
            b         = Vector.CreateFromArray(PFetiDPCoarseProblem2D.RhsVectors[1]);
            xExpected = Vector.CreateFromArray(PFetiDPCoarseProblem2D.SolutionVectors[1]);

            xA     = Vector.CreateZero(A.NumRows);
            statsA = pcg.Solve(A, M, b, xA, true, () => Vector.CreateZero(order));
            Assert.True(xExpected.Equals(xA, 1E-10));
            Debug.WriteLine($"Initial run - method A: iterations = {statsA.NumIterationsRequired}");

            xB = Vector.CreateZero(A.NumRows);
            pcgReorthoRestart.ReorthoCache.Clear();
            statsB = pcgReorthoRestart.Solve(A, M, b, xB, true, () => Vector.CreateZero(order));
            Assert.True(xExpected.Equals(xB, 1E-10));
            Debug.WriteLine($"Initial run - method B iterations = {statsB.NumIterationsRequired}");

            xC     = Vector.CreateZero(A.NumRows);
            statsC = pcgReortho.Solve(A, M, b, xC, true, () => Vector.CreateZero(order));
            Assert.True(xExpected.Equals(xC, 1E-10));
            Debug.WriteLine($"Initial run - method C: iterations = {statsC.NumIterationsRequired}");
        }