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; }
SolveModelWithSubdomains(double stiffnessRatio, InterfaceSolver interfaceSolver, Precond precond, MatrixQ q, Residual residualConvergence, double factorizationTolerance, double pcgConvergenceTolerance) { // Model Model multiSubdomainModel = CreateModel(stiffnessRatio); // Solver var factorizationTolerances = new Dictionary <int, double>(); foreach (Subdomain s in multiSubdomainModel.Subdomains) { factorizationTolerances[s.ID] = factorizationTolerance; } //var fetiMatrices = new DenseFeti1SubdomainMatrixManager.Factory(); //var fetiMatrices = new SkylineFeti1SubdomainMatrixManager.Factory(); var fetiMatrices = new SkylineFeti1SubdomainMatrixManager.Factory(new OrderingAmdCSparseNet()); var solverBuilder = new Feti1Solver.Builder(fetiMatrices, factorizationTolerances); // Homogeneous/heterogeneous problem, matrix Q. solverBuilder.ProblemIsHomogeneous = stiffnessRatio == 1.0; if (q == MatrixQ.Identity) { solverBuilder.ProjectionMatrixQIsIdentity = true; } else { solverBuilder.ProjectionMatrixQIsIdentity = false; } // Preconditioner if (precond == Precond.Lumped) { solverBuilder.PreconditionerFactory = new LumpedPreconditioner.Factory(); } else if (precond == Precond.DirichletDiagonal) { solverBuilder.PreconditionerFactory = new DiagonalDirichletPreconditioner.Factory(); } else { solverBuilder.PreconditionerFactory = new DirichletPreconditioner.Factory(); } // PCG may need to use the exact residual for the comparison with the expected values bool residualIsExact = residualConvergence == Residual.Exact; ExactFeti1PcgConvergence.Factory exactResidualConvergence = null; if (residualIsExact) { exactResidualConvergence = new ExactFeti1PcgConvergence.Factory( CreateSingleSubdomainModel(stiffnessRatio), solverBuilder.DofOrderer, (model, solver) => new ProblemStructural(model, solver)); } // Lagrange separation method if (interfaceSolver == InterfaceSolver.Method1) { var interfaceProblemSolverBuilder = new Feti1UnprojectedInterfaceProblemSolver.Builder(); interfaceProblemSolverBuilder.MaxIterationsProvider = new FixedMaxIterationsProvider(maxIterations); interfaceProblemSolverBuilder.PcgConvergenceTolerance = pcgConvergenceTolerance; if (residualIsExact) { interfaceProblemSolverBuilder.PcgConvergenceStrategyFactory = exactResidualConvergence; } Feti1UnprojectedInterfaceProblemSolver interfaceProblemSolver = interfaceProblemSolverBuilder.Build(); solverBuilder.InterfaceProblemSolver = interfaceProblemSolver; } else { var interfaceProblemSolverBuilder = new Feti1ProjectedInterfaceProblemSolver.Builder(); interfaceProblemSolverBuilder.MaxIterationsProvider = new FixedMaxIterationsProvider(maxIterations); interfaceProblemSolverBuilder.PcgConvergenceTolerance = pcgConvergenceTolerance; if (residualIsExact) { interfaceProblemSolverBuilder.PcgConvergenceStrategyFactory = exactResidualConvergence; } if (interfaceSolver == InterfaceSolver.Method2) { interfaceProblemSolverBuilder.LagrangeSeparation = Feti1ProjectedInterfaceProblemSolver.LagrangeMultiplierSeparation.Simple; interfaceProblemSolverBuilder.ProjectionSideMatrix = Feti1ProjectedInterfaceProblemSolver.ProjectionSide.Left; interfaceProblemSolverBuilder.ProjectionSidePreconditioner = Feti1ProjectedInterfaceProblemSolver.ProjectionSide.Left; } else if (interfaceSolver == InterfaceSolver.Method3) { interfaceProblemSolverBuilder.LagrangeSeparation = Feti1ProjectedInterfaceProblemSolver.LagrangeMultiplierSeparation.WithProjection; interfaceProblemSolverBuilder.ProjectionSideMatrix = Feti1ProjectedInterfaceProblemSolver.ProjectionSide.Both; interfaceProblemSolverBuilder.ProjectionSidePreconditioner = Feti1ProjectedInterfaceProblemSolver.ProjectionSide.None; } else if (interfaceSolver == InterfaceSolver.Method4) { interfaceProblemSolverBuilder.LagrangeSeparation = Feti1ProjectedInterfaceProblemSolver.LagrangeMultiplierSeparation.WithProjection; interfaceProblemSolverBuilder.ProjectionSideMatrix = Feti1ProjectedInterfaceProblemSolver.ProjectionSide.Both; interfaceProblemSolverBuilder.ProjectionSidePreconditioner = Feti1ProjectedInterfaceProblemSolver.ProjectionSide.Left; } else // default { interfaceProblemSolverBuilder.LagrangeSeparation = Feti1ProjectedInterfaceProblemSolver.LagrangeMultiplierSeparation.WithProjection; interfaceProblemSolverBuilder.ProjectionSideMatrix = Feti1ProjectedInterfaceProblemSolver.ProjectionSide.Both; interfaceProblemSolverBuilder.ProjectionSidePreconditioner = Feti1ProjectedInterfaceProblemSolver.ProjectionSide.Both; } Feti1ProjectedInterfaceProblemSolver interfaceProblemSolver = interfaceProblemSolverBuilder.Build(); solverBuilder.InterfaceProblemSolver = interfaceProblemSolver; // Only needed in methods 2,3,4, default (where there is lagrange separation) if (residualIsExact) { exactResidualConvergence.InterfaceProblemSolver = interfaceProblemSolver; } } Feti1Solver fetiSolver = solverBuilder.BuildSolver(multiSubdomainModel); if (residualIsExact) { exactResidualConvergence.FetiSolver = fetiSolver; } // Structural problem provider var provider = new ProblemStructural(multiSubdomainModel, fetiSolver); // Linear static analysis var childAnalyzer = new LinearAnalyzer(multiSubdomainModel, fetiSolver, provider); var parentAnalyzer = new StaticAnalyzer(multiSubdomainModel, fetiSolver, provider, childAnalyzer); // Run the analysis parentAnalyzer.Initialize(); parentAnalyzer.Solve(); // Gather the global displacements var sudomainDisplacements = new Dictionary <int, IVectorView>(); foreach (var ls in fetiSolver.LinearSystems) { sudomainDisplacements[ls.Key] = ls.Value.Solution; } Vector globalDisplacements = fetiSolver.GatherGlobalDisplacements(sudomainDisplacements); // Other stats int numUniqueGlobalDofs = multiSubdomainModel.Nodes.Count * 2; int numExtenedDomainDofs = 0; foreach (var subdomain in multiSubdomainModel.Subdomains) { numExtenedDomainDofs += subdomain.Nodes.Count * 2; } return(globalDisplacements, fetiSolver.Logger, numUniqueGlobalDofs, numExtenedDomainDofs); }