Example #1
0
        public IMatrix GetSecondSpaceDerivatives(ISubdomain subdomain, IVectorView vector)
        {
            var ndofs = model.Subdomains[subdomain.ID].Nodes.Count;
            var v1    = new double[] { 1, 0, 0 };
            var v2    = new double[] { 0, 1, 0 };
            var v3    = new double[] { 0, 0, 1 };
            var i1    = Vector.CreateFromArray(v1);
            var i2    = Vector.CreateFromArray(v2);
            var i3    = Vector.CreateFromArray(v3);
            var secondSpaceDerivatives = Matrix.CreateZero(ndofs, 1);
            var ddX  = (Vector)SecondDerivativeXMatrix[subdomain.ID].Multiply(vector);
            var ddY  = (Vector)SecondDerivativeYMatrix[subdomain.ID].Multiply(vector);
            var ddZ  = (Vector)SecondDerivativeZMatrix[subdomain.ID].Multiply(vector);
            var ddMX = ddX.TensorProduct(i1);
            var ddMY = ddY.TensorProduct(i2);
            var ddMZ = ddZ.TensorProduct(i3);

            ddMX.AddIntoThis(ddMY);
            ddMX.AddIntoThis(ddMZ);
            return(ddMX);
        }
        internal static void CsrTransTimesVector(int numCsrRows, double[] csrValues, int[] csrRowOffsets, int[] csrColIndices,
                                                 IVectorView lhs, IVector rhs)
        {
            var temp = new double[rhs.Length];

            CsrTransTimesVector(numCsrRows, csrValues, csrRowOffsets, csrColIndices, lhs, temp);
            rhs.CopyFrom(Vector.CreateFromArray(temp));

            // The following requires a lot of indexing into the rhs vector.
            //// A^T * x = linear combination of columns of A^T = rows of A, with the entries of x as coefficients
            //for (int i = 0; i < numCsrRows; ++i)
            //{
            //    double scalar = lhs[i];
            //    int rowStart = csrRowOffsets[i]; //inclusive
            //    int rowEnd = csrRowOffsets[i + 1]; //exclusive
            //    for (int k = rowStart; k < rowEnd; ++k)
            //    {
            //        rhs.Set(csrColIndices[k], rhs[csrColIndices[k]] + scalar * csrValues[k]);
            //    }
            //}
        }
Example #3
0
 /// <summary>
 /// See <see cref="IVectorView.LinearCombination(double, IVectorView, double)"/>.
 /// </summary>
 public IVector LinearCombination(double thisCoefficient, IVectorView otherVector, double otherCoefficient)
 {
     if (otherVector is Vector3 casted)
     {
         return(LinearCombination(thisCoefficient, casted, otherCoefficient));
     }
     else if (thisCoefficient == 1.0)
     {
         return(Axpy(otherVector, otherCoefficient));
     }
     else
     {
         Preconditions.CheckVectorDimensions(this, otherVector);
         return(new Vector3(new double[]
         {
             thisCoefficient *data[0] + otherCoefficient * otherVector[0],
             thisCoefficient *data[1] + otherCoefficient * otherVector[1],
             thisCoefficient *data[2] + otherCoefficient * otherVector[2]
         }));
     }
 }
        private static bool CompareResults(IVectorView solution)
        {
            var comparer = new ValueComparer(1E-5);

            //                                                   dofs:   1,   2,   4,   5,   7,   8
            var expectedSolution = Vector.CreateFromArray(new double[] { 150, 200, 150, 200, 150, 200 });
            int numFreeDofs      = 6;

            if (solution.Length != 6)
            {
                return(false);
            }
            for (int i = 0; i < numFreeDofs; ++i)
            {
                if (!comparer.AreEqual(expectedSolution[i], solution[i]))
                {
                    return(false);
                }
            }
            return(true);
        }
        private static bool CompareResults(IVectorView solution)
        {
            var comparer = new ValueComparer(1E-3);

            //                                               dofs:       4,       5,       6,       7,       8,       9,      13,      14,      15,      16,      17,      18,      22,      23,      24,      25,      26,  27
            var expectedSolution = Vector.CreateFromArray(new double[] { 135.054, 158.824, 135.054, 469.004, 147.059, 159.327, 178.178, 147.299, 139.469, 147.059, 191.717, 147.059, 135.054, 158.824, 135.054, 469.004, 147.059, 159.327 });
            int numFreeDofs      = 18;

            if (solution.Length != 18)
            {
                return(false);
            }
            for (int i = 0; i < numFreeDofs; ++i)
            {
                if (!comparer.AreEqual(expectedSolution[i], solution[i]))
                {
                    return(false);
                }
            }
            return(true);
        }
Example #6
0
        internal T Indexer_Get <T>(int index)
        {
            if (index < 0)
            {
                throw new ArgumentOutOfRangeException("index");
            }
            IVectorView <T> vectorView = JitHelpers.UnsafeCast <IVectorView <T> >((object)this);

            try
            {
                return(vectorView.GetAt((uint)index));
            }
            catch (Exception ex)
            {
                if (-2147483637 == ex._HResult)
                {
                    throw new ArgumentOutOfRangeException("index");
                }
                throw;
            }
        }
Example #7
0
        /// <summary>
        /// See <see cref="IVectorView.DotProduct(IVectorView)"/>.
        /// </summary>
        public double DotProduct(IVectorView vector)
        {
            Preconditions.CheckVectorDimensions(this, vector);

            if (vector is Vector dense)
            {
                return(SparseBlas.Ddoti(values.Length, values, indices, 0, dense.RawData, 0));
            }
            else if ((vector is SparseVector sparse) && HasSameIndexer(sparse))
            {
                return(Blas.Ddot(values.Length, this.values, 0, 1, sparse.values, 0, 1));
            }

            double sum = 0;

            for (int i = 0; i < values.Length; ++i)
            {
                sum += values[i] * vector[indices[i]];
            }
            return(sum);
        }
Example #8
0
        /// <summary>
        /// See <see cref="IVector.AxpySubvectorIntoThis(int, IVectorView, double, int, int)"/>
        /// </summary>
        public void AxpySubvectorIntoThis(int destinationIndex, IVectorView sourceVector, double sourceCoefficient,
                                          int sourceIndex, int length)
        {
            Preconditions.CheckSubvectorDimensions(this, destinationIndex, length);
            Preconditions.CheckSubvectorDimensions(sourceVector, sourceIndex, length);

            if (sourceVector is Vector2 casted)
            {
                for (int i = 0; i < length; ++i)
                {
                    data[i + destinationIndex] += sourceCoefficient * casted.data[i + sourceIndex];
                }
            }
            else
            {
                for (int i = 0; i < length; ++i)
                {
                    data[i + destinationIndex] += sourceCoefficient * sourceVector[i + sourceIndex];
                }
            }
        }
Example #9
0
        public IVector GetRhsFromSolution(IVectorView solution, IVectorView dSolution)
        {
            var forces = Vector.CreateZero(FreeDofOrdering.NumFreeDofs); //TODO: use Vector

            foreach (Element element in Elements)
            {
                //var localSolution = GetLocalVectorFromGlobal(element, solution);//TODOMaria: This is where the element displacements are calculated //removeMaria
                //var localdSolution = GetLocalVectorFromGlobal(element, dSolution);//removeMaria

                //TODO: ElementType should operate with Vector instead of double[]. Then the ToRawArray() calls can be removed
                double[] localSolution  = CalculateElementDisplacements(element, solution);
                double[] localdSolution = CalculateElementDisplacements(element, dSolution);
                element.ElementType.CalculateStresses(element, localSolution, localdSolution);
                if (element.ElementType.MaterialModified)
                {
                    element.Subdomain.StiffnessModified = true;
                }
                var f = element.ElementType.CalculateForces(element, localSolution, localdSolution);
                FreeDofOrdering.AddVectorElementToSubdomain(element, f, forces);
            }
            return(forces);
        }
Example #10
0
        /// <summary>
        /// See <see cref="IVector.AxpySubvectorIntoThis(int, IVectorView, double, int, int)"/>.
        /// </summary>
        public void AxpySubvectorIntoThis(int destinationIndex, IVectorView sourceVector, double sourceCoefficient,
                                          int sourceIndex, int length)
        {
            //TODO: needs testing for off-by-1 bugs and extension to cases where source and destination indices are different.

            Preconditions.CheckSubvectorDimensions(this, destinationIndex, length);
            Preconditions.CheckSubvectorDimensions(sourceVector, sourceIndex, length);

            if ((sourceVector is SparseVector otherSparse) && HasSameIndexer(otherSparse))
            {
                if (destinationIndex != sourceIndex)
                {
                    throw new NotImplementedException();
                }
                int start        = Array.FindIndex(this.indices, x => x >= destinationIndex);
                int end          = Array.FindIndex(this.indices, x => x >= destinationIndex + length);
                int sparseLength = end - start;
                Blas.Daxpy(sparseLength, sourceCoefficient, otherSparse.values, start, 1, this.values, start, 1);
            }
            throw new SparsityPatternModifiedException(
                      "This operation is legal only if the other vector has the same sparsity pattern");
        }
Example #11
0
 /// <summary>
 /// See <see cref="IVector.AddIntoThisNonContiguouslyFrom(int[], IVectorView)"/>
 /// </summary>
 public void AddIntoThisNonContiguouslyFrom(int[] thisIndices, IVectorView otherVector)
 {
     if (thisIndices.Length != otherVector.Length)
     {
         throw new NonMatchingDimensionsException(
                   "thisIndices and otherVector must have the same length.");
     }
     if (otherVector is Vector casted)
     {
         for (int i = 0; i < casted.Length; ++i)
         {
             this.data[thisIndices[i]] += casted.data[i];
         }
     }
     else
     {
         for (int i = 0; i < otherVector.Length; ++i)
         {
             data[thisIndices[i]] += otherVector[i];
         }
     }
 }
Example #12
0
        //ADDED1
        public IVector GetRHSFromSolutionWithInitialDisplacementsEffect(IVectorView solution, IVectorView dSolution, Dictionary <int, INode> boundaryNodes,
                                                                        Dictionary <int, Dictionary <IDofType, double> > initialConvergedBoundaryDisplacements, Dictionary <int, Dictionary <IDofType, double> > totalBoundaryDisplacements,
                                                                        int nIncrement, int totalIncrements)
        {
            var forces = Vector.CreateZero(FreeDofOrdering.NumFreeDofs);             //TODO: use Vector

            foreach (Element element in Elements)
            {
                var localSolution = GetLocalVectorFromGlobalWithoutPrescribedDisplacements(element, solution);
                ImposePrescribedDisplacementsWithInitialConditionSEffect(element, localSolution, boundaryNodes, initialConvergedBoundaryDisplacements, totalBoundaryDisplacements, nIncrement, totalIncrements);
                var localdSolution = GetLocalVectorFromGlobalWithoutPrescribedDisplacements(element, dSolution);
                ImposePrescribed_d_DisplacementsWithInitialConditionSEffect(element, localdSolution, boundaryNodes, initialConvergedBoundaryDisplacements, totalBoundaryDisplacements, nIncrement, totalIncrements);
                element.ElementType.CalculateStresses(element, localSolution, localdSolution);
                if (element.ElementType.MaterialModified)
                {
                    element.Subdomain.StiffnessModified = true;
                }
                var f = element.ElementType.CalculateForces(element, localSolution, localdSolution);
                FreeDofOrdering.AddVectorElementToSubdomain(element, f, forces);
            }
            return(forces);
        }
Example #13
0
 /// <summary>
 /// See <see cref="IVector.CopyNonContiguouslyFrom(IVectorView, int[])"/>
 /// </summary>
 public void CopyNonContiguouslyFrom(IVectorView otherVector, int[] otherIndices)
 {
     if (otherIndices.Length != this.Length)
     {
         throw new NonMatchingDimensionsException(
                   "otherIndices and this vector must have the same length.");
     }
     if (otherVector is Vector casted)
     {
         for (int i = 0; i < this.Length; ++i)
         {
             this.data[i] = casted.data[otherIndices[i]];
         }
     }
     else
     {
         for (int i = 0; i < this.Length; ++i)
         {
             data[i] = otherVector[otherIndices[i]];
         }
     }
 }
Example #14
0
        public Vector GatherGlobalForces(Dictionary <int, IVectorView> subdomainForces)
        {
            var globalForces = Vector.CreateZero(model.GlobalDofOrdering.NumGlobalFreeDofs);

            foreach (ISubdomain subdomain in model.Subdomains)
            {
                int         id = subdomain.ID;
                int[]       subdomainFreeToGlobalDofs = model.GlobalDofOrdering.MapFreeDofsSubdomainToGlobal(subdomain);
                IVectorView forces = subdomainForces[id]; //TODO: benchmark the performance if this was concrete Vector

                for (int i = 0; i < forces.Length; ++i)
                {
                    // Internal forces will be copied (which is identical to adding 0 + single value).
                    // Boundary remainder forces will be summed. Previously we had distributed them depending on
                    // homogeneity / heterogeneity (e.g. Ftot = 0.4 * Ftot + 0.6 * Ftot) and now we sum them.
                    // Boundary corner forces are also summed. Previously we had also distributed them equally irregardless of
                    // homogeneity / heterogeneity (e.g. Ftot = 0.5 * Ftot + 0.5 * Ftot) and now we sum them.
                    globalForces[subdomainFreeToGlobalDofs[i]] += forces[i];
                }
            }
            return(globalForces);
        }
Example #15
0
        public Vector GatherGlobalDisplacements(Dictionary <int, IVectorView> subdomainRemainderDisplacements,
                                                IVectorView globalCornerDisplacements)
        {
            var globalDisplacements = Vector.CreateZero(model.GlobalDofOrdering.NumGlobalFreeDofs);

            // Remainder dofs
            foreach (ISubdomain subdomain in model.Subdomains)
            {
                int         id = subdomain.ID;
                int[]       freeToGlobalDofs       = model.GlobalDofOrdering.MapFreeDofsSubdomainToGlobal(subdomain);
                int[]       remainderToFreeDofs    = dofSeparator.RemainderDofIndices[id];
                IVectorView remainderDisplacements = subdomainRemainderDisplacements[id]; //TODO: benchmark the performance if this was concrete Vector

                // Internal dofs are copied without averaging.
                foreach (int remainderDofIdx in dofSeparator.InternalDofIndices[id])
                {
                    int globalDofIdx = freeToGlobalDofs[remainderToFreeDofs[remainderDofIdx]];
                    globalDisplacements[globalDofIdx] = remainderDisplacements[remainderDofIdx];
                }

                // For boundary dofs we take average across subdomains with respect to multiplicity or stiffness.
                double[] boundaryDofCoeffs = distribution.CalcBoundaryDofCoefficients(subdomain);
                for (int i = 0; i < dofSeparator.BoundaryDofIndices[id].Length; ++i)
                {
                    int remainderDofIdx = dofSeparator.BoundaryDofIndices[id][i];
                    int globalDofIdx    = freeToGlobalDofs[remainderToFreeDofs[remainderDofIdx]];
                    globalDisplacements[globalDofIdx] += remainderDisplacements[remainderDofIdx] * boundaryDofCoeffs[i];
                }
            }

            // Corner dofs are copied without averaging.
            for (int i = 0; i < dofSeparator.NumGlobalCornerDofs; ++i)
            {
                int globalDofIdx = dofSeparator.GlobalCornerToFreeDofMap[i];
                globalDisplacements[globalDofIdx] = globalCornerDisplacements[i];
            }

            return(globalDisplacements);
        }
Example #16
0
        /// <summary>
        /// See <see cref="IMatrixView.Multiply(IVectorView, bool)"/>.
        /// </summary>
        public IVector Multiply(IVectorView vector, bool transposeThis = false)
        {
            if (vector is Vector dense)
            {
                return(Multiply(dense, transposeThis));
            }

            if (transposeThis)
            {
                var result = new double[NumColumns];
                Preconditions.CheckMultiplicationDimensions(NumRows, vector.Length);
                CsrMultiplications.CsrTimesVector(NumColumns, values, colOffsets, rowIndices, vector, result);
                return(Vector.CreateFromArray(result, false));
            }
            else
            {
                var result = new double[NumRows];
                Preconditions.CheckMultiplicationDimensions(NumColumns, vector.Length);
                CsrMultiplications.CsrTransTimesVector(NumColumns, values, colOffsets, rowIndices, vector, result);
                return(Vector.CreateFromArray(result, false));
            }
        }
Example #17
0
        internal double CalculateForceAt(Node node, IDofType dofType, IVectorView totalDisplacements)
        {
            double totalForce = 0.0;

            foreach (Element element in node.ElementsDictionary.Values)
            {
                // It is possible that one of the elements at this node does not engage this dof type, in which case -1 will be returned.
                // We will not have any contribution from them. If none of the elements engage this dof type, the total force will always be 0.
                int monitorDofIdx = FindLocalDofIndex(element, node, dofType);
                if (monitorDofIdx == -1)
                {
                    continue;
                }

                //TODO: if an element has embedded elements, then we must also take into account their forces.
                double[] totalElementDisplacements = subdomain.CalculateElementDisplacements(element, totalDisplacements);
                double[] elementForces             = element.ElementType.CalculateForcesForLogging(element, totalElementDisplacements);

                totalForce += elementForces[monitorDofIdx];
            }

            return(totalForce);
        }
Example #18
0
        /// <summary>
        /// Solves the linear system A * x = b, where A = <paramref name="matrix"/> and b = <paramref name="rhs"/>.
        /// Initially x = <paramref name="initialGuess"/> and then it converges to the solution.
        /// </summary>
        /// <param name="matrix">
        /// Represents the matrix A of the linear system A * x = b, which must be symmetric positive definite.
        /// </param>
        /// <param name="rhs">
        /// The right hand side vector b of the linear system A * x = b. Constraints:
        /// <paramref name="rhs"/>.<see cref="IIndexable1D.Length"/>
        /// == <paramref name="matrix"/>.<see cref="IIndexable2D.NumRows"/>.
        /// </param>
        /// <param name="solution">
        /// The vector from which to start refining the solution vector x. Constraints:
        /// <paramref name="solution"/>.<see cref="IIndexable1D.Length"/>
        /// == <paramref name="matrix"/>.<see cref="IIndexable2D.NumColumns"/>.
        /// </param>
        /// <param name="initialGuessIsZero">
        /// If <paramref name="solution"/> is 0, then set <paramref name="initialGuessIsZero"/> to true to avoid performing the
        /// operation b-A*0 before starting.
        /// </param>
        /// <exception cref="NonMatchingDimensionsException">
        /// Thrown if <paramref name="rhs"/> or <paramref name="solution"/> violate the described constraints.
        /// </exception>
        public IterativeStatistics Solve(ILinearTransformation matrix, IVectorView rhs, IVector solution,
                                         bool initialGuessIsZero) //TODO: find a better way to handle the case x0=0
        {
            //TODO: these will also be checked by the matrix vector multiplication.
            Preconditions.CheckMultiplicationDimensions(matrix.NumColumns, solution.Length);
            Preconditions.CheckSystemSolutionDimensions(matrix.NumRows, rhs.Length);

            this.Matrix   = matrix;
            this.Rhs      = rhs;
            this.solution = solution;

            // r = b - A * x
            if (initialGuessIsZero)
            {
                residual = rhs.Copy();
            }
            else
            {
                residual = ExactResidual.Calculate(matrix, rhs, solution);
            }

            return(SolveInternal(maxIterationsProvider.GetMaxIterations(matrix.NumColumns)));
        }
Example #19
0
 /// <summary>
 /// See <see cref="IVectorView.Axpy(IVectorView, double)"/>.
 /// </summary>
 public IVector Axpy(IVectorView otherVector, double otherCoefficient)
 {
     Preconditions.CheckVectorDimensions(this, otherVector);
     if (otherVector is SparseVector otherSparse) // In case both matrices have the exact same index arrays
     {
         if (HasSameIndexer(otherSparse))
         {
             // Do not copy the index arrays, since they are already spread around. TODO: is this a good idea?
             double[] result = new double[this.values.Length];
             Array.Copy(this.values, result, this.values.Length);
             Blas.Daxpy(values.Length, otherCoefficient, otherSparse.values, 0, 1, result, 0, 1);
             return(new SparseVector(Length, result, indices));
         }
     }
     else if (otherVector is Vector otherDense)
     {
         double[] result = otherDense.Scale(otherCoefficient).RawData;
         SparseBlas.Daxpyi(this.indices.Length, 1.0, this.values, this.indices, 0, result, 0);
         return(Vector.CreateFromArray(result, false));
     }
     // All entries must be processed. TODO: optimizations may be possible (e.g. only access the nnz in this vector)
     return(DenseStrategies.LinearCombination(this, 1.0, otherVector, otherCoefficient));
 }
        public void UpdateModelAndAnalyze(IVectorView youngModuli)
        {
            this.youngModuli = youngModuli;

            // Global stiffness matrix assembly
            int numAllDofs = 2 * (numElementsX + 1) * (numElementsY + 1);
            var K          = DokSymmetric.CreateEmpty(numAllDofs);

            for (int e = 0; e < NumElements; ++e)
            {
                int[] elementDofsGlobal = GetElementDofs(e);
                K.AddSubmatrixSymmetric(unitStiffness.Scale(youngModuli[e]), elementDofsLocal, elementDofsGlobal);
            }

            // Apply boundary conditions
            (int[] freeDofs, Vector[] Fs) = ApplyBoundaryConditions();
            int numLoadCases = Fs.Length;

            globalDisplacements = new Vector[numLoadCases];

            // Solve linear system
            DokSymmetric Kf     = K.GetSubmatrix(freeDofs);
            var          factor = CholeskyCSparseNet.Factorize(Kf.BuildSymmetricCscMatrix(true));

            for (int c = 0; c < numLoadCases; ++c)
            {
                Vector Ff = Fs[c].GetSubvector(freeDofs);
                Vector Uf = factor.SolveLinearSystem(Ff);
                var    U  = Vector.CreateZero(numAllDofs);
                for (int i = 0; i < freeDofs.Length; ++i)
                {
                    U[freeDofs[i]] = Uf[i];
                }
                globalDisplacements[c] = U;
                //U.CopyNonContiguouslyFrom(freeDofs, Uf, Enumerable.Range(0, freeDofs.Length).ToArray()); // alternative way, but probably slower.
            }
        }
        /// <summary>
        /// Solves the linear system A * x = b by solving the preconditioned system inv(P) * A * inv(P)^T * y = inv(P) * b,
        /// where A = <paramref name="matrix"/>, b = <paramref name="rhsVector"/>, x is the solution, y = P^T * x,
        /// P*P^T = <paramref name="preconditioner"/>.
        /// Initially x = <paramref name="initialGuess"/> and then it converges to the solution.
        /// </summary>
        /// <param name="matrix">
        /// Represents the matrix A of the linear system A * x = b, which must be symmetric positive definite.
        /// </param>
        /// <param name="rhs">
        /// The right hand side vector b of the linear system A * x = b. Constraints:
        /// <paramref name="rhs"/>.<see cref="IIndexable1D.Length"/>
        /// == <paramref name="matrix"/>.<see cref="IIndexable2D.NumRows"/>.
        /// </param>
        /// <param name="preconditioner">
        /// A preconditioner matrix that is also symmetric positive definite and has the same dimensions as A.
        /// </param>
        /// <param name="solution">
        /// The vector from which to start refining the solution vector x. Constraints:
        /// <paramref name="solution"/>.<see cref="IIndexable1D.Length"/>
        /// == <paramref name="matrix"/>.<see cref="IIndexable2D.NumColumns"/>.
        /// </param>
        /// <param name="initialGuessIsZero">
        /// If <paramref name="solution"/> is 0, then set <paramref name="initialGuessIsZero"/> to true to avoid performing the
        /// operation b-A*0 before starting.
        /// </param>
        /// <exception cref="NonMatchingDimensionsException">
        /// Thrown if <paramref name="rhs"/> or <paramref name="solution"/> violate the described constraints.
        /// </exception>
        public virtual IterativeStatistics Solve(ILinearTransformation matrix, IPreconditioner preconditioner, IVectorView rhs,
                                                 IVector solution, bool initialGuessIsZero, Func <IVector> zeroVectorInitializer)
        {
            //TODO: find a better way to handle optimizations for the case x0=0, than using an initialGuessIsZero flag

            Preconditions.CheckMultiplicationDimensions(matrix.NumColumns, solution.Length);
            Preconditions.CheckSystemSolutionDimensions(matrix.NumRows, rhs.Length);

            this.Matrix         = matrix;
            this.Preconditioner = preconditioner;
            this.Rhs            = rhs;
            this.solution       = solution;

            // r = b - A * x
            if (initialGuessIsZero)
            {
                residual = rhs.Copy();
            }
            else
            {
                residual = ExactResidual.Calculate(matrix, rhs, solution);
            }
            return(SolveInternal(MaxIterationsProvider.GetMaxIterations(matrix.NumColumns), zeroVectorInitializer));
        }
Example #22
0
        public void ExtractVectorElementFromSubdomain(IElement element, IVectorView subdomainVector, IVector elementVector)
        {
            IReadOnlyList <INode> elementNodes = element.ElementType.DofEnumerator.GetNodesForMatrixAssembly(element);
            IReadOnlyList <IReadOnlyList <IDofType> > elementDofs = element.ElementType.DofEnumerator.GetDofTypesForMatrixAssembly(element);
            //int numElementDofs = 0;
            //for (int nodeIdx = 0; nodeIdx < elementDofs.Count; ++nodeIdx) numElementDofs += elementDofs[nodeIdx].Count;

            int elementDofIdx = 0;

            for (int nodeIdx = 0; nodeIdx < elementNodes.Count; ++nodeIdx)
            {
                for (int dofIdx = 0; dofIdx < elementDofs[nodeIdx].Count; ++dofIdx)
                {
                    bool isFree = FreeDofs.TryGetValue(elementNodes[nodeIdx], elementDofs[nodeIdx][dofIdx],
                                                       out int subdomainDofIdx);
                    if (isFree)
                    {
                        elementVector.Set(elementDofIdx, subdomainVector[subdomainDofIdx]);
                    }
                    // Else, the quantity of interest is 0.0 at all constrained dofs.
                    ++elementDofIdx; // This must be incremented for constrained dofs as well
                }
            }
        }
        // Stiffness ratio = 1E-6
        //[InlineData(1E-6, InterfaceSolver.Method1, Precond.Dirichlet, MatrixQ.Identity, Residual.Exact, 40)] // converges, stagnates almost before the tolerance and then diverges
        //[InlineData(1E-6, InterfaceSolver.Method2, Precond.Dirichlet, MatrixQ.Precond, Residual.Exact, 9)] // converges, stagnates almost before the tolerance and then diverges
        //[InlineData(1E-6, InterfaceSolver.Method3, Precond.Dirichlet, MatrixQ.Precond, Residual.Exact, 23)] //3
        //[InlineData(1E-6, InterfaceSolver.Method4, Precond.Dirichlet, MatrixQ.Precond, Residual.Exact, 9)] // converges, stagnates almost before the tolerance and then diverges
        //[InlineData(1E-6, InterfaceSolver.Default, Precond.Dirichlet, MatrixQ.Precond, Residual.Approximate, 9)]
        public static void Run(double stiffnessRatio, InterfaceSolver interfaceSolver, Precond precond, MatrixQ q,
            Residual convergence, int iterExpected)
        {
            //InterfaceSolver interfaceSolver = 0;
            double factorizationTol = 1E-3, pcpgConvergenceTol = 1E-5;
            IVectorView directDisplacements = SolveModelWithoutSubdomains(stiffnessRatio);
            (IVectorView ddDisplacements, SolverLogger logger, int numUniqueGlobalDofs, int numExtenedDomainDofs) =
                SolveModelWithSubdomains(stiffnessRatio, interfaceSolver, precond, q, convergence, 
                    factorizationTol, pcpgConvergenceTol);
            double normalizedError = directDisplacements.Subtract(ddDisplacements).Norm2() / directDisplacements.Norm2();

            int analysisStep = 0;
            Assert.Equal(882, numUniqueGlobalDofs);    // 882 includes constrained and free dofs
            Assert.Equal(1056, numExtenedDomainDofs); // 1056 includes constrained and free dofs
            Assert.Equal(190, logger.GetNumDofs(analysisStep, "Lagrange multipliers"));

            // The error is provided in the reference solution the, but it is almost impossible for two different codes run on 
            // different machines to achieve the exact same accuracy.
            Assert.Equal(0.0, normalizedError, 5);

            // Allow a tolerance: It is ok if my solver is better or off by 1 iteration 
            int pcgIterations = logger.GetNumIterationsOfIterativeAlgorithm(analysisStep);
            Assert.InRange(pcgIterations, 1, iterExpected + 1); // the upper bound is inclusive!
        }
        public static void Run(double stiffnessRatio, Precond precond, Residual convergence, int iterExpected)
        {
            double      pcgConvergenceTol   = 1E-5;
            IVectorView directDisplacements = SolveModelWithoutSubdomains(stiffnessRatio);

            (IVectorView ddDisplacements, SolverLogger logger) =
                SolveModelWithSubdomains(stiffnessRatio, precond, convergence, pcgConvergenceTol);
            double normalizedError = directDisplacements.Subtract(ddDisplacements).Norm2() / directDisplacements.Norm2();

            int analysisStep = 0;

            Assert.Equal(140, logger.GetNumDofs(analysisStep, "Lagrange multipliers"));
            Assert.Equal(20, logger.GetNumDofs(analysisStep, "Corner dofs"));

            // The error is provided in the reference solution the, but it is almost impossible for two different codes run on
            // different machines to achieve the exact same accuracy.
            Assert.Equal(0.0, normalizedError, 6);

            // Allow some tolerance for the iterations:
            int maxIterationsForApproximateResidual = (int)Math.Ceiling(1.0 * iterExpected);
            int pcgIterations = logger.GetNumIterationsOfIterativeAlgorithm(analysisStep);

            Assert.InRange(pcgIterations, 1, maxIterationsForApproximateResidual); // the upper bound is inclusive!
        }
Example #25
0
 /// <summary>
 /// See <see cref="IVector.AxpyIntoThis(IVectorView, double)"/>.
 /// </summary>
 public void AxpyIntoThis(IVectorView otherVector, double otherCoefficient)
 {
     if (otherVector is Vector dense)
     {
         AxpyIntoThis(dense, otherCoefficient);
     }
     else
     {
         Preconditions.CheckVectorDimensions(this, otherVector);
         if (otherVector is SparseVector sparse)
         {
             //TODO: should I check whether the sparse vector is all 0, in order to avoid the BLAS call?
             SparseBlas.Daxpyi(sparse.RawIndices.Length, otherCoefficient, sparse.RawValues,
                               sparse.RawIndices, 0, data, 0);
         }
         else
         {
             for (int i = 0; i < Length; ++i)
             {
                 this.data[i] += otherCoefficient * otherVector[i];
             }
         }
     }
 }
Example #26
0
 private static void WinRT_IReadOnlyList <T>(IVectorViewToIReadOnlyListAdapter vectorToListAdapter, IReadOnlyListToIVectorViewAdapter listToVectorAdapter, IVectorView <T> vectorView)
 {
     Internal.WinRT_IEnumerable <T>(null, null, null);
     Internal.WinRT_IReadOnlyCollection <T>(null);
     vectorToListAdapter.Indexer_Get <T>(0);
     listToVectorAdapter.GetAt <T>(0U);
     listToVectorAdapter.Size <T>();
 }
        public static double[] CalculateFppReactionsVector(Subdomain subdomain, IElementMatrixProvider elementProvider,
                                                           IScaleTransitions scaleTransitions, Dictionary <int, INode> boundaryNodes, IVectorView solution, IVectorView dSolution,
                                                           Dictionary <int, Dictionary <IDofType, double> > initialConvergedBoundaryDisplacements, Dictionary <int, Dictionary <IDofType, double> > totalBoundaryDisplacements,
                                                           int nIncrement, int totalIncrements)
        {
            //TODOGerasimos: 1) Subdomain2 einai h upo kataskevh subdomain.cs ths Marias gia na mporoume na anaferthoume sthn methodo ths CalculateElementNodalDisplacements(..,..).
            // Otan parei telikh morfh tha taftizetai me thn Subdomain.cs
            // 2)IVector solution, IVector dSolution EINAI AFTA ME TA OPOIA kaloume thn GetRHSFromSolution sthn 213 tou NRNLAnalyzer
            double[] FppReactionVector;
            Dictionary <int, int> boundaryNodesOrder = GetNodesOrderInDictionary(boundaryNodes);

            FppReactionVector = new double[boundaryNodesOrder.Count * scaleTransitions.PrescribedDofsPerNode()]; // h allliws subdomain.Forces.GetLength(0)


            var times      = new Dictionary <string, TimeSpan>();
            var totalStart = DateTime.Now;

            times.Add("rowIndexCalculation", DateTime.Now - totalStart);
            times.Add("element", TimeSpan.Zero);
            times.Add("addition", TimeSpan.Zero);
            foreach (Element element in subdomain.Elements)
            {
                var isEmbeddedElement = element.ElementType is IEmbeddedElement;
                var elStart           = DateTime.Now;
                //IMatrix2D ElementK = elementProvider.Matrix(element);
                var localSolution = subdomain.GetLocalVectorFromGlobalWithoutPrescribedDisplacements(element, solution);
                subdomain.ImposePrescribedDisplacementsWithInitialConditionSEffect(element, localSolution, boundaryNodes, initialConvergedBoundaryDisplacements, totalBoundaryDisplacements, nIncrement, totalIncrements);
                double[] localdSolution = subdomain.GetLocalVectorFromGlobalWithoutPrescribedDisplacements(element, dSolution);
                double[] f = element.ElementType.CalculateForces(element, localSolution, localdSolution);

                times["element"] += DateTime.Now - elStart;

                elStart = DateTime.Now;
                var elementDOFTypes     = element.ElementType.DofEnumerator.GetDofTypesForMatrixAssembly(element);
                var matrixAssemblyNodes = element.ElementType.DofEnumerator.GetNodesForMatrixAssembly(element);
                int iElementMatrixRow   = 0;
                for (int i = 0; i < elementDOFTypes.Count; i++)
                {
                    INode nodeRow = matrixAssemblyNodes[i];
                    if (boundaryNodes.ContainsKey(nodeRow.ID))
                    {
                        for (int i1 = 0; i1 < scaleTransitions.PrescribedDofsPerNode(); i1++)
                        {
                            int dofrow_p = scaleTransitions.PrescribedDofsPerNode() * (boundaryNodesOrder[nodeRow.ID] - 1) + i1;
                            FppReactionVector[dofrow_p] += f[iElementMatrixRow + i1];
                        }
                    }
                    iElementMatrixRow += elementDOFTypes[i].Count;
                }
                times["addition"] += DateTime.Now - elStart;
            }
            var totalTime = DateTime.Now - totalStart;

            return(FppReactionVector);
        }
 /// <summary>
 /// Solves the linear system A * x = b by solving the preconditioned system inv(P) * A * inv(P)^T * y = inv(P) * b,
 /// where A = <paramref name="matrix"/>, b = <paramref name="rhsVector"/>, x is the solution, y = P^T * x,
 /// P*P^T = <paramref name="preconditioner"/>.
 /// Initially x = <paramref name="initialGuess"/> and then it converges to the solution.
 /// </summary>
 /// <param name="matrix">The matrix A of the linear system A * x = b. It must be symmetric positive definite.</param>
 /// <param name="rhs">
 /// The right hand side vector b of the linear system A * x = b. Constraints:
 /// <paramref name="rhs"/>.<see cref="IIndexable1D.Length"/>
 /// == <paramref name="matrix"/>.<see cref="IIndexable2D.NumRows"/>.
 /// </param>
 /// <param name="preconditioner">
 /// A preconditioner matrix that is also symmetric positive definite and has the same dimensions as A.
 /// </param>
 /// <param name="solution">
 /// The vector from which to start refining the solution vector x. Constraints:
 /// <paramref name="solution"/>.<see cref="IIndexable1D.Length"/>
 /// == <paramref name="matrix"/>.<see cref="IIndexable2D.NumColumns"/>.
 /// </param>
 /// <param name="initialGuessIsZero">
 /// If <paramref name="solution"/> is 0, then set <paramref name="initialGuessIsZero"/> to true to avoid performing the
 /// operation b-A*0 before starting.
 /// </param>
 /// <exception cref="NonMatchingDimensionsException">
 /// Thrown if <paramref name="rhs"/> or <paramref name="solution"/> violate the described constraints.
 /// </exception>
 public IterativeStatistics Solve(IMatrixView matrix, IPreconditioner preconditioner, IVectorView rhs, IVector solution,
                                  bool initialGuessIsZero, Func <IVector> zeroVectorInitializer) //TODO: find a better way to handle the case x0=0
 {
     return(Solve(new ExplicitMatrixTransformation(matrix), preconditioner, rhs, solution, initialGuessIsZero,
                  zeroVectorInitializer));
 }
 public IVectorViewToIBindableVectorViewAdapter(IVectorView <T> vectorView)
 {
     _vectorView = vectorView;
 }
Example #30
0
 public IVector GetRhsFromSolution(IVectorView solution, IVectorView dSolution)
 {
     throw new NotImplementedException();
 }