/// <summary> /// Divides the given frame into given number of pieces. /// </summary> public void DivideFrame(Frame f, int n) { Node n1 = f.NodeI; Node n2 = f.NodeJ; double xStep = (n2.X - n1.X) / (double)n; double zStep = (n2.Z - n1.Z) / (double)n; Node[] nodes = new Node[n + 1]; nodes[0] = n1; nodes[nodes.Length - 1] = n2; double x = n1.X + xStep; double z = n1.Z + zStep; for (int i = 0; i < n - 1; i++) { nodes[i + 1] = AddNode(x, z); x += xStep; z += zStep; } Frames.Remove(f); for (int i = 0; i < n; i++) { Frame newFrame = AddFrame(f.Section, nodes[i], nodes[i + 1]); // Transfer loads // Uniform loads foreach (FrameLoad masterLoad in f.Loads.FindAll((e) => e is FrameUniformLoad)) { FrameUniformLoad masterUniformLoad = masterLoad as FrameUniformLoad; newFrame.AddUniformLoad(masterUniformLoad.AnalysisCase, masterUniformLoad.FX, masterUniformLoad.FZ); } // Trapezoidal loads foreach (FrameLoad masterLoad in f.Loads.FindAll((e) => e is FrameTrapezoidalLoad)) { FrameTrapezoidalLoad masterTrapezoidalLoad = masterLoad as FrameTrapezoidalLoad; double mxi = masterTrapezoidalLoad.FXI; double mzi = masterTrapezoidalLoad.FZI; double mxj = masterTrapezoidalLoad.FXJ; double mzj = masterTrapezoidalLoad.FZJ; double xTotal = f.Length; double xStart = newFrame.NodeI.DistanceTo(f.NodeI); double xEnd = newFrame.NodeJ.DistanceTo(f.NodeI); double fxi = xStart / xTotal * (mxj - mxi) + mxi; double fzi = xStart / xTotal * (mzj - mzi) + mzi; double fxj = xEnd / xTotal * (mxj - mxi) + mxi; double fzj = xEnd / xTotal * (mzj - mzi) + mzi; newFrame.AddTrapezoidalLoad(masterTrapezoidalLoad.AnalysisCase, fxi, fzi, fxj, fzj); } } }
/// <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); }