public FetiDPFlexibilityMatrix(FetiDPDofSeparator dofSeparator, FetiDPLagrangeMultipliersEnumerator lagrangeEnumerator, Dictionary <int, IFetiDPSubdomainMatrixManager> matrixManagers) { this.Br = lagrangeEnumerator.BooleanMatrices; this.Lc = dofSeparator.CornerBooleanMatrices; this.matrixManagers = matrixManagers; this.numCornerDofs = dofSeparator.NumGlobalCornerDofs; this.Order = lagrangeEnumerator.NumLagrangeMultipliers; }
public void Initialize() { var watch = new Stopwatch(); watch.Start(); // Identify corner nodes CornerNodesOfSubdomains = cornerNodeSelection.SelectCornerNodesOfSubdomains(); //TODO: Could this cause change in connectivity? // Define boundary / internal dofs dofSeparator.DefineGlobalBoundaryDofs(model, CornerNodesOfSubdomains); dofSeparator.DefineGlobalCornerDofs(model, CornerNodesOfSubdomains); foreach (ISubdomain subdomain in model.Subdomains) { int s = subdomain.ID; HashSet <INode> cornerNodes = CornerNodesOfSubdomains[s]; if (subdomain.ConnectivityModified) { //TODO: should I cache this somewhere? //TODO: should I use subdomain.Nodes.Except(cornerNodes) instead? IEnumerable <INode> remainderAndConstrainedNodes = subdomain.Nodes.Where(node => !cornerNodes.Contains(node)); Debug.WriteLine($"{this.GetType().Name}: Separating and ordering corner-remainder dofs of subdomain {s}"); dofSeparator.SeparateCornerRemainderDofs(subdomain, cornerNodes, remainderAndConstrainedNodes); Debug.WriteLine($"{this.GetType().Name}: Reordering internal dofs of subdomain {s}."); matrixManagers[s].ReorderRemainderDofs(dofSeparator, subdomain); Debug.WriteLine($"{this.GetType().Name}: Separating and ordering boundary-internal dofs of subdomain {s}"); dofSeparator.SeparateBoundaryInternalDofs(subdomain, remainderAndConstrainedNodes); } } // This must be called after determining the corner dofs of each subdomain //TODO: Perhaps the corner dofs of each subdomain should be handled in dofSeparator.DefineGlobalCornerDofs(); coarseProblemSolver.ReorderCornerDofs(dofSeparator); dofSeparator.CalcCornerMappingMatrices(model, CornerNodesOfSubdomains); //TODO: B matrices could also be reused in some cases // Define lagrange multipliers and boolean matrices. this.lagrangeEnumerator = new FetiDPLagrangeMultipliersEnumerator(crosspointStrategy, dofSeparator); if (problemIsHomogeneous) { lagrangeEnumerator.DefineBooleanMatrices(model); // optimization in this case } else { lagrangeEnumerator.DefineLagrangesAndBooleanMatrices(model); } // Log dof statistics watch.Stop(); Logger.LogTaskDuration("Dof ordering", watch.ElapsedMilliseconds); int numExpandedDomainFreeDofs = 0; foreach (var subdomain in model.Subdomains) { numExpandedDomainFreeDofs += subdomain.FreeDofOrdering.NumFreeDofs; } Logger.LogNumDofs("Expanded domain dofs", numExpandedDomainFreeDofs); Logger.LogNumDofs("Lagrange multipliers", lagrangeEnumerator.NumLagrangeMultipliers); Logger.LogNumDofs("Corner dofs", dofSeparator.NumGlobalCornerDofs); // Use the newly created stiffnesses to determine the stiffness distribution between subdomains. //TODO: Should this be done here or before factorizing by checking that isMatrixModified? var Kff = new Dictionary <int, IMatrixView>(); foreach (int s in linearSystems.Keys) { Kff[s] = linearSystems[s].Matrix; } stiffnessDistribution.Update(Kff); subdomainGlobalMapping = new FetiDPSubdomainGlobalMapping(model, dofSeparator, stiffnessDistribution); }