protected override Matrix InverseSystemMatrixTimesOtherMatrix(IMatrixView otherMatrix) { var watch = new Stopwatch(); // Factorization if (mustFactorize) { watch.Start(); factorization = CholeskySuiteSparse.Factorize(linearSystem.Matrix, useSuperNodalFactorization); watch.Stop(); Logger.LogTaskDuration("Matrix factorization", watch.ElapsedMilliseconds); watch.Reset(); mustFactorize = false; } // Substitutions watch.Start(); Matrix solutionVectors; if (otherMatrix is Matrix otherDense) { return(factorization.SolveLinearSystems(otherDense)); } 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(); solutionVectors = factorization.SolveLinearSystems(rhsVectors); } catch (InsufficientMemoryException) //TODO: what about OutOfMemoryException? { // Solution vectors int systemOrder = linearSystem.Matrix.NumColumns; int numRhs = otherMatrix.NumColumns; solutionVectors = Matrix.CreateZero(systemOrder, numRhs); Vector solutionVector = linearSystem.CreateZeroVectorConcrete(); // Solve each linear system separately, to avoid copying the RHS matrix to a dense one. for (int j = 0; j < numRhs; ++j) { if (j != 0) { solutionVector.Clear(); } Vector rhsVector = otherMatrix.GetColumn(j); factorization.SolveLinearSystem(rhsVector, solutionVector); solutionVectors.SetSubcolumn(j, solutionVector); } } } watch.Stop(); Logger.LogTaskDuration("Back/forward substitutions", watch.ElapsedMilliseconds); Logger.IncrementAnalysisStep(); return(solutionVectors); }
internal static Matrix AbaqusToMSolveHexa8StructuralMatrix(IMatrixView abaqusMatrix) { var msolveFromAbaqusNodeMap = new int[] { 2, 6, 7, 3, 1, 5, 4, 0 }; var msolveFromAbaqusDofMap = new int[24]; for (int node = 0; node < 8; ++node) { msolveFromAbaqusDofMap[3 * node + 0] = 3 * msolveFromAbaqusNodeMap[node] + 0; msolveFromAbaqusDofMap[3 * node + 1] = 3 * msolveFromAbaqusNodeMap[node] + 1; msolveFromAbaqusDofMap[3 * node + 2] = 3 * msolveFromAbaqusNodeMap[node] + 2; } Matrix msolveMatrix = abaqusMatrix.CopyToFullMatrix(); return(msolveMatrix.Reorder(msolveFromAbaqusDofMap, false)); }