private Vector CreateInterfaceProblemRhs(FetiDPFlexibilityMatrix flexibility, IFetiDPCoarseProblemSolver coarseProblemSolver, Vector globalFcStar, Vector dr) { // rhs = dr - FIrc * inv(KccStar) * fcStar Vector rhs = coarseProblemSolver.MultiplyInverseCoarseProblemMatrixTimes(globalFcStar); rhs = flexibility.MultiplyFIrc(rhs); rhs = dr - rhs; return(rhs); }
internal InterfaceProblemMatrix(FetiDPFlexibilityMatrix flexibility, IFetiDPCoarseProblemSolver coarseProblemSolver) { this.flexibility = flexibility; this.coarseProblemSolver = coarseProblemSolver; }
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 FetiDPSolver(IModel model, ICornerNodeSelection cornerNodeSelection, IFetiDPSubdomainMatrixManagerFactory matrixManagerFactory, IDofOrderer dofOrderer, IFetiPreconditionerFactory preconditionerFactory, bool problemIsHomogeneous, IFetiDPInterfaceProblemSolver interfaceProblemSolver) { // Model if (model.Subdomains.Count == 1) { throw new InvalidSolverException( $"{name} cannot be used if there is only 1 subdomain"); } this.model = model; this.cornerNodeSelection = cornerNodeSelection; // Subdomains subdomains = new Dictionary <int, ISubdomain>(); foreach (ISubdomain subdomain in model.Subdomains) { subdomains[subdomain.ID] = subdomain; } // Matrix managers and linear systems matrixManagers = new Dictionary <int, IFetiDPSubdomainMatrixManager>(); matrixManagersGeneral = new Dictionary <int, IFetiSubdomainMatrixManager>(); this.linearSystems = new Dictionary <int, ISingleSubdomainLinearSystem>(); var externalLinearSystems = new Dictionary <int, ILinearSystem>(); foreach (ISubdomain subdomain in model.Subdomains) { int s = subdomain.ID; var matrixManager = matrixManagerFactory.CreateMatricesManager(subdomain); matrixManagers[s] = matrixManager; matrixManagersGeneral[s] = matrixManager; this.linearSystems[s] = matrixManager.LinearSystem; externalLinearSystems[s] = matrixManager.LinearSystem; //TODO: This will call HandleMatrixWillBeSet() once for each subdomain. For now I will clear the data when // BuildMatrices() is called. Redesign this. //matrixManager.LinearSystem.MatrixObservers.Add(this); } LinearSystems = externalLinearSystems; this.dofOrderer = dofOrderer; this.dofSeparator = new FetiDPDofSeparator(); this.preconditionerFactory = preconditionerFactory; // Interface problem this.coarseProblemSolver = matrixManagerFactory.CreateCoarseProblemSolver(model.Subdomains); this.interfaceProblemSolver = interfaceProblemSolver; // Homogeneous/heterogeneous problems this.problemIsHomogeneous = problemIsHomogeneous; if (problemIsHomogeneous) { this.stiffnessDistribution = new HomogeneousStiffnessDistribution(model, dofSeparator); } else { this.stiffnessDistribution = new HeterogeneousStiffnessDistribution(model, dofSeparator); } }