示例#1
0
        /// <summary>
        /// Merges all nodes so that no two nodes are within the given tolerance.
        /// </summary>
        public void MergeNodes(double mergeTolerance)
        {
            Dictionary <Node, List <Node> > toMerge  = new Dictionary <Node, List <Node> >();
            Dictionary <Node, Node>         toRemove = new Dictionary <Node, Node>();

            foreach (Node n1 in Nodes)
            {
                if (toMerge.ContainsKey(n1))
                {
                    continue;
                }
                if (toRemove.ContainsKey(n1))
                {
                    continue;
                }

                foreach (Node n2 in Nodes)
                {
                    if (ReferenceEquals(n1, n2))
                    {
                        continue;
                    }
                    if (toMerge.ContainsKey(n1))
                    {
                        continue;
                    }
                    if (toRemove.ContainsKey(n1))
                    {
                        continue;
                    }

                    if (Node.Distance(n1, n2) < mergeTolerance)
                    {
                        List <Node> removeList;
                        if (toMerge.TryGetValue(n1, out removeList))
                        {
                            removeList.Add(n2);
                        }
                        else
                        {
                            toMerge[n1] = new List <Node>()
                            {
                                n2
                            };
                        }
                        toRemove[n2] = n1;
                    }
                }
            }

            // Arrange frame nodes
            foreach (Frame f in Frames)
            {
                Node n1;
                Node n2;

                if (toRemove.TryGetValue(f.NodeI, out n1))
                {
                    f.NodeI = n1;
                }
                if (toRemove.TryGetValue(f.NodeJ, out n2))
                {
                    f.NodeJ = n2;
                }
            }

            // Assemble node loads
            foreach (KeyValuePair <Node, List <Node> > pair in toMerge)
            {
                Node        master  = pair.Key;
                List <Node> removed = pair.Value;

                foreach (AnalysisCase analysisCase in AnalysisCases)
                {
                    // Assemble point loads
                    NodePointLoad assembledPointLoad = new NodePointLoad(analysisCase, 0, 0, 0);
                    foreach (NodeLoad masterLoad in master.Loads.FindAll((e) => e.AnalysisCase == analysisCase && e is NodePointLoad))
                    {
                        NodePointLoad masterPointLoad = masterLoad as NodePointLoad;
                        assembledPointLoad.FX += masterPointLoad.FX;
                        assembledPointLoad.FZ += masterPointLoad.FZ;
                        assembledPointLoad.MY += masterPointLoad.MY;
                    }

                    foreach (Node slave in removed)
                    {
                        foreach (NodeLoad slaveLoad in slave.Loads.FindAll((e) => e.AnalysisCase == analysisCase && e is NodePointLoad))
                        {
                            NodePointLoad slavePointLoad = slaveLoad as NodePointLoad;
                            assembledPointLoad.FX += slavePointLoad.FX;
                            assembledPointLoad.FZ += slavePointLoad.FZ;
                            assembledPointLoad.MY += slavePointLoad.MY;
                        }
                    }

                    master.Loads.RemoveAll((e) => e.AnalysisCase == analysisCase && e is NodePointLoad);
                    if (!MathNet.Numerics.Precision.AlmostEqual(assembledPointLoad.FX + assembledPointLoad.FZ + assembledPointLoad.MY, 0))
                    {
                        master.AddPointLoad(analysisCase, assembledPointLoad.FX, assembledPointLoad.FZ, assembledPointLoad.MY);
                    }
                }
            }

            // Remove nodes
            foreach (Node n in toRemove.Keys)
            {
                Nodes.Remove(n);
            }
        }
示例#2
0
        /// <summary>
        /// Merges all nodes so that no two nodes are within the given tolerance.
        /// </summary>
        public void MergeNodes(double mergeTolerance)
        {
            Dictionary<Node, List<Node>> toMerge = new Dictionary<Node, List<Node>>();
            Dictionary<Node, Node> toRemove = new Dictionary<Node, Node>();

            foreach (Node n1 in Nodes)
            {
                if (toMerge.ContainsKey(n1)) continue;
                if (toRemove.ContainsKey(n1)) continue;

                foreach (Node n2 in Nodes)
                {
                    if (ReferenceEquals(n1, n2)) continue;
                    if (toMerge.ContainsKey(n1)) continue;
                    if (toRemove.ContainsKey(n1)) continue;

                    if (Node.Distance(n1, n2) < mergeTolerance)
                    {
                        List<Node> removeList;
                        if (toMerge.TryGetValue(n1, out removeList))
                        {
                            removeList.Add(n2);
                        }
                        else
                        {
                            toMerge[n1] = new List<Node>() { n2 };
                        }
                        toRemove[n2] = n1;
                    }
                }
            }

            // Arrange frame nodes
            foreach (Frame f in Frames)
            {
                Node n1;
                Node n2;

                if (toRemove.TryGetValue(f.NodeI, out n1))
                {
                    f.NodeI = n1;
                }
                if (toRemove.TryGetValue(f.NodeJ, out n2))
                {
                    f.NodeJ = n2;
                }
            }

            // Assemble node loads
            foreach (KeyValuePair<Node, List<Node>> pair in toMerge)
            {
                Node master = pair.Key;
                List<Node> removed = pair.Value;

                foreach (AnalysisCase analysisCase in AnalysisCases)
                {
                    // Assemble point loads
                    NodePointLoad assembledPointLoad = new NodePointLoad(analysisCase, 0, 0, 0);
                    foreach (NodeLoad masterLoad in master.Loads.FindAll((e) => e.AnalysisCase == analysisCase && e is NodePointLoad))
                    {
                        NodePointLoad masterPointLoad = masterLoad as NodePointLoad;
                        assembledPointLoad.FX += masterPointLoad.FX;
                        assembledPointLoad.FZ += masterPointLoad.FZ;
                        assembledPointLoad.MY += masterPointLoad.MY;
                    }

                    foreach (Node slave in removed)
                    {
                        foreach (NodeLoad slaveLoad in slave.Loads.FindAll((e) => e.AnalysisCase == analysisCase && e is NodePointLoad))
                        {
                            NodePointLoad slavePointLoad = slaveLoad as NodePointLoad;
                            assembledPointLoad.FX += slavePointLoad.FX;
                            assembledPointLoad.FZ += slavePointLoad.FZ;
                            assembledPointLoad.MY += slavePointLoad.MY;
                        }
                    }

                    master.Loads.RemoveAll((e) => e.AnalysisCase == analysisCase && e is NodePointLoad);
                    if (!MathNet.Numerics.Precision.AlmostEqual(assembledPointLoad.FX + assembledPointLoad.FZ + assembledPointLoad.MY, 0))
                    {
                        master.AddPointLoad(analysisCase, assembledPointLoad.FX, assembledPointLoad.FZ, assembledPointLoad.MY);
                    }
                }
            }

            // Remove nodes
            foreach (Node n in toRemove.Keys)
            {
                Nodes.Remove(n);
            }
        }
示例#3
0
        /// <summary>
        /// Returns the load vector for the given load case.
        /// </summary>
        private Vector <double> GetLoadVector(AnalysisCase analysisCase)
        {
            Vector <double> p = Vector <double> .Build.Dense(nodes.Count * 3, 0);

            // Node loads
            foreach (Node node in nodes)
            {
                foreach (NodeLoad load in node.Loads.FindAll((e) => e.AnalysisCase == analysisCase))
                {
                    if (load is NodePointLoad)
                    {
                        // Applied point loads
                        NodePointLoad pl = (NodePointLoad)load;
                        int           i  = node.Index;
                        p[i * 3 + 0] += pl.FX;
                        p[i * 3 + 1] += pl.FZ;
                        p[i * 3 + 2] += pl.MY;
                    }
                }
            }

            // Frame loads
            foreach (Frame frame in Frames)
            {
                double l = frame.Length;
                int    i = frame.NodeI.Index;
                int    j = frame.NodeJ.Index;

                foreach (FrameLoad load in frame.Loads.FindAll((e) => e.AnalysisCase == analysisCase))
                {
                    if (load is FrameUniformLoad)
                    {
                        // Frame fixed-end reactions from frame uniform loads
                        FrameUniformLoad pl = (FrameUniformLoad)load;
                        double           fx = pl.FX * l / 2.0;
                        double           fz = pl.FZ * l / 2.0;

                        p[i * 3 + 0] += fx;
                        p[i * 3 + 1] += fz;
                        p[i * 3 + 2] += 0; // End moment

                        p[j * 3 + 0] += fx;
                        p[j * 3 + 1] += fz;
                        p[j * 3 + 2] += 0; // End moment
                    }
                    else if (load is FrameTrapezoidalLoad)
                    {
                        // Frame fixed-end reactions from frame trapezoidal loads
                        FrameTrapezoidalLoad pl = (FrameTrapezoidalLoad)load;

                        double fx = (pl.FXI + pl.FXJ) / 2.0 * l / 2.0;
                        double fz = (pl.FZI + pl.FZJ) / 2.0 * l / 2.0;

                        p[i * 3 + 0] += fx;
                        p[i * 3 + 1] += fz;
                        p[i * 3 + 2] += 0; // End moment

                        p[j * 3 + 0] += fx;
                        p[j * 3 + 1] += fz;
                        p[j * 3 + 2] += 0; // End moment
                    }
                }
            }

            // Set restrained node coefficients to 0
            foreach (Node n in nodes)
            {
                if ((n.Restraints & DOF.UX) != DOF.Free)
                {
                    p[n.Index * 3 + 0] = 0;
                }
                if ((n.Restraints & DOF.UZ) != DOF.Free)
                {
                    p[n.Index * 3 + 1] = 0;
                }
                if ((n.Restraints & DOF.RY) != DOF.Free)
                {
                    p[n.Index * 3 + 2] = 0;
                }
            }

            return(p);
        }