예제 #1
0
        public double[] ExtractVectorElementFromSubdomain(IElement element, IVectorView subdomainVector)
        {
            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;
            }
            var elementVector = new double[numElementDofs];

            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[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
                }
            }

            return(elementVector);
        }
예제 #2
0
        public (int[] elementDofIndices, int[] subdomainDofIndices) MapFreeDofsElementToSubdomain(IElement element)
        {
            IReadOnlyList <INode> elementNodes = element.ElementType.DofEnumerator.GetNodesForMatrixAssembly(element);
            IReadOnlyList <IReadOnlyList <IDofType> > elementDofs = element.ElementType.DofEnumerator.GetDofTypesForMatrixAssembly(element);

            // Count the dof superset (free and constrained) to allocate enough memory and avoid resizing
            int allElementDofs = 0;

            for (int i = 0; i < elementNodes.Count; ++i)
            {
                allElementDofs += elementDofs[i].Count;
            }
            var elementDofIndices   = new List <int>(allElementDofs);
            var subdomainDofIndices = new List <int>(allElementDofs);

            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)
                    {
                        elementDofIndices.Add(elementDofIdx);
                        subdomainDofIndices.Add(subdomainDofIdx);
                    }
                    ++elementDofIdx; // This must be incremented for constrained dofs as well
                }
            }
            return(elementDofIndices.ToArray(), subdomainDofIndices.ToArray());
        }
예제 #3
0
        public (int[] elementDofIndices, int[] subdomainDofIndices) MapFreeDofsElementToSubdomain(IElement element)
        {
            var collocationElement = ((ICollocationElement)element);

            //IList<INode> elementNodes = element.ElementType.DofEnumerator.GetNodesForMatrixAssembly(element);
            //IList<IList<DOFType>> elementDofs = element.ElementType.DofEnumerator.GetDOFTypes(element);

            // Count the dof superset (free and constrained) to allocate enough memory and avoid resizing
            var rowDofs             = collocationElement.GetDOFTypesForDOFEnumeration(element);
            int allElementDofs      = rowDofs.Count;
            var elementDofIndices   = new List <int>(allElementDofs);
            var subdomainDofIndices = new List <int>(allElementDofs);
            var elementDofs         = new IDofType[1][];

            elementDofs[0] = rowDofs.ToArray();

            int elementDofIdx = 0;

            for (int dofIdx = 0; dofIdx < elementDofs[0].Length; ++dofIdx)
            {
                bool isFree = FreeDofs.TryGetValue(collocationElement.CollocationPoint, elementDofs[0][dofIdx],
                                                   out int subdomainDofIdx);
                if (isFree)
                {
                    elementDofIndices.Add(elementDofIdx);
                    subdomainDofIndices.Add(subdomainDofIdx);
                }
                ++elementDofIdx;
            }

            return(elementDofIndices.ToArray(), subdomainDofIndices.ToArray());
        }
예제 #4
0
        public void Reorder(IReorderingAlgorithm reorderingAlgorithm, ISubdomain subdomain)
        {
            var pattern = SparsityPatternSymmetric.CreateEmpty(NumFreeDofs);

            foreach (var element in subdomain.Elements)
            {
                (int[] elementDofIndices, int[] subdomainDofIndices) = MapFreeDofsElementToSubdomain(element);

                //TODO: ISubdomainFreeDofOrdering could perhaps return whether the subdomainDofIndices are sorted or not.
                pattern.ConnectIndices(subdomainDofIndices, false);
            }
            (int[] permutation, bool oldToNew) = reorderingAlgorithm.FindPermutation(pattern);
            FreeDofs.Reorder(permutation, oldToNew);
        }
예제 #5
0
        public void AddVectorElementToSubdomain(IElement element, double[] elementVector, IVector subdomainVector)
        {
            IReadOnlyList <INode> elementNodes = element.ElementType.DofEnumerator.GetNodesForMatrixAssembly(element);
            IReadOnlyList <IReadOnlyList <IDofType> > elementDofs = element.ElementType.DofEnumerator.GetDofTypesForMatrixAssembly(element);

            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)
                    {
                        subdomainVector.Set(subdomainDofIdx, subdomainVector[subdomainDofIdx] + elementVector[elementDofIdx]);
                    }
                    ++elementDofIdx; // This must be incremented for constrained dofs as well
                }
            }
        }
예제 #6
0
 public void ReorderNodeMajor(IReadOnlyList <INode> sortedNodes) => FreeDofs.ReorderNodeMajor(sortedNodes);