public void ReorderCornerDofs(FetiDPDofSeparator dofSeparator) { if (reordering == null) { return; // Use the natural ordering and do not modify any stored dof data } var pattern = SparsityPatternSymmetric.CreateEmpty(dofSeparator.NumGlobalCornerDofs); for (int s = 0; s < subdomains.Count; ++s) { // Treat each subdomain as a superelement with only its corner nodes. var localCornerDofOrdering = dofSeparator.SubdomainCornerDofOrderings[s]; int numLocalCornerDofs = localCornerDofOrdering.EntryCount; var subdomainToGlobalDofs = new int[numLocalCornerDofs]; foreach ((INode node, IDofType dofType, int localIdx) in localCornerDofOrdering) { int globalIdx = dofSeparator.GlobalCornerDofOrdering[node, dofType]; subdomainToGlobalDofs[localIdx] = globalIdx; } pattern.ConnectIndices(subdomainToGlobalDofs, false); } (int[] permutation, bool oldToNew) = reordering.FindPermutation(pattern); dofSeparator.GlobalCornerDofOrdering.Reorder(permutation, oldToNew); dofSeparator.GlobalCornerToFreeDofMap = ReorderingUtilities.ReorderKeysOfDofIndicesMap(dofSeparator.GlobalCornerToFreeDofMap, permutation, oldToNew); }
//TODO: Move this method to SparsityPatternSymmetric, so that I can optimize access to its private data internal static SparsityPatternSymmetric GetSubmatrixSymmetricPattern(double[] skyValues, int[] skyDiagOffsets, int[] rowsColsToKeep) { //TODO: perhaps this can be combined with the CSC and full version to get all 2 submatrices needed for // Schur complements more efficiently. int subOrder = rowsColsToKeep.Length; if (subOrder == 0) { throw new NonMatchingDimensionsException("The original matrix had 0 rows and columns."); } var submatrix = SparsityPatternSymmetric.CreateEmpty(subOrder); for (int subCol = 0; subCol < subOrder; ++subCol) { int col = rowsColsToKeep[subCol]; int diagOffset = skyDiagOffsets[col]; int colHeight = skyDiagOffsets[col + 1] - diagOffset - 1; // excluding diagonal for (int subRow = 0; subRow <= subCol; ++subRow) { int row = rowsColsToKeep[subRow]; if (row <= col) { int entryHeight = col - row; // excluding diagonal if (entryHeight <= colHeight) // inside stored non zero pattern { double val = skyValues[diagOffset + entryHeight]; if (val != 0.0) { submatrix.AddEntryUpper(subRow, subCol); // Skyline format stores many unnecessary zeros. } } } else // Transpose row <-> col. The cached column height and offset must be recalculated. { int transposedDiagOffset = skyDiagOffsets[row]; int transposedColHeight = skyDiagOffsets[row + 1] - transposedDiagOffset - 1; // excluding diagonal int entryHeight = row - col; // excluding diagonal if (entryHeight <= transposedColHeight) // inside stored non zero pattern { double val = skyValues[transposedDiagOffset + entryHeight]; if (val != 0.0) { submatrix.AddEntryUpper(subRow, subCol); // Skyline format stores many unnecessary zeros. } } } } } return(submatrix); }
public void Reorder(IReorderingAlgorithm reorderingAlgorithm, ISubdomain subdomain) { var pattern = SparsityPatternSymmetric.CreateEmpty(NumFreeDofs); foreach (var element in subdomain.Elements) { (int[] elementDofIndices, int[] subdomainDofIndices) = MapFreeDofsElementToSubdomain(element); //TODO: ISubdomainFreeDofOrdering could perhaps return whether the subdomainDofIndices are sorted or not. pattern.ConnectIndices(subdomainDofIndices, false); } (int[] permutation, bool oldToNew) = reorderingAlgorithm.FindPermutation(pattern); FreeDofs.Reorder(permutation, oldToNew); }
private static void TestSparsePosDef() { int n = SparsePosDef10by10.Order; var pattern = SparsityPatternSymmetric.CreateEmpty(n); for (int i = 0; i < n; ++i) { for (int j = 0; j < n; ++j) { if (SparsePosDef10by10.Matrix[i, j] != 0) { pattern.AddEntry(i, j); } } } TestWriteOperation(pattern, SparsePosDef10by10.PatternPath); }
private static void TestConnectIndices() { int n = GlobalMatrixAssembly.GlobalOrder; var dense = Matrix.CreateFromArray(GlobalMatrixAssembly.GlobalMatrix); var pattern = SparsityPatternSymmetric.CreateEmpty(n); pattern.ConnectIndices(GlobalMatrixAssembly.GlobalIndices1, true); pattern.ConnectIndices(GlobalMatrixAssembly.GlobalIndices2, true); pattern.ConnectIndices(GlobalMatrixAssembly.GlobalIndices3, true); for (int i = 0; i < n; ++i) { for (int j = 0; j < n; ++j) { bool denseHasZero = dense[i, j] == 0.0; bool patternHasZero = !pattern.IsNonZero(i, j); Assert.True(patternHasZero == denseHasZero); } } }