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