public void CreateAndInvertCoarseProblemMatrix(Dictionary <int, HashSet <INode> > cornerNodesOfSubdomains, FetiDPDofSeparator dofSeparator, Dictionary <int, IFetiDPSubdomainMatrixManager> matrixManagers) { SkylineMatrix globalKccStar = CreateGlobalKccStar(cornerNodesOfSubdomains, dofSeparator, matrixManagers); this.inverseGlobalKccStar = globalKccStar.FactorLdl(true); }
/// <summary> /// Solves the linear system with back-forward substitution. If the matrix has been modified, it will be refactorized. /// </summary> public override void Solve() { var watch = new Stopwatch(); if (linearSystem.SolutionConcrete == null) { linearSystem.SolutionConcrete = linearSystem.CreateZeroVectorConcrete(); } //else linearSystem.Solution.Clear(); // no need to waste computational time on this in a direct solver // Factorization if (mustFactorize) { watch.Start(); factorizedMatrix = linearSystem.Matrix.FactorLdl(factorizeInPlace, factorizationPivotTolerance); watch.Stop(); Logger.LogTaskDuration("Matrix factorization", watch.ElapsedMilliseconds); watch.Reset(); mustFactorize = false; } // Substitutions watch.Start(); factorizedMatrix.SolveLinearSystem(linearSystem.RhsConcrete, linearSystem.SolutionConcrete); watch.Stop(); Logger.LogTaskDuration("Back/forward substitutions", watch.ElapsedMilliseconds); Logger.IncrementAnalysisStep(); }
/// <summary> /// Will do nothing if it was already called. To perform this for a different stiffness matrix, first call /// <see cref="Clear"/>. /// </summary> public void InvertKrr(bool inPlace) { if (inverseKrr != null) { return; } inverseKrr = Krr.FactorLdl(inPlace); }
public static Matrix CalcSchurComplementFull(Matrix A, CscMatrix B, LdlSkyline inverseC) { // S = A - B^T * inv(C) * B Matrix invCB = Matrix.CreateZero(inverseC.Order, B.NumColumns); inverseC.SolveLinearSystems(B, invCB); return(A - B.MultiplyRight(invCB, true)); }
/// <summary> /// If the matrices stored in this object have already been calculated, they will be reused even if the original /// free-free stiffness matrix has changed. To avoid that, this method must be called. /// </summary> public void Clear() { inverseKff = null; RigidBodyModes = null; inverseKii = null; inverseKiiDiagonal = null; Kbb = null; Kib = null; //linearSystem.Matrix = null; // DO NOT DO THAT!!! The analyzer manages that. }
protected override Matrix InverseSystemMatrixTimesOtherMatrix(IMatrixView otherMatrix) { var watch = new Stopwatch(); // Factorization if (mustFactorize) { watch.Start(); factorizedMatrix = linearSystem.Matrix.FactorLdl(factorizeInPlace, factorizationPivotTolerance); watch.Stop(); Logger.LogTaskDuration("Matrix factorization", watch.ElapsedMilliseconds); watch.Reset(); mustFactorize = false; } // Substitutions watch.Start(); int systemOrder = linearSystem.Matrix.NumColumns; int numRhs = otherMatrix.NumColumns; var solutionVectors = Matrix.CreateZero(systemOrder, numRhs); if (otherMatrix is Matrix otherDense) { factorizedMatrix.SolveLinearSystems(otherDense, solutionVectors); } else { try { // If there is enough memory, copy the RHS matrix to a dense one, to speed up computations. //TODO: must be benchmarked, if it is actually more efficient than solving column by column. Matrix rhsVectors = otherMatrix.CopyToFullMatrix(); factorizedMatrix.SolveLinearSystems(rhsVectors, solutionVectors); } catch (InsufficientMemoryException) //TODO: what about OutOfMemoryException? { // Solve each linear system separately, to avoid copying the RHS matrix to a dense one. Vector solutionVector = linearSystem.CreateZeroVectorConcrete(); for (int j = 0; j < numRhs; ++j) { if (j != 0) { solutionVector.Clear(); } Vector rhsVector = otherMatrix.GetColumn(j); factorizedMatrix.SolveLinearSystem(rhsVector, solutionVector); solutionVectors.SetSubcolumn(j, solutionVector); } } } watch.Stop(); Logger.LogTaskDuration("Back/forward substitutions", watch.ElapsedMilliseconds); Logger.IncrementAnalysisStep(); return(solutionVectors); }
/// <summary> /// Will do nothing if it was already called. To perform this for a different stiffness matrix, first call /// <see cref="Clear"/>. /// </summary> public void Clear() { inverseKii = null; inverseKiiDiagonal = null; inverseKrr = null; Kbb = null; Kib = null; Kcc = null; Krc = null; Krr = null; KccStar = null; //linearSystem.Matrix = null; // DO NOT DO THAT!!! The analyzer manages that. }
private static void TestSystemSolution(/*LinearAlgebraProviderChoice providers*/) { //TestSettings.RunMultiproviderTest(providers, delegate () { // var skyline = SkylineMatrix.CreateFromArrays(SparsePosDef10by10.Order, SparsePosDef10by10.SkylineValues, SparsePosDef10by10.SkylineDiagOffsets, true, true); var b = Vector.CreateFromArray(SparsePosDef10by10.Rhs); var xExpected = Vector.CreateFromArray(SparsePosDef10by10.Lhs); LdlSkyline factor = skyline.FactorLdl(false); Vector xComputed = factor.SolveLinearSystem(b); comparer.AssertEqual(xExpected, xComputed); //}); }
/// <summary> /// Will do nothing if it was already called. To perform this for a different stiffness matrix, first call /// <see cref="Clear"/>. /// </summary> public void ExtractAndInvertKii(int[] internalDofs) { if (inverseKii != null) { return; } try { SkylineMatrix Kii = Krr.GetSubmatrixSymmetricSkyline(internalDofs); inverseKii = Kii.FactorLdl(true); } catch (MatrixDataOverwrittenException) { throw new InvalidOperationException( "The remainder-remainder stiffness submatrix of this subdomain has been overwritten and cannot be used" + " anymore. Try calling this method before factorizing/inverting it."); } }
private static void TestMultipleSystemsSolution(/*LinearAlgebraProviderChoice providers*/) { //TestSettings.RunMultiproviderTest(providers, delegate () { // var skyline = SkylineMatrix.CreateFromArrays(SparsePosDef10by10.Order, SparsePosDef10by10.SkylineValues, SparsePosDef10by10.SkylineDiagOffsets, true, true); LdlSkyline factor = skyline.FactorLdl(false); var identity = Matrix.CreateIdentity(SparsePosDef10by10.Order); var inverse = Matrix.CreateZero(SparsePosDef10by10.Order, SparsePosDef10by10.Order); factor.SolveLinearSystems(identity, inverse); var matrixTimesInverse = MatrixOperations.MatrixTimesMatrix(SparsePosDef10by10.Matrix, inverse.CopyToArray2D()); comparer.AssertEqual(identity.CopyToArray2D(), matrixTimesInverse); //}); }
public void ClearCoarseProblemMatrix() { inverseGlobalKccStar = null; }
public override void HandleMatrixWillBeSet() { mustFactorize = true; factorizedMatrix = null; }