public CsrMatrix BuildGlobalMatrix(ISubdomainFreeDofOrdering dofOrdering, IEnumerable <IElement> elements,
                                           IElementMatrixProvider matrixProvider)
        {
            int numFreeDofs     = dofOrdering.NumFreeDofs;
            var subdomainMatrix = DokRowMajor.CreateEmpty(numFreeDofs, numFreeDofs);

            foreach (IElement element in elements)
            {
                (int[] elementDofIndices, int[] subdomainDofIndices) = dofOrdering.MapFreeDofsElementToSubdomain(element);
                IMatrix elementMatrix = matrixProvider.Matrix(element);
                subdomainMatrix.AddSubmatrixSymmetric(elementMatrix, elementDofIndices, subdomainDofIndices);
            }

            (double[] values, int[] colIndices, int[] rowOffsets) = subdomainMatrix.BuildCsrArrays(sortColsOfEachRow);
            if (!isIndexerCached)
            {
                cachedColIndices = colIndices;
                cachedRowOffsets = rowOffsets;
                isIndexerCached  = true;
            }
            else
            {
                Debug.Assert(Utilities.AreEqual(cachedColIndices, colIndices));
                Debug.Assert(Utilities.AreEqual(cachedRowOffsets, rowOffsets));
            }
            return(CsrMatrix.CreateFromArrays(numFreeDofs, numFreeDofs, values, cachedColIndices, cachedRowOffsets, false));
        }
        private static void TestIndexer()
        {
            Matrix      dense = Matrix.CreateFromArray(SparseRectangular10by5.Matrix);
            DokRowMajor dok   = CreateDok(SparseRectangular10by5.Matrix);

            comparer.AssertEqual(dense, dok);
        }
Beispiel #3
0
        private void CreateCoarseSpaceInterpolation()
        {
            var degreKsi           = _ksiDecomposition.Degree;
            var knotValueVectorKsi = _ksiDecomposition.KnotValueVector;
            var coarsePointsKsi    = _ksiDecomposition.GetAxisCoarsePoints();

            var degreeHeta          = _hetaDecomposition.Degree;
            var knotValueVectorHeta = _hetaDecomposition.KnotValueVector;
            var coarsePointsHeta    = _hetaDecomposition.GetAxisCoarsePoints();
            var coarsePoints2D      =
                (from ksi in coarsePointsKsi from heta in coarsePointsHeta select new NaturalPoint(ksi, heta)).ToList();

            var R0 = DokRowMajor.CreateEmpty(_patchControlPoints.Count * 2, coarsePoints2D.Count * 2);

            for (int i = 0; i < coarsePoints2D.Count; i++)
            {
                var NurbsValues = CalculateNURBS2D(degreKsi, degreeHeta, knotValueVectorKsi,
                                                   knotValueVectorHeta, coarsePoints2D[i], _patchControlPoints);

                for (int j = 0; j < NurbsValues.NumRows; j++)
                {
                    if (Math.Abs(NurbsValues[j, 0]) < 10e-9)
                    {
                        continue;
                    }
                    R0[2 * j, 2 * i]         = NurbsValues[j, 0];
                    R0[2 * j + 1, 2 * i + 1] = NurbsValues[j, 0];
                }
            }

            _coarseSpaceInterpolation = R0.BuildCsrMatrix(true).GetSubmatrix(freeSubdomainDofs.ToArray(), _coarseSpaceNodeSelection.GetFreeCoarseSpaceDofs());
        }
        public static void CompareDokCsrMultiplication()
        {
            int         numRows = 100000;
            int         numCols = 10000;
            DokRowMajor dok     = RandomUtilities.CreateRandomSparseMatrix(numRows, numCols, 0.15);
            Vector      lhs     = RandomUtilities.CreateRandomVector(numCols);

            var watch = new Stopwatch();

            watch.Start();
            Vector dokTimesLhs = dok.MultiplyRight(lhs);

            watch.Stop();
            long dokTime = watch.ElapsedMilliseconds;

            LibrarySettings.LinearAlgebraProviders = LinearAlgebraProviderChoice.Managed;
            watch.Restart();
            Vector csrUnsortedTimesLhs = dok.BuildCsrMatrix(false).Multiply(lhs, false);

            watch.Stop();
            long csrUnsortedTime = watch.ElapsedMilliseconds;

            watch.Restart();
            Vector csrSortedTimesLhs = dok.BuildCsrMatrix(true).Multiply(lhs, false);

            watch.Stop();
            long csrSortedTime = watch.ElapsedMilliseconds;

            LibrarySettings.LinearAlgebraProviders = LinearAlgebraProviderChoice.MKL;
            watch.Restart();
            Vector csrUnsortedMklTimesLhs = dok.BuildCsrMatrix(false).Multiply(lhs, false);

            watch.Stop();
            long csrUnsortedMklTime = watch.ElapsedMilliseconds;

            watch.Restart();
            Vector csrSortedMklTimesLhs = dok.BuildCsrMatrix(true).Multiply(lhs, false);

            watch.Stop();
            long csrSortedMklTime = watch.ElapsedMilliseconds;

            Console.WriteLine("Checking correctness and performance of DOK, sorted and unsorted CSR * vector:");
            Console.WriteLine($"DOK * vector: time = {dokTime} ms");
            Console.WriteLine($"Unsorted CSR * vector (C#): time = {csrUnsortedTime} ms");
            Console.WriteLine($"Sorted CSR * vector (C#): time = {csrSortedTime} ms");
            Console.WriteLine($"Unsorted CSR * vector (MKL): time = {csrUnsortedMklTime} ms");
            Console.WriteLine($"Sorted CSR * vector (MKL): time = {csrSortedMklTime} ms");

            var    comparer         = new ValueComparer(1e-12);
            double errorUnsorted    = (csrUnsortedTimesLhs - dokTimesLhs).Norm2() / dokTimesLhs.Norm2();
            double errorSorted      = (csrSortedTimesLhs - dokTimesLhs).Norm2() / dokTimesLhs.Norm2();
            double errorUnsortedMkl = (csrUnsortedMklTimesLhs - dokTimesLhs).Norm2() / dokTimesLhs.Norm2();
            double errorSortedMkl   = (csrSortedMklTimesLhs - dokTimesLhs).Norm2() / dokTimesLhs.Norm2();

            Console.WriteLine("Multiplication DOK - unsorted CSR (C#): normalized error = " + errorUnsorted);
            Console.WriteLine("Multiplication DOK - sorted CSR (C#): normalized error = " + errorSorted);
            Console.WriteLine("Multiplication DOK - unsorted CSR (MKL): normalized error = " + errorUnsortedMkl);
            Console.WriteLine("Multiplication DOK - sorted CSR (MKL): normalized error = " + errorSortedMkl);
        }
Beispiel #5
0
 /// <summary>
 /// Reads a general sparse matrix from the file specified by <paramref name="path"/>. Even if the matrix is symmetric,
 /// the file must contain both the upper and lower triangle.
 /// </summary>
 /// <param name="path">The absolute path of the array.</param>
 /// <exception cref="IOException">Thrown if there is no such file or if the dimensions of the matrix specified in the
 ///     first line are invalid.</exception>
 public DokRowMajor ReadFileAsDokRowMajor(string path)
 {
     using (var reader = new StreamReader(path))
     {
         (int numRows, int numCols, int nnz) = ReadMatrixDimensions(reader);
         var builder = DokRowMajor.CreateEmpty(numRows, numCols);
         ReadMatrixEntries(reader, nnz, builder);
         return(builder);
     }
 }
Beispiel #6
0
                matrixConstrConstr) BuildGlobalSubmatrices(ISubdomainFreeDofOrdering freeDofRowOrdering,
                                                           ISubdomainFreeDofOrdering freeDofColOrdering,
                                                           ISubdomainConstrainedDofOrdering constrainedDofRowOrdering,
                                                           ISubdomainConstrainedDofOrdering constrainedDofColOrdering, IEnumerable <IElement> elements,
                                                           IElementMatrixProvider matrixProvider)
        {
            int numFreeRowDofs = freeDofRowOrdering.NumFreeDofs;
            int numFreeColDofs = freeDofColOrdering.NumFreeDofs;

            var subdomainMatrix = DokRowMajor.CreateEmpty(numFreeRowDofs, numFreeColDofs);

            constrainedAssembler.InitializeNewMatrices(freeDofRowOrdering.NumFreeDofs,
                                                       constrainedDofRowOrdering.NumConstrainedDofs);

            foreach (var element in elements)
            {
                (int[] elementRowDofsFree, int[] subdomainRowDofsFree) =
                    freeDofRowOrdering.MapFreeDofsElementToSubdomain(element);
                (int[] elementColDofsFree, int[] subdomainColDofsFree) =
                    freeDofColOrdering.MapFreeDofsElementToSubdomain(element);

                (int[] elementRowDofsConstrained, int[] subdomainRowDofsConstrained) =
                    constrainedDofRowOrdering.MapConstrainedDofsElementToSubdomain(element);
                (int[] elementColDofsConstrained, int[] subdomainColDofsConstrained) =
                    constrainedDofColOrdering.MapConstrainedDofsElementToSubdomain(element);

                IMatrix elementMatrix = matrixProvider.Matrix(element);
                subdomainMatrix.AddSubmatrix(elementMatrix, elementRowDofsFree, subdomainRowDofsFree,
                                             elementColDofsFree, subdomainColDofsFree);
                constrainedAssembler.AddElementMatrix(elementMatrix, elementRowDofsFree, subdomainRowDofsFree,
                                                      elementRowDofsConstrained, subdomainRowDofsConstrained); //TODO: check validity
            }

            (double[] values, int[] colIndices, int[] rowOffsets) = subdomainMatrix.BuildCsrArrays(sortColsOfEachRow);
            if (!isIndexerCached)
            {
                cachedColIndices = colIndices;
                cachedRowOffsets = rowOffsets;
                isIndexerCached  = true;
            }
            else
            {
                Debug.Assert(Utilities.AreEqual(cachedColIndices, colIndices));
                Debug.Assert(Utilities.AreEqual(cachedRowOffsets, rowOffsets));
            }

            subdomainMatrix = null;
            var matrixFreeFree =
                CsrMatrix.CreateFromArrays(numFreeRowDofs, numFreeColDofs, values, cachedColIndices, cachedRowOffsets,
                                           false);

            (CsrMatrix matrixConstrFree, CsrMatrix matrixConstrConstr) =
                constrainedAssembler.BuildMatrices(); // TODO: see if this work
            return(matrixFreeFree, matrixConstrFree, matrixConstrFree.TransposeToCSC(false), matrixConstrConstr);
        }
Beispiel #7
0
        internal (CsrMatrix matrixConstrFree, CsrMatrix matrixConstrConstr) BuildMatrices()
        {
            // Also free the memory used by each builders, as soon as it is no longer used.
            CsrMatrix matrixConstrFree = dokConstrFree.BuildCsrMatrix(true);

            dokConstrFree = null;
            CsrMatrix matrixConstrConstr = dokConstrConstr.BuildCsrMatrix(true);

            dokConstrConstr = null;
            return(matrixConstrFree, matrixConstrConstr);
        }
Beispiel #8
0
        //TODO: this should be done by an assembler class
        //TODO: make sure this is called whenever the ordering changes
        private CsrMatrix BuildQFromSubdomain(Subdomain subdomain)
        {
            int      numFreeDofs = subdomain.FreeDofOrdering.NumFreeDofs;
            var      qSubdomain  = DokRowMajor.CreateEmpty(numFreeDofs, numFreeDofs);
            DofTable allDofs     = subdomain.FreeDofOrdering.FreeDofs;

            foreach (Element element in subdomain.Elements)
            {
                if (!(element.ElementType is IPorousFiniteElement))
                {
                    continue;
                }

                var     e = (IPorousFiniteElement)element.ElementType;
                IMatrix q = e.CouplingMatrix(element);

                int iElementMatrixRow = 0;
                for (int i = 0; i < element.ElementType.DofEnumerator.GetDofTypesForMatrixAssembly(element).Count; i++)
                {
                    Node nodeRow = element.Nodes[i];
                    foreach (IDofType dofTypeRow in element.ElementType.DofEnumerator.GetDofTypesForMatrixAssembly(element)[i])
                    {
                        if (dofTypeRow != PorousMediaDof.Pressure)
                        {
                            continue;
                        }

                        int dofRow = allDofs[nodeRow, dofTypeRow];
                        int iElementMatrixColumn = 0;

                        for (int j = 0; j < element.ElementType.DofEnumerator.GetDofTypesForMatrixAssembly(element).Count; j++)
                        {
                            Node nodeColumn = element.Nodes[j];
                            foreach (IDofType dofTypeColumn in element.ElementType.DofEnumerator.GetDofTypesForMatrixAssembly(element)[j])
                            {
                                if (dofTypeColumn == PorousMediaDof.Pressure)
                                {
                                    continue;
                                }

                                int dofColumn = allDofs[nodeColumn, dofTypeColumn];
                                qSubdomain.AddToEntry(dofColumn, dofRow, q[iElementMatrixRow, iElementMatrixColumn]);
                                iElementMatrixColumn++;
                            }
                        }
                        iElementMatrixRow++;
                    }
                }
            }

            return(qSubdomain.BuildCsrMatrix(true));
        }
        private static void TestBuildCSR()
        {
            var         dense = Matrix.CreateFromArray(SparseRectangular10by5.Matrix);
            DokRowMajor dok   = CreateDok(SparseRectangular10by5.Matrix);

            // CSR with sorted col indices of each row
            CsrMatrix csrSorted = dok.BuildCsrMatrix(true);

            comparer.AssertEqual(dense, csrSorted);

            // CSR without sorting
            CsrMatrix csrUnsorted = dok.BuildCsrMatrix(false);

            comparer.AssertEqual(dense, csrUnsorted);
        }
        internal static DokRowMajor CreateRandomSparseMatrix(int numRows, int numCols, double nonZeroChance)
        {
            var rand = new Random();
            var dok  = DokRowMajor.CreateEmpty(numRows, numCols);

            for (int i = 0; i < numRows; ++i)
            {
                for (int j = 0; j < numCols; ++j)
                {
                    if (rand.NextDouble() <= nonZeroChance)
                    {
                        dok[i, j] = rand.NextDouble();
                    }
                }
            }
            return(dok);
        }
                IMatrixView matrixConstrConstr) BuildGlobalSubmatrices(
            ISubdomainFreeDofOrdering freeDofOrdering, ISubdomainConstrainedDofOrdering constrainedDofOrdering,
            IEnumerable <IElement> elements, IElementMatrixProvider matrixProvider)
        {
            int numFreeDofs     = freeDofOrdering.NumFreeDofs;
            var subdomainMatrix = DokRowMajor.CreateEmpty(numFreeDofs, numFreeDofs);

            //TODO: also reuse the indexers of the constrained matrices.
            constrainedAssembler.InitializeNewMatrices(freeDofOrdering.NumFreeDofs, constrainedDofOrdering.NumConstrainedDofs);

            // Process the stiffness of each element
            foreach (IElement element in elements)
            {
                (int[] elementDofsFree, int[] subdomainDofsFree) = freeDofOrdering.MapFreeDofsElementToSubdomain(element);
                (int[] elementDofsConstrained, int[] subdomainDofsConstrained) =
                    constrainedDofOrdering.MapConstrainedDofsElementToSubdomain(element);

                IMatrix elementMatrix = matrixProvider.Matrix(element);
                subdomainMatrix.AddSubmatrixSymmetric(elementMatrix, elementDofsFree, subdomainDofsFree);
                constrainedAssembler.AddElementMatrix(elementMatrix, elementDofsFree, subdomainDofsFree,
                                                      elementDofsConstrained, subdomainDofsConstrained);
            }

            // Create and cache the CSR arrays for the free dofs.
            (double[] values, int[] colIndices, int[] rowOffsets) = subdomainMatrix.BuildCsrArrays(sortColsOfEachRow);
            if (!isIndexerCached)
            {
                cachedColIndices = colIndices;
                cachedRowOffsets = rowOffsets;
                isIndexerCached  = true;
            }
            else
            {
                Debug.Assert(Utilities.AreEqual(cachedColIndices, colIndices));
                Debug.Assert(Utilities.AreEqual(cachedRowOffsets, rowOffsets));
            }

            // Create the free and constrained matrices.
            subdomainMatrix = null; // Let the DOK be garbaged collected early, in case there isn't sufficient memory.
            var matrixFreeFree =
                CsrMatrix.CreateFromArrays(numFreeDofs, numFreeDofs, values, cachedColIndices, cachedRowOffsets, false);

            (CsrMatrix matrixConstrFree, CsrMatrix matrixConstrConstr) = constrainedAssembler.BuildMatrices();
            return(matrixFreeFree, matrixConstrFree, matrixConstrFree.TransposeToCSC(false), matrixConstrConstr);
        }
        private static DokRowMajor CreateDok(double[,] matrix)
        {
            int m   = matrix.GetLength(0);
            int n   = matrix.GetLength(1);
            var dok = DokRowMajor.CreateEmpty(m, n);

            for (int i = 0; i < m; ++i)
            {
                for (int j = 0; j < n; ++j)
                {
                    if (matrix[i, j] != 0.0)
                    {
                        dok[i, j] = matrix[i, j];
                    }
                }
            }
            return(dok);
        }
Beispiel #13
0
 internal void InitializeNewMatrices(int numFreeDofs, int numConstrainedDofs)
 {
     dokConstrFree   = DokRowMajor.CreateEmpty(numConstrainedDofs, numFreeDofs);
     dokConstrConstr = DokRowMajor.CreateEmpty(numConstrainedDofs, numConstrainedDofs);
 }