public static void TestSolver() { // Setup the model double stiffnessRatio = 1E-2; // Do not change this! The expected solution is taken for this value Model model = CreateModel(stiffnessRatio); Dictionary <int, HashSet <INode> > cornerNodes = Quads4x4MappingMatricesTests.DefineCornerNodes(model); // Setup solver var interfaceSolverBuilder = new FetiDPInterfaceProblemSolver.Builder(); interfaceSolverBuilder.PcgConvergenceTolerance = 1E-7; //var fetiMatrices = new SkylineFetiDPSubdomainMatrixManager.Factory(); var fetiMatrices = new DenseFetiDPSubdomainMatrixManager.Factory(); var cornerNodeSelection = new UsedDefinedCornerNodes(cornerNodes); var fetiSolverBuilder = new FetiDPSolver.Builder(cornerNodeSelection, fetiMatrices); fetiSolverBuilder.InterfaceProblemSolver = interfaceSolverBuilder.Build(); fetiSolverBuilder.ProblemIsHomogeneous = false; fetiSolverBuilder.PreconditionerFactory = new DirichletPreconditioner.Factory(); FetiDPSolver fetiSolver = fetiSolverBuilder.BuildSolver(model); // Run the analysis var problem = new ProblemStructural(model, fetiSolver); var linearAnalyzer = new LinearAnalyzer(model, fetiSolver, problem); var staticAnalyzer = new StaticAnalyzer(model, fetiSolver, problem, linearAnalyzer); staticAnalyzer.Initialize(); staticAnalyzer.Solve(); // Gather the global displacements var sudomainDisplacements = new Dictionary <int, IVectorView>(); foreach (var ls in fetiSolver.LinearSystems) { sudomainDisplacements[ls.Key] = ls.Value.Solution; } Vector globalU = fetiSolver.GatherGlobalDisplacements(sudomainDisplacements); // Check against expected solution double tol = 1E-7; var globalUExpected = Vector.CreateFromArray(new double[] { 17.623494584618864, 12.564560593215612, 31.832863897135404, 34.496634608059082, 40.255481382985629, 66.49190654178912, 42.572002358887204, 99.798764204232072, 4.267568672307144, 9.00506902466324, 9.100928263505315, 31.107370029452451, 12.1615036308774, 66.065492717632239, 11.510673148931499, 102.06649895017948, -3.0529124682202156, 9.24107474483673, -7.8531777412741217, 26.728892403726846, -16.890006178831449, 70.602493468916791, -21.80233265288679, 109.39882637058051, -4.7311061272016808, 10.030926199331375, -5.6722429958962142, 18.837815470700932, 146.94209278892487, 392.04674590737193, -35.619167413693908, 1407.200332011206, -9.9609496807814057, 10.46574373452243, -17.603838651152756, 20.760800663270086, -843.13592713307355, 371.10700308359418, -1666.2547486301742, 3714.1637893447919 }); Assert.True(globalUExpected.Equals(globalU, tol)); }
public static void TestInterfaceProblemCreation() { // Setup the model and solver Model model = Quads4x4MappingMatricesTests.CreateModel(); Dictionary <int, HashSet <INode> > cornerNodes = Quads4x4MappingMatricesTests.DefineCornerNodes(model); var fetiMatrices = new DenseFetiDPSubdomainMatrixManager.Factory(); var cornerNodeSelection = new UsedDefinedCornerNodes(cornerNodes); var solver = new FetiDPSolver.Builder(cornerNodeSelection, fetiMatrices).BuildSolver(model); model.ConnectDataStructures(); solver.OrderDofs(false); solver.Initialize(); // Mock the stiffness matrices and force vectors Dictionary <int, IFetiDPSubdomainMatrixManager> matrixManagers = MockStiffnesses(); Vector dr = VectorDr; // Access private fields of FetiDPSolver FieldInfo fi = typeof(FetiDPSolver).GetField("lagrangeEnumerator", BindingFlags.NonPublic | BindingFlags.Instance); var lagrangeEnumerator = (FetiDPLagrangeMultipliersEnumerator)fi.GetValue(solver); fi = typeof(FetiDPSolver).GetField("dofSeparator", BindingFlags.NonPublic | BindingFlags.Instance); var dofSeparator = (FetiDPDofSeparator)fi.GetValue(solver); // Hardcoded coarse problem matrix and rhs var coarseSolver = new DenseFetiDPCoarseProblemSolver(model.Subdomains); Vector globalFcStar = VectorFcStar; Matrix inverseKccStar = MatrixKccStar.Invert(); // It must be set as a private field using reflection. fi = typeof(DenseFetiDPCoarseProblemSolver).GetField("inverseGlobalKccStar", BindingFlags.NonPublic | BindingFlags.Instance); fi.SetValue(coarseSolver, inverseKccStar); // Create the rhs vector of the interface problem FetiDPInterfaceProblemSolver interfaceSolver = new FetiDPInterfaceProblemSolver.Builder().Build(); var flexibility = new FetiDPFlexibilityMatrix(dofSeparator, lagrangeEnumerator, matrixManagers); Vector fcStar = VectorFcStar; MethodInfo method = interfaceSolver.GetType().GetMethod("CreateInterfaceProblemRhs", BindingFlags.NonPublic | BindingFlags.Instance); // reflection for the private method Vector interfaceRhs = (Vector)method.Invoke(interfaceSolver, new object[] { flexibility, coarseSolver, fcStar, dr }); // Create the matrix of the interface problem by multiplying with identity matrix int numLagranges = lagrangeEnumerator.NumLagrangeMultipliers; var interfaceMatrixImplicit = new FetiDPInterfaceProblemSolver.InterfaceProblemMatrix(flexibility, coarseSolver); Matrix interfaceMatrix = MultiplyWithIdentity(numLagranges, numLagranges, interfaceMatrixImplicit.Multiply); // Action<T> is contravariant!!! // Check against expected linear system double tol = 1E-13; Assert.True(InterfaceProblemVector.Equals(interfaceRhs, tol)); Assert.True(InterfaceProblemMatrix.Equals(interfaceMatrix, tol)); }
public static void TestInterfaceProblemSolution() { // Setup the model and solver Model model = Quads4x4MappingMatricesTests.CreateModel(); Dictionary <int, HashSet <INode> > cornerNodes = Quads4x4MappingMatricesTests.DefineCornerNodes(model); var fetiMatrices = new DenseFetiDPSubdomainMatrixManager.Factory(); var cornerNodeSelection = new UsedDefinedCornerNodes(cornerNodes); var solver = new FetiDPSolver.Builder(cornerNodeSelection, fetiMatrices).BuildSolver(model); model.ConnectDataStructures(); solver.OrderDofs(false); solver.Initialize(); // Mock the stiffness matrices and force vectors Dictionary <int, IFetiDPSubdomainMatrixManager> matrixManagers = MockStiffnesses(); Dictionary <int, IFetiSubdomainMatrixManager> matrixManagersPreconditioning = MockStiffnessesForPreconditioning(); Dictionary <int, Matrix> Krr = MatricesKrr; Vector dr = VectorDr; // Access private fields of FetiDPSolver FieldInfo fi = typeof(FetiDPSolver).GetField("lagrangeEnumerator", BindingFlags.NonPublic | BindingFlags.Instance); var lagrangeEnumerator = (FetiDPLagrangeMultipliersEnumerator)fi.GetValue(solver); fi = typeof(FetiDPSolver).GetField("dofSeparator", BindingFlags.NonPublic | BindingFlags.Instance); var dofSeparator = (FetiDPDofSeparator)fi.GetValue(solver); // Hardcoded coarse problem matrix and rhs var coarseSolver = new DenseFetiDPCoarseProblemSolver(model.Subdomains); Vector globalFcStar = VectorFcStar; Matrix inverseKccStar = MatrixKccStar.Invert(); // It must be set as a private field using reflection. fi = typeof(DenseFetiDPCoarseProblemSolver).GetField("inverseGlobalKccStar", BindingFlags.NonPublic | BindingFlags.Instance); fi.SetValue(coarseSolver, inverseKccStar); // Dirichlet preconditioner var precondFactory = new DirichletPreconditioner.Factory(); var repackagedKrr = new Dictionary <int, IMatrixView>(); foreach (var idMatrixPair in Krr) { repackagedKrr[idMatrixPair.Key] = idMatrixPair.Value; } var stiffnessDistribution = new HomogeneousStiffnessDistribution(model, dofSeparator); stiffnessDistribution.Update(null); IFetiPreconditioner preconditioner = precondFactory.CreatePreconditioner(model, stiffnessDistribution, dofSeparator, lagrangeEnumerator, matrixManagersPreconditioning); // Solve the interface problem FetiDPInterfaceProblemSolver interfaceSolver = new FetiDPInterfaceProblemSolver.Builder().Build(); var flexibility = new FetiDPFlexibilityMatrix(dofSeparator, lagrangeEnumerator, matrixManagers); var logger = new SolverLogger("mock FETI-DP"); (Vector lagranges, Vector uc) = interfaceSolver.SolveInterfaceProblem( flexibility, preconditioner, coarseSolver, globalFcStar, dr, GlobalForcesNorm, logger); // Check against expected solution double tol = 1E-7; Assert.True(SolutionLagrangeMultipliers.Equals(lagranges, tol)); Assert.True(SolutionCornerDisplacements.Equals(uc, tol)); }
private static (IVectorView globalDisplacements, SolverLogger logger) SolveModelWithSubdomains(double stiffnessRatio, Precond precond, Residual residualConvergence, double pcgConvergenceTolerance) { // Model Model multiSubdomainModel = CreateModel(stiffnessRatio); // Corner nodes double meshTol = 1E-6; var cornerNodesOfEachSubdomain = new Dictionary <int, HashSet <INode> >(); foreach (Subdomain subdomain in multiSubdomainModel.Subdomains) { subdomain.DefineNodesFromElements(); //TODO: This will also be called by the analyzer. INode[] corners = CornerNodeUtilities.FindCornersOfRectangle2D(subdomain); var cornerNodes = new HashSet <INode>(); foreach (INode node in corners) { if (node.Constraints.Count > 0) { continue; } if ((Math.Abs(node.X - domainLengthX) <= meshTol) && (Math.Abs(node.Y) <= meshTol)) { continue; } if ((Math.Abs(node.X - domainLengthX) <= meshTol) && (Math.Abs(node.Y - domainLengthY) <= meshTol)) { continue; } cornerNodes.Add(node); } cornerNodesOfEachSubdomain[subdomain.ID] = cornerNodes; } // Solver var fetiMatrices = new SkylineFetiDPSubdomainMatrixManager.Factory(new OrderingAmdSuiteSparse()); //var fetiMatrices = new SkylineFetiDPSubdomainMatrixManager.Factory(); //var fetiMatrices = new DenseFetiDPSubdomainMatrixManager.Factory(); var cornerNodeSelection = new UsedDefinedCornerNodes(cornerNodesOfEachSubdomain); var solverBuilder = new FetiDPSolver.Builder(cornerNodeSelection, fetiMatrices); solverBuilder.ProblemIsHomogeneous = stiffnessRatio == 1.0; //solverBuilder.ProblemIsHomogeneous = 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(); } //TODO: This needs to be implemented for FETI-DP //// PCG may need to use the exact residual for the comparison with the expected values //bool residualIsExact = residualConvergence == Residual.Exact; //ExactPcpgConvergence.Factory exactResidualConvergence = null; //if (residualIsExact) //{ // exactResidualConvergence = new ExactPcpgConvergence.Factory( // CreateSingleSubdomainModel(stiffnessRatio), solverBuilder.DofOrderer, // (model, solver) => new ProblemStructural(model, solver)); //} //if (residualIsExact) exactResidualConvergence.InterfaceProblemSolver = interfaceProblemSolver; // Specify solver for the interface problem var interfaceSolverBuilder = new FetiDPInterfaceProblemSolver.Builder(); interfaceSolverBuilder.PcgConvergenceStrategyFactory = new ApproximateResidualConvergence.Factory(); interfaceSolverBuilder.PcgConvergenceTolerance = pcgConvergenceTolerance; solverBuilder.InterfaceProblemSolver = interfaceSolverBuilder.Build(); FetiDPSolver 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); return(globalDisplacements, fetiSolver.Logger); }
public static void TestScalingMatrices() { #region Replace the next with hardcoded matrices and mocking objects // Run the analysis so that all objects are created // Setup the model double stiffnessRatio = 1E-2; // Do not change this! The expected solution is taken for this value Model model = CreateModel(stiffnessRatio); Dictionary <int, HashSet <INode> > cornerNodes = Quads4x4MappingMatricesTests.DefineCornerNodes(model); // Setup solver var interfaceSolverBuilder = new FetiDPInterfaceProblemSolver.Builder(); interfaceSolverBuilder.PcgConvergenceTolerance = 1E-7; var fetiMatrices = new DenseFetiDPSubdomainMatrixManager.Factory(); var cornerNodeSelection = new UsedDefinedCornerNodes(cornerNodes); var fetiSolverBuilder = new FetiDPSolver.Builder(cornerNodeSelection, fetiMatrices); fetiSolverBuilder.InterfaceProblemSolver = interfaceSolverBuilder.Build(); fetiSolverBuilder.ProblemIsHomogeneous = false; var preconditionerFactory = new DirichletPreconditioner.Factory(); fetiSolverBuilder.PreconditionerFactory = preconditionerFactory; FetiDPSolver fetiSolver = fetiSolverBuilder.BuildSolver(model); // Run the analysis var problem = new ProblemStructural(model, fetiSolver); var linearAnalyzer = new LinearAnalyzer(model, fetiSolver, problem); var staticAnalyzer = new StaticAnalyzer(model, fetiSolver, problem, linearAnalyzer); staticAnalyzer.Initialize(); staticAnalyzer.Solve(); #endregion // Access private fields of FetiDPSolver and DirichletPreconditioner.Factory using reflection FieldInfo fi = typeof(FetiDPSolver).GetField("lagrangeEnumerator", BindingFlags.NonPublic | BindingFlags.Instance); var lagrangeEnumerator = (FetiDPLagrangeMultipliersEnumerator)fi.GetValue(fetiSolver); fi = typeof(FetiDPSolver).GetField("dofSeparator", BindingFlags.NonPublic | BindingFlags.Instance); var dofSeparator = (FetiDPDofSeparator)fi.GetValue(fetiSolver); fi = typeof(FetiDPSolver).GetField("stiffnessDistribution", BindingFlags.NonPublic | BindingFlags.Instance); var stiffnessDistribution = (IStiffnessDistribution)fi.GetValue(fetiSolver); MethodInfo method = preconditionerFactory.GetType().GetMethod("CalcBoundaryPreconditioningBooleanMatrices", BindingFlags.NonPublic | BindingFlags.Instance); var Bpbr = (Dictionary <int, IMappingMatrix>)method.Invoke(preconditionerFactory, new object[] { stiffnessDistribution, dofSeparator, lagrangeEnumerator }); // Compare the mapping matrices against the expected ones var expectedBpbr = new Dictionary <int, Matrix>(); expectedBpbr[0] = Matrix.CreateFromArray(new double[, ] { { 0.5, 0, 0, 0 }, { 0, 0.5, 0, 0 }, { 0, 0, 0.5, 0 }, { 0, 0, 0, 0.5 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 } }); expectedBpbr[1] = Matrix.CreateFromArray(new double[, ] { { -0.5, 0, 0, 0 }, { 0, -0.5, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0.00990099009900990, 0 }, { 0, 0, 0, 0.00990099009900990 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 } }); expectedBpbr[2] = Matrix.CreateFromArray(new double[, ] { { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { -0.5, 0, 0, 0 }, { 0, -0.5, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0.00990099009900990, 0 }, { 0, 0, 0, 0.00990099009900990 } }); expectedBpbr[3] = Matrix.CreateFromArray(new double[, ] { { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { -0.990099009900990, 0, 0, 0 }, { 0, -0.990099009900990, 0, 0 }, { 0, 0, -0.990099009900990, 0 }, { 0, 0, 0, -0.990099009900990 } }); double tol = 1E-13; foreach (int s in expectedBpbr.Keys) { Matrix explicitBpr = Bpbr[s].MultiplyRight(Matrix.CreateIdentity(Bpbr[s].NumColumns)); Assert.True(expectedBpbr[s].Equals(explicitBpr, tol)); } }