OrderUnconstrainedDofs(Model2D_old model)
        {
            ITable <XNode, StructuralDof, double> constraints = model.Constraints;
            var standardDofs = new DofTable <StructuralDof>();
            var enrichedDofs = new DofTable <EnrichedDof>();
            int dofCounter   = 0;

            foreach (XNode node in model.Nodes)
            {
                // Standard free dofs. No rotational dofs. They can be X or Y. One or both of them may be constrained.
                if (!constraints.Contains(node, StructuralDof.TranslationX))
                {
                    standardDofs[node, StructuralDof.TranslationX] = dofCounter++;
                }
                if (!constraints.Contains(node, StructuralDof.TranslationY))
                {
                    standardDofs[node, StructuralDof.TranslationY] = dofCounter++;
                }

                // Enriched dofs. No rotational dofs. They cannot be constrained.
                foreach (IEnrichmentItem2D enrichment in node.EnrichmentItems.Keys)
                {
                    foreach (EnrichedDof dofType in enrichment.Dofs)
                    {
                        enrichedDofs[node, dofType] = dofCounter++;
                    }
                }
            }
            return(standardDofs, enrichedDofs);
            //TODO: Also return each table's count, by keeping separate counters. This avoids the O(numRows) Table.Count()
        }
Пример #2
0
 private XClusterDofOrderer(XCluster2D cluster, int numConstrainedDofs,
                            DofTable <StructuralDof> constrainedDofs, int numStandardDofs, DofTable <StructuralDof> standardDofs)
 {
     this.cluster            = cluster;
     this.NumConstrainedDofs = numConstrainedDofs;
     this.constrainedDofs    = constrainedDofs;
     this.NumStandardDofs    = numStandardDofs;
     this.standardDofs       = standardDofs;
 }
Пример #3
0
 private XSubdomainDofOrderer(int numEnrichedDofs, DofTable <EnrichedDof> subdomainEnrichedDofs,
                              Dictionary <XNode, HashSet <IEnrichmentItem2D> > singularHeavisideEnrichments,
                              Dictionary <XNode, ISet <EnrichedDof> > boundaryDofs)
 {
     this.NumEnrichedDofs              = numEnrichedDofs;
     this.subdomainEnrichedDofs        = subdomainEnrichedDofs;
     this.SingularHeavisideEnrichments = singularHeavisideEnrichments;
     this.BoundaryDofs = boundaryDofs;
 }
Пример #4
0
 protected DofOrdererBase(int constrainedDofsCount, DofTable <StructuralDof> constrainedDofs,
                          int enrichedDofsCount, DofTable <EnrichedDof> enrichedDofs,
                          int standardDofsCount, DofTable <StructuralDof> standardDofs)
 {
     this.NumConstrainedDofs = constrainedDofsCount;
     this.constrainedDofs    = constrainedDofs;
     this.NumEnrichedDofs    = enrichedDofsCount;
     this.enrichedDofs       = enrichedDofs;
     this.NumStandardDofs    = standardDofsCount;
     this.standardDofs       = standardDofs;
 }
Пример #5
0
        private static (int numConstrainedDofs, DofTable <StructuralDof> constrainedDofs) OrderConstrainedDofs(
            ITable <XNode, StructuralDof, double> constraints)
        {
            var constrainedDofs = new DofTable <StructuralDof>();
            int counter         = 0;

            foreach ((XNode node, StructuralDof dofType, double displacement) in constraints)
            {
                constrainedDofs[node, dofType] = counter++;
            }
            return(counter, constrainedDofs);
        }
Пример #6
0
        /// <summary>
        /// </summary>
        /// <param name="element"></param>
        /// <param name="globalFreeVector">Both the free standard and enriched dofs.</param>
        /// <returns></returns>
        public Vector ExtractEnrichedDisplacementsOfElementFromGlobal(XContinuumElement2D element, Vector globalFreeVector)
        {
            DofTable <EnrichedDof> elementDofs = element.GetEnrichedDofs();

            double[] elementVector = new double[elementDofs.EntryCount];
            foreach ((XNode node, EnrichedDof dofType, int dofIdx) in elementDofs)
            {
                int globalEnrichedDof = enrichedDofs[node, dofType];
                elementVector[dofIdx] = globalFreeVector[globalEnrichedDof];
            }
            return(Vector.CreateFromArray(elementVector));
        }
Пример #7
0
        public static XSubdomainDofOrderer CreateNodeMajor(ICrackDescription crack, XSubdomain2D_old subdomain) //TODO: also add AMD reordering
        {
            // Handle nodes with singular Heaviside enrichment
            Dictionary <XNode, HashSet <IEnrichmentItem2D> > singularityHeavisideEnrichments =
                FindBoundaryNodesWithSingularHeaviside(crack, subdomain);

            if (singularityHeavisideEnrichments.Count > 0)
            {
                Console.Write($"WARNING: Subdomain {subdomain.ID} has boundary nodes that are enriched with Heaviside,");
                Console.Write(" but that would lead to singular matrices, since the nodal support in this subdomain only");
                Console.Write(" contains Gauss points with the same sign. It would be better to use another domain");
                Console.Write(" decomposition. The nodes in question are: ");
                foreach (var node in singularityHeavisideEnrichments.Keys)
                {
                    Console.Write(node + " ");
                }
                Console.WriteLine();
            }

            var subdomainEnrichedDofs = new DofTable <EnrichedDof>();
            var boundaryDofs          = new Dictionary <XNode, ISet <EnrichedDof> >();
            int dofCounter            = 0;

            foreach (XNode node in subdomain.AllNodes)
            {
                bool isboundaryNode = subdomain.BoundaryNodes.Contains(node);
                if (isboundaryNode && node.IsEnriched)
                {
                    boundaryDofs.Add(node, new HashSet <EnrichedDof>());
                }
                bool isSingularityNode = singularityHeavisideEnrichments.TryGetValue(node,
                                                                                     out HashSet <IEnrichmentItem2D> singularEnrichments);

                foreach (IEnrichmentItem2D enrichment in node.EnrichmentItems.Keys)
                {
                    if (isSingularityNode && singularEnrichments.Contains(enrichment))
                    {
                        continue;
                    }
                    foreach (EnrichedDof dof in enrichment.Dofs)
                    {
                        if (isboundaryNode)
                        {
                            boundaryDofs[node].Add(dof);
                        }
                        subdomainEnrichedDofs[node, dof] = dofCounter;
                        ++dofCounter;
                    }
                }
            }
            return(new XSubdomainDofOrderer(dofCounter, subdomainEnrichedDofs, singularityHeavisideEnrichments, boundaryDofs));
        }
Пример #8
0
        private static (int numStandardDofs, DofTable <StructuralDof> standardDofs) OrderStandardDofs(Model2D_old model)
        {
            ITable <XNode, StructuralDof, double> constraints = model.Constraints;
            var standardDofs = new DofTable <StructuralDof>();
            int counter      = 0;

            foreach (var node in model.Nodes)
            {
                if (!constraints.Contains(node, StructuralDof.TranslationX))
                {
                    standardDofs[node, StructuralDof.TranslationX] = counter++;
                }
                if (!constraints.Contains(node, StructuralDof.TranslationY))
                {
                    standardDofs[node, StructuralDof.TranslationY] = counter++;
                }
            }
            return(counter, standardDofs);
        }
Пример #9
0
        // Each artificial dof has index that is node major, then enrichment item major, then enrichment function major and finally axis minor
        private static (int enrichedDofsCount, DofTable <EnrichedDof> enrichedDofs) OrderEnrichedDofs(
            IEnumerable <XNode> nodes, int standardDofsCount)
        {
            var enrichedDofs = new DofTable <EnrichedDof>();
            int dofCounter   = standardDofsCount; // This if I put everything in the same matrix

            //int dofCounter = 0; // This if I use different matrices
            foreach (XNode node in nodes)
            {
                foreach (IEnrichmentItem2D enrichment in node.EnrichmentItems.Keys)
                {
                    foreach (EnrichedDof dofType in enrichment.Dofs) // Are dofs determined by the element type (e.g. structural) as well?
                    {
                        enrichedDofs[node, dofType] = dofCounter++;
                    }
                }
            }
            return(dofCounter - standardDofsCount, enrichedDofs);
        }
Пример #10
0
        //Node major ordering
        private static (int standardDofsCount, DofTable <StructuralDof> standardDofs) OrderStandardDofs(
            IDictionary <XNode, HashSet <StructuralDof> > nodalDofTypes, ITable <XNode, StructuralDof, double> constraints)
        {
            var standardDofs = new DofTable <StructuralDof>();
            int counter      = 0;

            foreach (var pair in nodalDofTypes)
            {
                XNode node = pair.Key;
                foreach (StructuralDof dofType in pair.Value)
                {
                    if (!constraints.Contains(node, dofType))
                    {
                        standardDofs[node, dofType] = counter++;
                    }
                }
            }
            return(counter, standardDofs);
        }
Пример #11
0
        /// <summary>
        /// TODO: Modify this method to extract any kind of vector, not only displacement, which means different
        /// handling of constrained dofs, if constrained dofs are defined in the first place.
        /// </summary>
        /// <param name="element"></param>
        /// <param name="globalFreeVector"></param>
        /// <param name="globalConstrainedVector"></param>
        /// <returns></returns>
        public Vector ExtractDisplacementVectorOfElementFromGlobal(XContinuumElement2D element,
                                                                   Vector globalFreeVector, Vector globalConstrainedVector)
        {
            DofTable <StructuralDof> elementDofs = element.GetStandardDofs();

            double[] elementVector = new double[elementDofs.EntryCount];
            foreach ((XNode node, StructuralDof dofType, int dofIdx) in elementDofs)
            {
                bool isStandard = this.standardDofs.TryGetValue(node, dofType, out int globalStandardDof);
                if (isStandard)
                {
                    elementVector[dofIdx] = globalFreeVector[globalStandardDof];
                }
                else
                {
                    int globalConstrainedDof = this.constrainedDofs[node, dofType];
                    elementVector[dofIdx] = globalConstrainedVector[globalConstrainedDof];
                }
            }
            return(Vector.CreateFromArray(elementVector));
        }
Пример #12
0
        /// <summary>
        /// </summary>
        /// <param name="element"></param>
        /// <param name="globalFreeVector">Both the free standard and enriched dofs.</param>
        /// <returns></returns>
        public Vector ExtractEnrichedDisplacementsOfElementFromGlobal(XCluster2D cluster, XContinuumElement2D element,
                                                                      Vector globalFreeVector)
        {
            // While Heaviside dofs on boundary nodes that would cause singular stiffness matrices are generally avoided,
            // the returned vector of this method must include them. Since H(x)-H(xNode)=0, it wouldn't be wrong to exclude
            // them in theory. However it would cause indexing problems if they are missing, since other XFEM classes (such as
            // XContinuumElement) have no concept of a node being enriched only for some elements.
            DofTable <EnrichedDof> elementDofs = element.GetEnrichedDofs();

            double[] elementVector = new double[elementDofs.EntryCount];
            foreach (XNode node in element.Nodes)
            {
                bool isSingularityNode = SingularHeavisideEnrichments.TryGetValue(node,
                                                                                  out HashSet <IEnrichmentItem2D> singularEnrichments);
                foreach (IEnrichmentItem2D enrichment in node.EnrichmentItems.Keys)
                {
                    XSubdomainDofOrderer correctOrderer = this;
                    if (isSingularityNode && singularEnrichments.Contains(enrichment))
                    {
                        // Find global dof index from other subdomain, sine it is not stored here
                        correctOrderer = FindSubdomainWhereNodeEnrichmentIsNotSingular(cluster, node, enrichment).DofOrderer;
                    }
                    foreach (var dofType in enrichment.Dofs)
                    {
                        int elementDofIdx = elementDofs[node, dofType];
                        int globalDofIdx  = correctOrderer.FirstGlobalDofIndex +
                                            correctOrderer.subdomainEnrichedDofs[node, dofType];
                        elementVector[elementDofIdx] = globalFreeVector[globalDofIdx];
                    }
                }
            }

            //foreach (Tuple<XNode2D, EnrichedDof, int> entry in elementDofs)
            //{
            //    int globalEnrichedDof = globalEnrichedDofs[entry.Item1, entry.Item2];
            //    elementVector[entry.Item3] = globalFreeVector[globalEnrichedDof];
            //}
            return(Vector.CreateFromArray(elementVector));
        }
Пример #13
0
        /// <summary>
        /// Index i = element local dof. Dictionary[i] = global dof.
        /// </summary>
        /// <param name="element"></param>
        /// <returns></returns>
        public void MatchElementToGlobalStandardDofsOf(XContinuumElement2D element,
                                                       out IReadOnlyDictionary <int, int> elementToGlobalStandardDofs,
                                                       out IReadOnlyDictionary <int, int> elementToGlobalConstrainedDofs)
        {
            DofTable <StructuralDof> elementDofs = element.GetStandardDofs();
            var globalStandardDofs    = new Dictionary <int, int>();
            var globalConstrainedDofs = new Dictionary <int, int>();

            foreach ((XNode node, StructuralDof dofType, int dofIdx) in elementDofs)
            {
                bool isStandard = this.standardDofs.TryGetValue(node, dofType, out int standardGlobalDof);
                if (isStandard)
                {
                    globalStandardDofs[dofIdx] = standardGlobalDof;
                }
                else
                {
                    globalConstrainedDofs[dofIdx] = this.constrainedDofs[node, dofType];
                }
            }
            elementToGlobalStandardDofs    = globalStandardDofs;
            elementToGlobalConstrainedDofs = globalConstrainedDofs;
        }
Пример #14
0
 private SeparateDofOrderer(int constrainedDofsCount, DofTable <StructuralDof> constrainedDofs,
                            int enrichedDofsCount, DofTable <EnrichedDof> enrichedDofs,
                            int standardDofsCount, DofTable <StructuralDof> standardDofs) :
     base(constrainedDofsCount, constrainedDofs, enrichedDofsCount, enrichedDofs, standardDofsCount, standardDofs)
 {
 }