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