Ejemplo n.º 1
0
        public Dictionary <int, SparseVector> DistributeNodalLoads(Table <INode, IDofType, double> globalNodalLoads)
        {
            var subdomainLoads = new SortedDictionary <int, double>();

            foreach ((INode node, IDofType dofType, double amount) in globalNodalLoads)
            {
                int subdomainDofIdx = subdomain.FreeDofOrdering.FreeDofs[node, dofType];
                subdomainLoads[subdomainDofIdx] = amount;
            }
            return(new Dictionary <int, SparseVector>
            {
                { subdomain.ID, SparseVector.CreateFromDictionary(subdomain.FreeDofOrdering.NumFreeDofs, subdomainLoads) }
            });
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Performs the matrix-vector multiplication: this * <paramref name="vector"/>.
        /// </summary>
        /// <param name="other">A vector with <see cref="IIndexable1D.Length"/> being equal to
        ///     this.<see cref="NumColumns"/>.</param>
        /// <exception cref="NonMatchingDimensionsException">Thrown if the <see cref="IIndexable1D.Length"/> of
        ///     <paramref name="vector"/> is different than the this.<see cref="NumColumns"/>.</exception>
        public SparseVector MultiplyRight(Vector vector)
        {
            Preconditions.CheckMultiplicationDimensions(NumColumns, vector.Length);
            var result = new SortedDictionary <int, double>();

            foreach (var wholeRow in rows)
            {
                double dot = 0.0;
                foreach (var colValPair in wholeRow.Value)
                {
                    dot += colValPair.Value * vector[colValPair.Key];
                }
                result[wholeRow.Key] = dot;
            }
            return(SparseVector.CreateFromDictionary(NumRows, result));
        }
Ejemplo n.º 3
0
        public Dictionary <int, SparseVector> DistributeNodalLoads(Dictionary <int, ISubdomain> subdomains,
                                                                   Table <INode, IDofType, double> globalNodalLoads)
        {
            //TODO: Should I implement this as fb(s) = Lpb(s) * fb, with a) Lpb(s) = Lb(s) * inv(Mb) for homogeneous and
            //      b) Lpb(s) = Db(s)*Lb(s) * inv(Lb^T*Db*Lb) for heterogeneous?

            var subdomainLoads = new Dictionary <int, SortedDictionary <int, double> >();

            foreach (var subdomainID in subdomains.Keys)
            {
                subdomainLoads[subdomainID] = new SortedDictionary <int, double>();
            }

            foreach ((INode node, IDofType dofType, double loadAmount) in globalNodalLoads)
            {
                if (node.SubdomainsDictionary.Count == 1) // optimization for internal dof
                {
                    ISubdomain subdomain       = node.SubdomainsDictionary.First().Value;
                    int        subdomainDofIdx = subdomain.FreeDofOrdering.FreeDofs[node, dofType];
                    subdomainLoads[subdomain.ID][subdomainDofIdx] = loadAmount;
                }
                else // boundary dof: regularize with respect to the diagonal entries of the stiffness matrix at this dof
                {
                    Dictionary <int, double> boundaryDofCoeffs = distribution.CalcBoundaryDofCoefficients(node, dofType);
                    foreach (var idSubdomain in node.SubdomainsDictionary)
                    {
                        int        id              = idSubdomain.Key;
                        ISubdomain subdomain       = idSubdomain.Value;
                        int        subdomainDofIdx = subdomain.FreeDofOrdering.FreeDofs[node, dofType];
                        subdomainLoads[id][subdomainDofIdx] = loadAmount * boundaryDofCoeffs[id];
                    }
                }
            }

            var vectors = new Dictionary <int, SparseVector>();

            foreach (var idSubdomains in subdomains)
            {
                int id = idSubdomains.Key;
                int numSubdomainDofs = idSubdomains.Value.FreeDofOrdering.NumFreeDofs;
                vectors[id] = SparseVector.CreateFromDictionary(numSubdomainDofs, subdomainLoads[id]);
            }
            return(vectors);
        }
Ejemplo n.º 4
0
        /// <summary>
        /// Returns the column with index = <paramref name="colIdx"/> as a vector. However, the entries with row index that
        /// belongs in <paramref name="tabooRows"/> will be set to 0. More accurately, they will not be included in the
        /// sparsity pattern of the returned <see cref="SparseVector"/>. Note that the length of the returned vector is
        /// equal to this.<see cref="NumRows"/>.
        /// </summary>
        /// <param name="colIdx">The index of the column to return. Constraints: Column <paramref name="colIdx"/> must be stored
        ///     and 0 &lt;= <paramref name="colIdx"/> &lt; this.<see cref="NumColumns"/>.</param>
        /// <param name="tabooRows">The entries of the returned column vector at the indices specified by
        ///     <paramref name="tabooRows"/> will be equal to 0. Constraints: foreach rowIdx in <paramref name="tabooRows"/>:
        ///     0 &lt;= rowIdx &lt; this.<see cref="NumRows"/>.</param>
        /// <exception cref="IndexOutOfRangeException">Thrown if <paramref name="colIdx"/> or <paramref name="tabooRows"/>
        ///     violate the described constraints.</exception>
        public SparseVector GetColumnWithoutRows(int colIdx, HashSet <int> tabooRows)
        {
            bool exists = columns.TryGetValue(colIdx, out Dictionary <int, double> wholeColumn); //TODO: Should I just let the Dictionary indexer throw?

            if (!exists)
            {
                throw new IndexOutOfRangeException($"Column {colIdx} is not stored.");
            }
            var result = new SortedDictionary <int, double>();

            foreach (var rowVal in columns[colIdx])
            {
                if (!tabooRows.Contains(rowVal.Key))
                {
                    result.Add(rowVal.Key, rowVal.Value);
                }
            }
            return(SparseVector.CreateFromDictionary(NumRows, result));
        }
Ejemplo n.º 5
0
        /// <summary>
        /// Returns the column with index = <paramref name="colIdx"/> as a vector. However, only the entries with row index that
        /// belongs in <paramref name="wantedRows"/> will be copied. The rest will be 0 and not stored explicitly. Note that
        /// the length of the returned vector is equal to this.<see cref="NumRows"/>.
        /// </summary>
        /// <param name="colIdx">The index of the column to return. Constraints: Column <paramref name="colIdx"/> must be stored
        ///     and 0 &lt;= <paramref name="colIdx"/> &lt; this.<see cref="NumColumns"/>.</param>
        /// <param name="wantedRows">The entries of the column <paramref name="colIdx"/> that will be copied to the returned
        ///     vector. Constraints: foreach rowIdx in <paramref name="wantedRows"/>:
        ///     0 &lt;= rowIdx &lt; this.<see cref="NumRows"/>.</param>
        /// <exception cref="IndexOutOfRangeException">Thrown if <paramref name="colIdx"/> or <paramref name="wantedRows"/>
        ///     violate the described constraints.</exception>
        public SparseVector GetColumnWithSelectedRows(int colIdx, HashSet <int> wantedRows)
        {
            //TODO: perhaps I should pass a sorted set, iterate it and create the raw arrays directly. Or sort the passed set.
            bool exists = columns.TryGetValue(colIdx, out Dictionary <int, double> wholeColumn); //TODO: Should I just let the Dictionary indexer throw?

            if (!exists)
            {
                throw new IndexOutOfRangeException($"Column {colIdx} is not stored.");
            }
            var result = new SortedDictionary <int, double>();

            foreach (var rowVal in columns[colIdx])
            {
                if (wantedRows.Contains(rowVal.Key))
                {
                    result.Add(rowVal.Key, rowVal.Value);
                }
            }
            return(SparseVector.CreateFromDictionary(NumRows, result));
        }
Ejemplo n.º 6
0
        public Dictionary <int, SparseVector> DistributeNodalLoads(Dictionary <int, ISubdomain> subdomains,
                                                                   Table <INode, IDofType, double> globalNodalLoads)
        {
            //TODO: Should I implement this as fb(s) = Lpb(s) * fb, with a) Lpb(s) = Lb(s) * inv(Mb) for homogeneous and
            //      b) Lpb(s) = Db(s)*Lb(s) * inv(Lb^T*Db*Lb) for heterogeneous?

            var subdomainLoads = new Dictionary <int, SortedDictionary <int, double> >();

            foreach (var subdomainID in subdomains.Keys)
            {
                subdomainLoads[subdomainID] = new SortedDictionary <int, double>();
            }

            foreach ((INode node, IDofType dofType, double loadAmount) in globalNodalLoads)
            {
                bool isCornerDof = dofSeparator.GlobalCornerDofOrdering.Contains(node, dofType);
                if (isCornerDof)
                {
                    // Loads at corner dofs will be distributed equally. It shouldn't matter how I distribute these, since I
                    // will only sum them together again during the static condensation of remainder dofs phase.
                    //TODO: is that correct?
                    double loadPerSubdomain = loadAmount / node.SubdomainsDictionary.Count;
                    foreach (var idSubdomain in node.SubdomainsDictionary)
                    {
                        int        id              = idSubdomain.Key;
                        ISubdomain subdomain       = idSubdomain.Value;
                        int        subdomainDofIdx = subdomain.FreeDofOrdering.FreeDofs[node, dofType];
                        subdomainLoads[id][subdomainDofIdx] = loadPerSubdomain;
                    }
                }
                else
                {
                    if (node.SubdomainsDictionary.Count == 1) // optimization for internal dof
                    {
                        ISubdomain subdomain       = node.SubdomainsDictionary.First().Value;
                        int        subdomainDofIdx = subdomain.FreeDofOrdering.FreeDofs[node, dofType];
                        subdomainLoads[subdomain.ID][subdomainDofIdx] = loadAmount;
                    }
                    else // boundary dof: regularize with respect to the diagonal entries of the stiffness matrix at this dof
                    {
                        Dictionary <int, double> boundaryDofCoeffs = distribution.CalcBoundaryDofCoefficients(node, dofType);
                        foreach (var idSubdomain in node.SubdomainsDictionary)
                        {
                            int        id              = idSubdomain.Key;
                            ISubdomain subdomain       = idSubdomain.Value;
                            int        subdomainDofIdx = subdomain.FreeDofOrdering.FreeDofs[node, dofType];
                            subdomainLoads[id][subdomainDofIdx] = loadAmount * boundaryDofCoeffs[id];
                        }
                    }
                }
            }

            var subdomainVectors = new Dictionary <int, SparseVector>();

            foreach (var idSubdomains in subdomains)
            {
                int id = idSubdomains.Key;
                int numSubdomainDofs = idSubdomains.Value.FreeDofOrdering.NumFreeDofs;
                subdomainVectors[id] = SparseVector.CreateFromDictionary(numSubdomainDofs, subdomainLoads[id]);
            }
            return(subdomainVectors);
        }