public static void TestSolver()
        {
            // 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);
            var problem        = new ProblemStructural(model, solver);
            var linearAnalyzer = new LinearAnalyzer(model, solver, problem);
            var staticAnalyzer = new StaticAnalyzer(model, solver, problem, linearAnalyzer);

            // Run the analysis
            staticAnalyzer.Initialize();
            staticAnalyzer.Solve();

            // Gather the global displacements
            var sudomainDisplacements = new Dictionary <int, IVectorView>();

            foreach (var ls in solver.LinearSystems)
            {
                sudomainDisplacements[ls.Key] = ls.Value.Solution;
            }
            Vector globalU = solver.GatherGlobalDisplacements(sudomainDisplacements);

            // Check against expected solution
            double tol = 1E-7;

            Assert.True(SolutionGlobalDisplacements.Equals(globalU, tol));
        }
        public static void TestDisconnectedDisplacements()
        {
            //TODO: Perhaps use the Br, Bc from the class that tests them instead of the solver.

            Model model = Quads4x4MappingMatricesTests.CreateModel();
            Dictionary <int, HashSet <INode> > cornerNodes = Quads4x4MappingMatricesTests.DefineCornerNodes(model);
            var          fetiMatrices        = new DenseFetiDPSubdomainMatrixManager.Factory();
            var          cornerNodeSelection = new UsedDefinedCornerNodes(cornerNodes);
            FetiDPSolver solver = new FetiDPSolver.Builder(cornerNodeSelection, fetiMatrices).BuildSolver(model);

            model.ConnectDataStructures();
            solver.OrderDofs(false);
            solver.Initialize();

            // Mock the stiffness matrices and force vectors
            var fr = VectorsFr;
            Dictionary <int, IFetiDPSubdomainMatrixManager> matrixManagers = MockStiffnesses();

            // Use reflection to set the necessary matrices
            FieldInfo fi;

            fi = typeof(FetiDPSolver).GetField("matrixManagers", BindingFlags.NonPublic | BindingFlags.Instance);
            fi.SetValue(solver, matrixManagers);

            Vector dr         = solver.CalcDisconnectedDisplacements(fr);
            var    expectedDr = VectorDr;

            double tol = 1E-13;

            Assert.True(expectedDr.Equals(dr, 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 TestCoarseProblem()
        {
            // 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();

            // Use the hardcoded intermediate matrices & vectors
            Dictionary <int, IFetiDPSubdomainMatrixManager> matrixManagers = MockStiffnesses();
            Dictionary <int, Vector> fbc = VectorsFbc;
            Dictionary <int, Vector> fr  = VectorsFr;

            // Access private fields of FetiDPSolver
            FieldInfo fi           = typeof(FetiDPSolver).GetField("dofSeparator", BindingFlags.NonPublic | BindingFlags.Instance);
            var       dofSeparator = (FetiDPDofSeparator)fi.GetValue(solver);

            // Calculate the coarse problem matrix and rhs
            var        coarseSolver = new DenseFetiDPCoarseProblemSolver(model.Subdomains);
            Vector     globalFcStar = coarseSolver.CreateCoarseProblemRhs(dofSeparator, matrixManagers, fr, fbc);
            MethodInfo method       = coarseSolver.GetType().GetMethod("CreateGlobalKccStar",
                                                                       BindingFlags.NonPublic | BindingFlags.Instance); // reflection for the private method
            Matrix globalKccStar = (Matrix)method.Invoke(coarseSolver, new object[] { dofSeparator, matrixManagers });

            // Check against expected matrices
            var    expectedKccStar = MatrixKccStar;
            var    expectedFcStar  = VectorFcStar;
            double tol             = 1E-13;

            Assert.True(expectedKccStar.Equals(globalKccStar, tol));
            Assert.True(expectedFcStar.Equals(globalFcStar, tol));
        }
        public static void TestFlexibilityMatrices()
        {
            // 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
            Dictionary <int, IFetiDPSubdomainMatrixManager> matrixManagers = MockStiffnesses();

            // 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);

            // Create the flexibility matrices by multiplying with identity matrices
            int    numLagranges  = lagrangeEnumerator.NumLagrangeMultipliers;
            int    numCornerDofs = dofSeparator.NumGlobalCornerDofs;
            var    flexibility   = new FetiDPFlexibilityMatrix(dofSeparator, lagrangeEnumerator, matrixManagers);
            Matrix FIrr          = MultiplyWithIdentity(numLagranges, numLagranges, flexibility.MultiplyFIrr);
            Matrix FIrc          = MultiplyWithIdentity(numLagranges, numLagranges, (x, y) => y.CopyFrom(flexibility.MultiplyFIrc(x)));

            // Check against expected matrices
            double tol = 1E-11;

            Assert.True(MatrixFIrr.Equals(FIrr, tol));
            Assert.True(MatrixFIrc.Equals(FIrc, 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));
        }