public Vector CreateCoarseProblemRhs(FetiDPDofSeparator dofSeparator,
                                             Dictionary <int, IFetiDPSubdomainMatrixManager> matrixManagers,
                                             Dictionary <int, Vector> fr, Dictionary <int, Vector> fbc)
        {
            // Static condensation for the force vectors
            var globalFcStar = Vector.CreateZero(dofSeparator.NumGlobalCornerDofs);

            for (int s = 0; s < subdomains.Count; ++s)
            {
                IFetiDPSubdomainMatrixManager matrices = matrixManagers[s];

                // fcStar[s] = fbc[s] - Krc[s]^T * inv(Krr[s]) * fr[s]
                // globalFcStar = sum_over_s(Lc[s]^T * fcStar[s])
                UnsignedBooleanMatrix Lc = dofSeparator.CornerBooleanMatrices[s];
                Vector temp = matrices.MultiplyInverseKrrTimes(fr[s]);
                temp = matrices.MultiplyKcrTimes(temp);
                Vector fcStar = fbc[s] - temp;
                globalFcStar.AddIntoThis(Lc.Multiply(fcStar, true));
            }
            return(globalFcStar);
        }
        private Matrix CreateGlobalKccStar(FetiDPDofSeparator dofSeparator,
                                           Dictionary <int, IFetiDPSubdomainMatrixManager> matrixManagers)
        {
            // Static condensation of remainder dofs (Schur complement).
            var globalKccStar = Matrix.CreateZero(dofSeparator.NumGlobalCornerDofs, dofSeparator.NumGlobalCornerDofs);

            for (int s = 0; s < subdomains.Count; ++s)
            {
                IFetiDPSubdomainMatrixManager matrices = matrixManagers[s];

                // KccStar[s] = Kcc[s] - Krc[s]^T * inv(Krr[s]) * Krc[s]
                if (subdomains[s].StiffnessModified)
                {
                    Debug.WriteLine($"{this.GetType().Name}: Calculating Schur complement of remainder dofs"
                                    + " for the stiffness of subdomain {s}");
                    matrices.CalcSchurComplementOfRemainderDofs(); //TODO: At this point Kcc and Krc can be cleared. Maybe Krr too.
                }

                // globalKccStar = sum_over_s(Lc[s]^T * KccStar[s] * Lc[s])
                UnsignedBooleanMatrix Lc = dofSeparator.CornerBooleanMatrices[s];
                globalKccStar.AddIntoThis(Lc.ThisTransposeTimesOtherTimesThis(matrices.SchurComplementOfRemainderDofs));
            }
            return(globalKccStar);
        }
Ejemplo n.º 3
0
        public static void TestUnsignedBooleanMatrices()
        {
            // Expected results
            int expectedNumCornerDofs = 8;
            var expectedLc            = new Dictionary <int, Matrix>();

            expectedLc[0]       = Matrix.CreateZero(4, 8);
            expectedLc[0][0, 0] = 1;
            expectedLc[0][1, 1] = 1;
            expectedLc[0][2, 2] = 1;
            expectedLc[0][3, 3] = 1;

            expectedLc[1]       = Matrix.CreateZero(6, 8);
            expectedLc[1][0, 0] = 1;
            expectedLc[1][1, 1] = 1;
            expectedLc[1][2, 2] = 1;
            expectedLc[1][3, 3] = 1;
            expectedLc[1][4, 4] = 1;
            expectedLc[1][5, 5] = 1;

            expectedLc[2]       = Matrix.CreateZero(4, 8);
            expectedLc[2][0, 2] = 1;
            expectedLc[2][1, 3] = 1;
            expectedLc[2][2, 6] = 1;
            expectedLc[2][3, 7] = 1;

            expectedLc[3]       = Matrix.CreateZero(6, 8);
            expectedLc[3][0, 2] = 1;
            expectedLc[3][1, 3] = 1;
            expectedLc[3][2, 4] = 1;
            expectedLc[3][3, 5] = 1;
            expectedLc[3][4, 6] = 1;
            expectedLc[3][5, 7] = 1;

            // Create model
            Model model = CreateModel();
            Dictionary <int, HashSet <INode> > cornerNodes = DefineCornerNodes(model);

            model.ConnectDataStructures();

            // Order free dofs.
            var dofOrderer = new DofOrderer(new NodeMajorDofOrderingStrategy(), new NullReordering());
            IGlobalFreeDofOrdering globalOrdering = dofOrderer.OrderFreeDofs(model);

            model.GlobalDofOrdering = globalOrdering;
            foreach (ISubdomain subdomain in model.Subdomains)
            {
                subdomain.FreeDofOrdering = globalOrdering.SubdomainDofOrderings[subdomain];
            }

            // Separate dofs
            var dofSeparator = new FetiDPDofSeparator();

            dofSeparator.DefineGlobalCornerDofs(model, cornerNodes);
            foreach (ISubdomain subdomain in model.Subdomains)
            {
                int s = subdomain.ID;
                IEnumerable <INode> remainderAndConstrainedNodes = subdomain.Nodes.Where(node => !cornerNodes[s].Contains(node));
                dofSeparator.SeparateCornerRemainderDofs(subdomain, cornerNodes[s], remainderAndConstrainedNodes);
                dofSeparator.SeparateBoundaryInternalDofs(subdomain, remainderAndConstrainedNodes);
            }
            dofSeparator.CalcCornerMappingMatrices(model, cornerNodes);

            // Check
            double tolerance = 1E-13;

            Assert.Equal(expectedNumCornerDofs, dofSeparator.NumGlobalCornerDofs);
            for (int id = 0; id < 4; ++id)
            {
                UnsignedBooleanMatrix Lc = dofSeparator.CornerBooleanMatrices[id];
                Assert.True(expectedLc[id].Equals(Lc, tolerance));
            }
        }