Ejemplo n.º 1
0
        private PcgMatrix DefinePcgMatrix(Feti1FlexibilityMatrix flexibility, Feti1Projection projection)
        {
            //TODO: projection.ProjectVector() overwrites the rhs vector passed in. However that is not clear by the method.
            //      I should either always return the resulting vector (negating any optimizations) or set the convention that
            //      vectors passed in as results will always be overwritten. The latter forces the method that accepts them to
            //      clear them (if the method needs to), which is not needed if the resulting vector has just be initialized to 0.

            if (projectionSideMatrix == ProjectionSide.Left)
            {
                // A * x = (P^T * F) * x = P^T * (F * x)
                return(new PcgMatrix(flexibility.Order, (x, y) => projection.ProjectVector(flexibility.Multiply(x), y, true)));
            }
            else if (projectionSideMatrix == ProjectionSide.Both)
            {
                // A * x = (P^T * F * P) * x = P^T * (F * (P * x))
                return(new PcgMatrix(flexibility.Order, (x, y) =>
                {
                    var temp = Vector.CreateZero(flexibility.Order);
                    projection.ProjectVector(x, temp, false);
                    projection.ProjectVector(flexibility.Multiply(temp), y, true);
                }));
            }
            else
            {
                throw new ArgumentException("The FETI-1 flexibility matrix can be multiplied from the left or both sides.");
            }
        }
Ejemplo n.º 2
0
        private readonly Vector lagrangesParticular;                                  // only needed when separating the lagranges during PCG

        public ExactFeti1PcgConvergence(IMatrixView globalStiffness, IVectorView globalForces, double globalForcesNorm,
                                        Feti1Solver fetiSolver, Feti1ProjectedInterfaceProblemSolver interfaceProblemSolver,
                                        Feti1Projection projection, Vector lagrangesParticular)
        {
            this.globalStiffness        = globalStiffness;
            this.globalForces           = globalForces;
            this.globalForcesNorm       = globalForcesNorm;
            this.fetiSolver             = fetiSolver;
            this.interfaceProblemSolver = interfaceProblemSolver;
            this.projection             = projection;
            this.lagrangesParticular    = lagrangesParticular;
        }
Ejemplo n.º 3
0
 private void BuildProjection()
 {
     if (!projectionMatrixQIsIdentity) // Previously (pde == PdeOrder.Fourth) || (!problemIsHomogeneous)
     {
         // Q = preconditioner
         projection = new Feti1Projection(lagrangeEnumerator.BooleanMatrices, matrixManagers,
                                          new PreconditionerAsMatrixQ(preconditioner));
     }
     else
     {
         // Q = indentity
         projection = new Feti1Projection(lagrangeEnumerator.BooleanMatrices, matrixManagers, new IdentityMatrixQ());
     }
     projection.InvertCoarseProblemMatrix();
 }
Ejemplo n.º 4
0
 public void HandleMatrixWillBeSet()
 {
     isStiffnessModified = true;
     foreach (ISubdomain subdomain in subdomains.Values)
     {
         if (subdomain.StiffnessModified)
         {
             Debug.WriteLine($"{this.GetType().Name}: Clearing saved matrices of subdomain {subdomain.ID}.");
             matrixManagers[subdomain.ID].Clear();
         }
     }
     flexibility    = null;
     preconditioner = null;
     projection     = null;
     //stiffnessDistribution = null; //WARNING: do not dispose of this. It is updated when BuildGlobalMatrix() is called.
 }
Ejemplo n.º 5
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);
        }
Ejemplo n.º 6
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);
        }
Ejemplo n.º 7
0
 private PcgPreconditioner DefinePcgPreconditioner(IFetiPreconditioner preconditioner, Feti1Projection projection)
 {
     if (projectionSidePreconditioner == ProjectionSide.None)
     {
         // x = prec(A) * y => x = prec(F) * y
         return(new PcgPreconditioner((x, y) => preconditioner.SolveLinearSystem(y, x)));
     }
     else if (projectionSidePreconditioner == ProjectionSide.Left)
     {
         // x = prec(A) * y => x = (P * prec(F)) * y => x = P * (prec(F) * y)
         return(new PcgPreconditioner((y, x) =>
         {
             int order = y.Length;
             var temp = Vector.CreateZero(order);
             preconditioner.SolveLinearSystem(y, temp);
             projection.ProjectVector(temp, x, false);
         }));
     }
     else if (projectionSidePreconditioner == ProjectionSide.Both)
     {
         // x = prec(A) * y => x = (P * prec(F) * P^T) * y => x = P * (prec(F) * (P^T * y))
         return(new PcgPreconditioner((y, x) =>
         {
             int order = y.Length;
             var temp1 = Vector.CreateZero(order);
             projection.ProjectVector(y, temp1, true);
             var temp2 = Vector.CreateZero(order);
             preconditioner.SolveLinearSystem(temp1, temp2);
             projection.ProjectVector(temp2, x, false);
         }));
     }
     else
     {
         throw new ArgumentException(
                   "The FETI-1 preconditioner can be multiplied from the left side, both sides or not at all.");
     }
 }
Ejemplo n.º 8
0
 /// <summary>
 /// Calculates the actual lagrange multipliers depending on the separation formula.
 /// </summary>
 internal Vector CombineLagrangeMultipliers(Vector lagrangesParticular, Vector lagrangesBar, Feti1Projection projection)
 {
     if (lagrangeSeparation == LagrangeMultiplierSeparation.Simple)
     {
         // λ = λ0 + P * λbar
         return(lagrangesBar + lagrangesParticular);
     }
     else if (lagrangeSeparation == LagrangeMultiplierSeparation.WithProjection)
     {
         // λ = λ0 + P * λbar
         var lagranges = Vector.CreateZero(lagrangesBar.Length);
         projection.ProjectVector(lagrangesBar, lagranges, false);
         lagranges.AddIntoThis(lagrangesParticular);
         return(lagranges);
     }
     else
     {
         throw new ArgumentException("The lagrange separation can only be: a) λ = λ0 + λbar or b) λ = λ0 + P * λbar");
     }
 }