public static Dictionary<string, object> SAPModel(string FilePath, bool read) { if (read) { StructuralModel Model = new StructuralModel(); Model.StructuralElements = new List<Element>(); cSapModel mySapModel = null; string units = string.Empty; // Open & instantiate SAP file Initialize.OpenSAPModel(FilePath, ref mySapModel, ref units); // Populate the model's elemets StructuralModelFromSapFile(ref mySapModel, ref Model, units); // Return outputs return new Dictionary<string, object> { {"StructuralModel", Model}, {"units", units} }; } else { throw new Exception("Set boolean True to read!"); } }
/// <summary> /// Decompose forces and moments in the model for a specific case /// </summary> /// <param name="StructuralModel">Structural model to get results from</param> /// <param name="AnalysisResults">Use Analysis.Run and Analysis.GetResults to select a specific case to decompose</param> /// <param name="ForceType">Use Force Type dropdown</param> /// <returns>Numerical values of forces and moments for each station in each structural member in the model </returns> public static List <List <double> > DecomposeResults(StructuralModel StructuralModel, Analysis AnalysisResults, string ForceType) { List <List <double> > Forces = new List <List <double> >(); for (int i = 0; i < StructuralModel.StructuralElements.Count; i++) { List <double> ff = new List <double>(); FrameResults frmresult = null; // linq inqury try { frmresult = (from frm in AnalysisResults.FrameResults where frm.ID == StructuralModel.StructuralElements[i].Label select frm).First(); } catch { } //if it is a joint, the element will not have frame results //Add 0.0 to maintain the order of the structural elements in the Structural Model if (frmresult == null || frmresult.Results.Count == 0) { ff.Add(0.0); Forces.Add(ff); continue; } foreach (FrameAnalysisData fad in frmresult.Results[AnalysisResults.LCaseOrLPatternRun].Values) { if (ForceType == "Axial") //Get Axial Forces P { ff.Add(fad.P); } else if (ForceType == "Shear22") // Get Shear V2 { ff.Add(fad.V2); } else if (ForceType == "Shear33") // Get Shear V3 { ff.Add(fad.V3); } else if (ForceType == "Torsion") // Get Torsion T { ff.Add(fad.T); } else if (ForceType == "Moment22") // Get Moment M2 { ff.Add(fad.M2); } else if (ForceType == "Moment33") // Get Moment M3 { ff.Add(fad.M3); } } Forces.Add(ff); } return(Forces); }
//------------------------------------------- // Constructor //-------------------------------------------- public ViewModel() { //var fm = new FEModel.FEModel(); p2pConverter = new Pix2Pix(); myFEView = new FEView(); myStructure = new StructuralModel(); }
public static Dictionary<string, object> ToSAP(StructuralModel StructuralModel, bool Bake, string Units = "kip_ft_F", bool Delete = true) { if (Bake) { // 1. Calculate Lenght Conversion Factor string fromUnit = "m"; // Dynamo API Units LengthUnit LU = new LengthUnit(); //LengthUnit LU= DynamoUnits.Length.LengthUnit; // Display Units //double LengthSF = SAPConnection.Utilities.UnitConversion(Units, fromUnit); // Lenght Conversion Factor double LengthSF = 1; // Clear Frame & Area Dictionaries to hold SAPFrmList.Clear(); SAPAreaList.Clear(); SAPJointList.Clear(); report.Clear(); // 2. Create new SAP Model and bake Stuctural Model if (StructuralModel != null) { CreateorUpdateSAPModel(ref StructuralModel, Units, LengthSF, Delete); } } else { throw new Exception("Node not run. Please, set boolean to true"); } //return StructuralModel; return new Dictionary<string, object> { {"Structural Model", StructuralModel}, {"Report", report} }; }
public static Dictionary<string, object> SAPModel(bool read) { if (read) { StructuralModel Model = new StructuralModel(); cSapModel mySapModel = null; string modelunits = string.Empty; // Open & instantiate SAP file Initialize.GrabOpenSAP(ref mySapModel, ref modelunits, ""); StructuralModelFromSapFile(ref mySapModel, ref Model, modelunits); // Return outputs return new Dictionary<string, object> { {"StructuralModel", Model}, {"units", modelunits} }; } else { throw new Exception("Set boolean True to read!"); } }
public void GetStructureFromP2P() { myStructure = new StructuralModel(); myStructure.PicColumns = p2pConverter.Columns; myStructure.PicWalls = p2pConverter.Walls; myStructure.PicOpenings = p2pConverter.Openings; myStructure.PicSlabs = p2pConverter.Slabs; //myStructure.pictureScale = p2pConverter.Scaling; StructurePreprocess(); }
public static DxfDocument generateDXF(StructuralModel structure) { var dxf = new netDxf.DxfDocument(); var ColumnLayer = new netDxf.Tables.Layer("Column") { Color = netDxf.AciColor.Red, Lineweight = netDxf.Lineweight.W50 }; var SlabLayer = new netDxf.Tables.Layer("Slab") { Color = netDxf.AciColor.Yellow, Lineweight = netDxf.Lineweight.W50 }; var OpeningLayer = new netDxf.Tables.Layer("Opening") { Color = netDxf.AciColor.Blue, Lineweight = netDxf.Lineweight.W50 }; var WallLayer = new netDxf.Tables.Layer("Wall") { Color = netDxf.AciColor.Green, Lineweight = netDxf.Lineweight.W50 }; dxf.Layers.Add(ColumnLayer); dxf.Layers.Add(SlabLayer); dxf.Layers.Add(OpeningLayer); dxf.Layers.Add(WallLayer); foreach (var item in structure.Columns) { dxf.AddEntity(getPolylineFromPoints(item.Points, ColumnLayer)); } foreach (var item in structure.Slabs) { dxf.AddEntity(getPolylineFromPoints(item.Points, SlabLayer)); } foreach (var item in structure.Walls) { dxf.AddEntity(getPolylineFromPoints(item.Points, WallLayer, false)); } foreach (var item in structure.Openings) { dxf.AddEntity(getPolylineFromPoints(item.Points, OpeningLayer)); } return(dxf); }
public static void CreateDXF(ref StructuralModel structure) { var saveDialog = new SaveFileDialog(); saveDialog.Filter = @"DXF files |*.DXF"; saveDialog.InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments); if (saveDialog.ShowDialog() != DialogResult.OK) { return; } string filePathDxf = saveDialog.FileName; var dxfDrawing = generateDXF(structure); dxfDrawing.Save(filePathDxf); }
public static Dictionary <string, object> Run(bool Run) { List <string> LoadCaseNames = new List <string>(); List <string> LoadPatternNames = new List <string>(); List <string> LoadComboNames = new List <string>(); StructuralModel Model = new StructuralModel(); string SaveAs = ""; if (Run) { string modelunits = string.Empty; SAPConnection.Initialize.GrabOpenSAP(ref mySapModel, ref modelunits, ""); Read.StructuralModelFromSapFile(ref mySapModel, ref Model, modelunits); SaveAs = SAPConnection.Initialize.GetModelFilename(ref mySapModel); if (SaveAs == "") { throw new Exception("File has not been saved before. Please, go to SAP and save the file"); } if (mySapModel == null) { throw new Exception("SAP Model was not grabbed. Use run analysis with filepath"); } else { // run analysis SAPConnection.AnalysisMapper.RunAnalysis(ref mySapModel, SaveAs, ref LoadCaseNames, ref LoadPatternNames, ref LoadComboNames); } } return(new Dictionary <string, object> { { "Structural Model", Model }, { "Load Cases", LoadCaseNames }, { "Load Patterns", LoadPatternNames }, { "Load Combos", LoadComboNames }, { "Filepath", SaveAs } }); }
public static Dictionary <string, object> Run(string FilePath, bool Run) { List <string> LoadCaseNames = new List <string>(); List <string> LoadPatternNames = new List <string>(); List <string> LoadComboNames = new List <string>(); StructuralModel Model = new StructuralModel(); if (Run) { string units = string.Empty; SAPConnection.Initialize.OpenSAPModel(FilePath, ref mySapModel, ref units); Read.StructuralModelFromSapFile(ref mySapModel, ref Model, units); // run analysis SAPConnection.AnalysisMapper.RunAnalysis(ref mySapModel, FilePath, ref LoadCaseNames, ref LoadPatternNames, ref LoadComboNames); } return(new Dictionary <string, object> { { "Structural Model", Model }, { "Load Cases", LoadCaseNames }, { "Load Patterns", LoadPatternNames }, { "Load Combos", LoadComboNames } }); }
/// <summary> /// Visualize forces and moments in the model for a specific case /// </summary> /// <param name="StructuralModel">Structural model to visualize results on</param> /// <param name="AnalysisResults">Use Analysis.Run and Analysis.GetResults to select a specific case to decompose</param> /// <param name="ForceType">Use Force Type dropdown</param> /// <param name="Scale">Scale of the visualization</param> /// <param name="Visualize">Set Boolean to True to draw the meshes</param> /// <returns>Forces and moments in the form of meshes for each station in each structural member in the model</returns> /// public static List <List <Mesh> > VisualizeResults(StructuralModel StructuralModel, Analysis AnalysisResults, string ForceType, bool Visualize, double Scale = 1.0) { List <List <double> > myForces = DecomposeResults(StructuralModel, AnalysisResults, ForceType); double max = 0.0; for (int i = 0; i < myForces.Count; i++) { for (int j = 0; j < myForces[i].Count; j++) { if (myForces[i][j] >= max) { max = myForces[i][j]; } } } // Define a coefficient to visualize the forces Frame fs = (Frame)StructuralModel.StructuralElements[0]; double lenght = 0.5 * fs.BaseCrv.Length; double coefficient = 0.0; if (max != 0) { coefficient = lenght / max; } List <List <Mesh> > VizMeshes = new List <List <Mesh> >(); List <Line> frameNormals = new List <Line>(); if (Visualize) { int j = 0; for (int i = 0; i < StructuralModel.StructuralElements.Count; i++) //for (int i = 0; i < AnalysisResults.FrameResults.Count; i++) { //List of meshes per structural element in the model List <Mesh> frameResultsMesh = new List <Mesh>(); // Linq inqury FrameResults frmresult = null; try { frmresult = (from frm in AnalysisResults.FrameResults where frm.ID == StructuralModel.StructuralElements[i].Label select frm).First(); } catch { } if (frmresult == null || StructuralModel.StructuralElements[i].Type != Structure.Type.Frame) { //Add an empty list to match the tree that contains Joints VizMeshes.Add(frameResultsMesh); continue; } // Get the frame's curve specified by the frameID // Frame f = (Frame)StructuralModel.StructuralElements[i]; Frame f = (Frame)(from frame in StructuralModel.StructuralElements where frame.Label == frmresult.ID select frame).First(); Curve c = f.BaseCrv; //LOCAL COORDINATE SYSTEM Vector xAxis = c.TangentAtParameter(0.0); Vector yAxis = c.NormalAtParameter(0.0); //This ensures the right axis for the Z direction CoordinateSystem localCS = CoordinateSystem.ByOriginVectors(c.StartPoint, xAxis, yAxis); //LINES TO VISUALIZE THE NORMALS OF THE FRAME CURVES //Point middlePt = c.PointAtParameter(0.5); //Line ln = Line.ByStartPointDirectionLength(middlePt, localCS.ZAxis, 30.0); //frameNormals.Add(ln); //List to hold the points to make a mesh face List <Point> MeshPoints = new List <Point>(); // t value of the previous station double t1 = 0.0; // t value of the current station double t2 = 0.0; // Local Z value of the previous station double v1 = 0.0; // Local Z value of the current station double v2 = 0; // Integer to count the number of times there are stations with value=0 (no force) int zeroCount = 0; // Loop through each station (t value) in the analysis results dictionary foreach (double t in frmresult.Results[AnalysisResults.LCaseOrLPatternRun].Keys) { double newt = t; if (t < 0) { newt = -t; } Mesh m = null; Point tPoint = c.PointAtParameter(newt); // Point on the curve at the specified t2 Point vPoint = null; // Point that is translated from the cPoint according to the value v2 // Double to hold the local Z value of the station multiplied by the scale factor double translateCoord = 0.0; if (ForceType == "Axial") // Get Axial P { v2 = AnalysisResults.FrameResults[j].Results[AnalysisResults.LCaseOrLPatternRun][newt].P; translateCoord = v2 * coefficient * (-Scale); } else if (ForceType == "Shear22") // Get Shear V2 { v2 = AnalysisResults.FrameResults[j].Results[AnalysisResults.LCaseOrLPatternRun][newt].V2; translateCoord = v2 * coefficient * (-Scale); } else if (ForceType == "Shear33") // Get Shear V3 { v2 = AnalysisResults.FrameResults[j].Results[AnalysisResults.LCaseOrLPatternRun][newt].V3; translateCoord = v2 * coefficient * coefficient * Scale; } else if (ForceType == "Torsion") // Get Torsion T { v2 = AnalysisResults.FrameResults[j].Results[AnalysisResults.LCaseOrLPatternRun][newt].T; translateCoord = v2 * coefficient * (-Scale); } else if (ForceType == "Moment22") // Get Moment M2 { v2 = AnalysisResults.FrameResults[j].Results[AnalysisResults.LCaseOrLPatternRun][newt].M2; translateCoord = v2 * coefficient * (-Scale); } else if (ForceType == "Moment33") // Get Moment M3 { v2 = AnalysisResults.FrameResults[j].Results[AnalysisResults.LCaseOrLPatternRun][newt].M3; translateCoord = v2 * coefficient * Scale; } v2 = Math.Round(v2, 4, MidpointRounding.AwayFromZero); // if there is no value for the force (it is zero), add one to the count if (translateCoord == 0.0) { zeroCount++; } if (ForceType == "Moment22" || ForceType == "Shear33") { vPoint = (Point)tPoint.Translate(localCS.YAxis, translateCoord); // Translate in the Y direction to match the visualization of SAP } else { vPoint = (Point)tPoint.Translate(localCS.ZAxis, translateCoord); // All the other types must be translate in the Z direction} } //Point that results from the intersection of the line between two value Points and the frame curve Point pzero = null; IndexGroup ig3 = IndexGroup.ByIndices(0, 1, 2); IndexGroup ig4 = IndexGroup.ByIndices(0, 1, 2, 3); //if no points have been added yet, add the point on the curve and then the point representing the value if (MeshPoints.Count == 0) { MeshPoints.Add(tPoint); //index 0 // if the first value is not 0 if (v2 != 0.0) { MeshPoints.Add(vPoint); //index 1 } } // if a previous point(s) has been added else { // List to hold the indices for the mesh face List <IndexGroup> indices = new List <IndexGroup>(); //Parameter at which the value of the forces = 0. It is the X coordinate of the pzero double tzero; // Current t parameter of the point being visualized relative to the length of the frame curve t2 = newt * c.Length; // If there is a change in the force sign, calculate the intersection point // Then, add two trianglular mesh faces if ((v1 > 0 && v2 < 0) || (v1 < 0 && v2 > 0)) { // The function of the line is: y= (t2-t1)tzero/(d2-d1)+d1 This has to be equal to 0 double ml = (v2 - v1) / (t2 - t1); tzero = (0 - v1) / ml; // Add the X coordinate of the last mesh point tzero += t1; pzero = Point.ByCartesianCoordinates(localCS, tzero, 0.0, 0.0); //Add the third point for the first triangular mesh face MeshPoints.Add(pzero); //index 2 indices.Add(ig3); // ||| Color coding here m = Mesh.ByPointsFaceIndices(MeshPoints, indices); frameResultsMesh.Add(m); MeshPoints.Clear(); //Add the third point for the second triangular mesh face MeshPoints.Add(pzero); //new face index 0 // Add the current station's points MeshPoints.Add(tPoint); //new face index 1 MeshPoints.Add(vPoint); //new face index 2 // ||| Color coding here m = Mesh.ByPointsFaceIndices(MeshPoints, indices); frameResultsMesh.Add(m); } // Create a quad mesh face or a triangular mesh if the first value was 0 else { MeshPoints.Add(vPoint); //index 2 (note: vPoint before cPoint) MeshPoints.Add(tPoint); //index 3 if (MeshPoints.Count == 4) { indices.Add(ig4); } else { indices.Add(ig3); } // ||| Color coding here m = Mesh.ByPointsFaceIndices(MeshPoints, indices); frameResultsMesh.Add(m); } //Clear the temporary list MeshPoints.Clear(); // Add the current station's points MeshPoints.Add(tPoint); //new face index 0 MeshPoints.Add(vPoint); //new face index 1 } // Update the values for the next station t1 = newt * c.Length; v1 = v2; } // If all the values were zero, show empty list in output for that specific member if (zeroCount == AnalysisResults.FrameResults[j].Results[AnalysisResults.LCaseOrLPatternRun].Keys.Count) { frameResultsMesh.Clear(); } VizMeshes.Add(frameResultsMesh); j++; } } return(VizMeshes); }
public static List <List <Object> > DisplayLoads(StructuralModel StructuralModel, string LPattern = "Show All", double Size = 1.0, bool ShowValues = true, double TextSize = 1.0) { //List to hold all the load visualization objects List <List <Object> > LoadViz = new List <List <Object> >(); // Length of the arrow Double length = 1.0; foreach (Element e in StructuralModel.StructuralElements) { if (e.GetType().ToString().Contains("Frame")) { //get the length of the first frame found in the collection and use to set up a scale for the load display length = ((Frame)e).BaseCrv.Length; break; } } double max = -10000000.0; double min = 10000000.0; // Loop through all the elements in the structural model // get the max and minimum values of distributed loads on the frame foreach (Element e in StructuralModel.StructuralElements) { // If the object is a frame if (e.GetType().ToString().Contains("Frame")) { Frame f = e as Frame; if (f.Loads != null && f.Loads.Count > 0) { foreach (Load load in f.Loads) { if (load.LoadType == "DistributedLoad") { if (load.Val > max) { max = load.Val; } if (load.Val < min) { min = load.Val; } if (load.Val2 > max) { max = load.Val2; } if (load.Val2 < min) { min = load.Val2; } } } } } } double refval = Math.Abs(max); if (Math.Abs(max) < Math.Abs(min)) { refval = Math.Abs(min); } // Loop through all the elements in the structural model foreach (Element e in StructuralModel.StructuralElements) { //List to hold the load visualization objects per structural member List <Object> LoadObjects = new List <Object>(); // 1. If the object is a frame if (e.GetType().ToString().Contains("Frame")) { Frame f = e as Frame; if (f.Loads != null && f.Loads.Count > 0) { //Loop through all the loads on the frame foreach (Load load in f.Loads) { // If the Load type is a moment, throw warning if (load.FMType == 2) { throw new Exception("Moment visualization is not supported"); } Point labelLocation = null; if (LPattern == "Show All") { //show all } else { if (load.lPattern.name != LPattern) { continue; // show only the loads whose load pattern is the specified in the node } } Curve c = f.BaseCrv; double sz = Size; // List to hold parameter values where arrows will be drawn List <double> dd = new List <double>(); bool isDistributed = false; if (load.LoadType == "DistributedLoad") { isDistributed = true; //number of arrows to represent a Distributed Load int n = Convert.ToInt32((load.Dist - load.Dist2) / 0.1); double step = (load.Dist - load.Dist2) / n; for (double i = load.Dist; i < load.Dist2; i += step) { dd.Add(i); } dd.Add(load.Dist2); } else // if its a point load { dd.Add(load.Dist); } //First top point for distributed load visualization Point A = null; //Last top point for distributed load visualization Point B = null; //Vector used to translate the arrow location point Vector v = null; Vector xAxis = c.TangentAtParameter(0.0); Vector yAxis = c.NormalAtParameter(0.0); Vector triangleNormal = null; //List to hold the index group of the mesh List <IndexGroup> igs = new List <IndexGroup>(); igs.Add(IndexGroup.ByIndices(0, 1, 2)); double arrowLenght = length / 6; double triangleBase = arrowLenght / 5; //Loop through all the parameter values along the curve. // If it is a point load it will only have one value for (int i = 0; i < dd.Count; i++) { //List to hold the points to create a triangular mesh per arrow List <Point> pps = new List <Point>(); //Create the point where the arrow should be located Point p1 = c.PointAtParameter(dd[i]); Point p2 = null; Point p3 = null; Point p4 = null; arrowLenght = -length / 6; double b = load.Val; if (load.Dist != 0) { b = load.Val - (load.Val2 - load.Val) / (load.Dist2 - load.Dist) * dd[0]; } double valueAtd = ((load.Val2 - load.Val) / (load.Dist2 - load.Dist)) * dd[i] + b; if (isDistributed) { arrowLenght *= valueAtd / refval; } //Calculate the vector needed to create the line of the arrow // if it's the local X Direction if (load.Dir == 1) { v = xAxis; } // if it's the local Y Direction else if (load.Dir == 2) { v = yAxis; } // if it's the local Z Direction else if (load.Dir == 3) { v = xAxis.Cross(yAxis); } // if it's the global X Direction else if (load.Dir == 4) { v = Vector.ByCoordinates(arrowLenght * sz, 0.0, 0.0); } // if it's the global Y Direction else if (load.Dir == 5) { v = Vector.ByCoordinates(0.0, arrowLenght * sz, 0.0); } // if it's the global Z Direction else if (load.Dir == 6) { v = Vector.ByCoordinates(0.0, 0.0, arrowLenght * sz); } // if the direction is 7, 8, 9, 10 or 11 else { throw new Exception("The direction of some of the loads is not supported"); } if (Math.Round(v.Length, 3) != 0.0) { // Create the line of the arrow p2 = (Point)p1.Translate(v); Line ln = Line.ByStartPointEndPoint(p1, p2); // Create a temporary point to hold the position of the base of the triangle of the arrow arrowLenght = length / 6; Point ptOnArrow = ln.PointAtDistance(arrowLenght / 5); triangleNormal = ln.Normal; // Translate the point on the arrow to the sides to create the base of the triangle p3 = (Point)ptOnArrow.Translate(triangleNormal, triangleBase); p4 = (Point)ptOnArrow.Translate(triangleNormal, -triangleBase); // Add the points to the list pps.Add(p1); pps.Add(p3); pps.Add(p4); //Create the triangular mesh of the arrow Mesh m = Mesh.ByPointsFaceIndices(pps, igs); //Add the arrow objects to the list LoadObjects.Add(ln); LoadObjects.Add(m); } // Calculate the location of the labels if (isDistributed) { //if it is the start value if (i == 0) { if (p2 == null) { A = p1; } else { A = p2; } if (load.Val != load.Val2) { if (Math.Round(v.Length, 3) != 0.0) { if (ShowValues) { labelLocation = (Point)A.Translate(v.Normalized().Scale(arrowLenght / 4)); labelLocation.Translate(triangleNormal, 2 * triangleBase); string value = Math.Round(load.Val, 2).ToString(); // value of the load rounded to two decimals createLabel(LoadObjects, labelLocation, value, TextSize); } } } } //if it is the end value else if (i == dd.Count - 1) { if (p2 == null) { B = p1; } else { B = p2; } //If it is a distributed load, create a top line Line topLine = Line.ByStartPointEndPoint(A, B); LoadObjects.Add(topLine); if (load.Val != load.Val2) { if (Math.Round(v.Length, 3) != 0.0) { if (ShowValues) { labelLocation = (Point)B.Translate(v.Normalized().Scale(arrowLenght / 4)); labelLocation.Translate(triangleNormal, -2 * triangleBase); string value = Math.Round(load.Val2, 2).ToString(); // value of the load rounded to two decimals createLabel(LoadObjects, labelLocation, value, TextSize); } } } } else if (i == Convert.ToInt32(dd.Count / 2) && load.Val == load.Val2) // if it is the middle point of a uniform distributed load { labelLocation = (Point)p2.Translate(v.Normalized().Scale(arrowLenght / 4)); if (ShowValues) { string value = Math.Round(load.Val, 2).ToString(); // value of the load rounded to two decimals createLabel(LoadObjects, labelLocation, value, TextSize); } } } //if it is a pointLoad else { // If the user wants to see the values of the forces if (ShowValues) { labelLocation = (Point)p2.Translate(v.Normalized().Scale(arrowLenght / 4)); string value = Math.Round(load.Val, 2).ToString(); // value of the load rounded to two decimals createLabel(LoadObjects, labelLocation, value, TextSize); } } } } } } //TO DO: // 2. Add condition for cable // 3. Add contiditon for shell LoadViz.Add(LoadObjects); } // Return Load Visualization return(LoadViz); }
/// <summary> /// Display the Loads /// </summary> /// <param name="StructuralModel">Structural Model</param> /// <param name="LPattern">Load Pattern to display</param> /// <param name="Size">Size of the arrows</param> /// <param name="ShowValues">Set Boolean to True to show the tags of the numeric values</param> /// <param name="TextSize">Size of the tags</param> /// <returns>Arrows and tags representing the loads</returns> public static List<List<Object>> DisplayLoads(StructuralModel StructuralModel, string LPattern = "Show All", double Size = 1.0, bool ShowValues = true, double TextSize = 1.0) { //List to hold all the load visualization objects List<List<Object>> LoadViz = new List<List<Object>>(); // Length of the arrow Double length = 1.0; foreach (Element e in StructuralModel.StructuralElements) { if (e.GetType().ToString().Contains("Frame")) { //get the length of the first frame found in the collection and use to set up a scale for the load display length = ((Frame)e).BaseCrv.Length; break; } } double max = -10000000.0; double min = 10000000.0; // Loop through all the elements in the structural model // get the max and minimum values of distributed loads on the frame foreach (Element e in StructuralModel.StructuralElements) { // If the object is a frame if (e.GetType().ToString().Contains("Frame")) { Frame f = e as Frame; if (f.Loads != null && f.Loads.Count > 0) { foreach (Load load in f.Loads) { if (load.LoadType == "DistributedLoad") { if (load.Val > max) max = load.Val; if (load.Val < min) min = load.Val; if (load.Val2 > max) max = load.Val2; if (load.Val2 < min) min = load.Val2; } } } } } double refval = Math.Abs(max); if (Math.Abs(max) < Math.Abs(min)) refval = Math.Abs(min); // Loop through all the elements in the structural model foreach (Element e in StructuralModel.StructuralElements) { //List to hold the load visualization objects per structural member List<Object> LoadObjects = new List<Object>(); // 1. If the object is a frame if (e.GetType().ToString().Contains("Frame")) { Frame f = e as Frame; if (f.Loads != null && f.Loads.Count > 0) { //Loop through all the loads on the frame foreach (Load load in f.Loads) { // If the Load type is a moment, throw warning if (load.FMType == 2) throw new Exception("Moment visualization is not supported"); Point labelLocation = null; if (LPattern == "Show All") { //show all } else { if (load.lPattern.name != LPattern) { continue; // show only the loads whose load pattern is the specified in the node } } Curve c = f.BaseCrv; double sz = Size; // List to hold parameter values where arrows will be drawn List<double> dd = new List<double>(); bool isDistributed = false; if (load.LoadType == "DistributedLoad") { isDistributed = true; //number of arrows to represent a Distributed Load int n = Convert.ToInt32((load.Dist - load.Dist2) / 0.1); double step = (load.Dist - load.Dist2) / n; for (double i = load.Dist; i < load.Dist2; i += step) { dd.Add(i); } dd.Add(load.Dist2); } else // if its a point load { dd.Add(load.Dist); } //First top point for distributed load visualization Point A = null; //Last top point for distributed load visualization Point B = null; //Vector used to translate the arrow location point Vector v = null; Vector xAxis = c.TangentAtParameter(0.0); Vector yAxis = c.NormalAtParameter(0.0); Vector triangleNormal = null; //List to hold the index group of the mesh List<IndexGroup> igs = new List<IndexGroup>(); igs.Add(IndexGroup.ByIndices(0, 1, 2)); double arrowLenght = length / 6; double triangleBase = arrowLenght / 5; //Loop through all the parameter values along the curve. // If it is a point load it will only have one value for (int i = 0; i < dd.Count; i++) { //List to hold the points to create a triangular mesh per arrow List<Point> pps = new List<Point>(); //Create the point where the arrow should be located Point p1 = c.PointAtParameter(dd[i]); Point p2 = null; Point p3 = null; Point p4 = null; arrowLenght = -length / 6; double b = load.Val; if (load.Dist != 0) b = load.Val - (load.Val2 - load.Val) / (load.Dist2 - load.Dist) * dd[0]; double valueAtd = ((load.Val2 - load.Val) / (load.Dist2 - load.Dist)) * dd[i] + b; if (isDistributed) { arrowLenght *= valueAtd / refval; } //Calculate the vector needed to create the line of the arrow // if it's the local X Direction if (load.Dir == 1) { v = xAxis; } // if it's the local Y Direction else if (load.Dir == 2) { v = yAxis; } // if it's the local Z Direction else if (load.Dir == 3) { v = xAxis.Cross(yAxis); } // if it's the global X Direction else if (load.Dir == 4) { v = Vector.ByCoordinates(arrowLenght * sz, 0.0, 0.0); } // if it's the global Y Direction else if (load.Dir == 5) { v = Vector.ByCoordinates(0.0, arrowLenght * sz, 0.0); } // if it's the global Z Direction else if (load.Dir == 6) { v = Vector.ByCoordinates(0.0, 0.0, arrowLenght * sz); } // if the direction is 7, 8, 9, 10 or 11 else { throw new Exception("The direction of some of the loads is not supported"); } if (Math.Round(v.Length, 3) != 0.0) { // Create the line of the arrow p2 = (Point)p1.Translate(v); Line ln = Line.ByStartPointEndPoint(p1, p2); // Create a temporary point to hold the position of the base of the triangle of the arrow arrowLenght = length / 6; Point ptOnArrow = ln.PointAtDistance(arrowLenght / 5); triangleNormal = ln.Normal; // Translate the point on the arrow to the sides to create the base of the triangle p3 = (Point)ptOnArrow.Translate(triangleNormal, triangleBase); p4 = (Point)ptOnArrow.Translate(triangleNormal, -triangleBase); // Add the points to the list pps.Add(p1); pps.Add(p3); pps.Add(p4); //Create the triangular mesh of the arrow Mesh m = Mesh.ByPointsFaceIndices(pps, igs); //Add the arrow objects to the list LoadObjects.Add(ln); LoadObjects.Add(m); } // Calculate the location of the labels if (isDistributed) { //if it is the start value if (i == 0) { if (p2 == null) A = p1; else A = p2; if (load.Val != load.Val2) { if (Math.Round(v.Length, 3) != 0.0) { if (ShowValues) { labelLocation = (Point)A.Translate(v.Normalized().Scale(arrowLenght / 4)); labelLocation.Translate(triangleNormal, 2 * triangleBase); string value = Math.Round(load.Val, 2).ToString(); // value of the load rounded to two decimals createLabel(LoadObjects, labelLocation, value, TextSize); } } } } //if it is the end value else if (i == dd.Count - 1) { if (p2 == null) B = p1; else B = p2; //If it is a distributed load, create a top line Line topLine = Line.ByStartPointEndPoint(A, B); LoadObjects.Add(topLine); if (load.Val != load.Val2) { if (Math.Round(v.Length, 3) != 0.0) { if (ShowValues) { labelLocation = (Point)B.Translate(v.Normalized().Scale(arrowLenght / 4)); labelLocation.Translate(triangleNormal, -2 * triangleBase); string value = Math.Round(load.Val2, 2).ToString(); // value of the load rounded to two decimals createLabel(LoadObjects, labelLocation, value, TextSize); } } } } else if (i == Convert.ToInt32(dd.Count / 2) && load.Val==load.Val2) // if it is the middle point of a uniform distributed load { labelLocation = (Point)p2.Translate(v.Normalized().Scale(arrowLenght / 4)); if (ShowValues) { string value = Math.Round(load.Val, 2).ToString(); // value of the load rounded to two decimals createLabel(LoadObjects, labelLocation, value, TextSize); } } } //if it is a pointLoad else { // If the user wants to see the values of the forces if (ShowValues) { labelLocation = (Point)p2.Translate(v.Normalized().Scale(arrowLenght / 4)); string value = Math.Round(load.Val, 2).ToString(); // value of the load rounded to two decimals createLabel(LoadObjects, labelLocation, value, TextSize); } } } } } } //TO DO: // 2. Add condition for cable // 3. Add contiditon for shell LoadViz.Add(LoadObjects); } // Return Load Visualization return LoadViz; }
// Create or Update Sap Model from a Dynamo Model private static void CreateorUpdateSAPModel(ref StructuralModel StructuralModel, string Units, double SF, bool delete) { string error = string.Empty; //1. INSTANTIATE NEW OR GRAB OPEN SAPMODEL // check if any SAP file is open, grab SAP2000v16.SapObject mySapObject = null; string ModelUnits = string.Empty; // Open & instantiate SAP file Initialize.GrabOpenSAP(ref mySapModel, ref ModelUnits, Units); if (mySapModel == null) { // Open a blank SAP Model try { SAPConnection.Initialize.InitializeSapModel(ref mySapObject, ref mySapModel, Units); } catch (Exception) { SAPConnection.Initialize.Release(ref mySapObject, ref mySapModel); }; } //2. Create or Update Frames (Sets Releases) // 2.a. Harvest the elements from SAP Model SAPConnection.StructureMapper.GetSAPFrameList(ref mySapModel, ref SAPFrmList); // frms SAPConnection.StructureMapper.GetSAPAreaList(ref mySapModel, ref SAPAreaList); // areas SAPConnection.StructureMapper.GetSAPJointList(ref mySapModel, ref SAPJointList); // joints // 2a. DELETE if (delete) { //Delete Frms from SAP not in Structural elements foreach (var sapfrm in SAPFrmList) { Element el = null; try { el = (from f in StructuralModel.StructuralElements where f.Label == sapfrm && f.Type == Structure.Type.Frame select f).First(); } catch (Exception) { } if (el == null) // not in Dynamo Structure so delete from SAP Model { SAPConnection.StructureMapper.DeleteFrm(ref mySapModel, sapfrm); } } // Delete Areas from SAP not in Structural elements foreach (var sapArea in SAPAreaList) { //Element el = null; //try //{ // el = (from f in StructuralModel.StructuralElements // where f.Label == sapArea // select f).First(); //} //catch (Exception) { } //if (el == null) //{ SAPConnection.StructureMapper.DeleteArea(ref mySapModel, sapArea, ref error); if (error != string.Empty) { report.Add(error); error = string.Empty; } //} } // Delete Joints from SAP not in Structural elements foreach (var sapJoint in SAPJointList) { Element el = null; try { el = (from f in StructuralModel.StructuralElements where f.Label == sapJoint && f.Type == Structure.Type.Joint select f).First(); } catch (Exception) { } if (el == null && sapJoint.StartsWith("dyn")) // not in Dynamo Structure so delete from SAP Model { SAPConnection.StructureMapper.DeleteJoint(ref mySapModel, sapJoint, ref error); if (error != string.Empty) { report.Add(error); error = string.Empty; } } } } //2. CREATE OR UPDATE SIMULTENOUSLY //2.b. Create or Update foreach (var el in StructuralModel.StructuralElements) { if (el.Type == Structure.Type.Frame) { bool isupdate = SAPFrmList.Contains(el.Label); CreateorUpdateFrame(el as Frame, ref mySapModel, SF, isupdate); Frame frm = el as Frame; // Set Releases if (frm.Releases != null) { SetReleases(el as Frame, ref mySapModel); // Set releases } } else if (el.Type == Structure.Type.Shell) { bool isupdate = SAPAreaList.Contains(el.Label); CreateorUpdateArea(el as Shell, ref mySapModel, SF, false); } else if (el.Type == Structure.Type.Joint) { bool isupdate = SAPJointList.Contains(el.Label); CreateorUpdateJoint(el as Joint, ref mySapModel, SF, isupdate); } } // LinqInquiry List<Definition> LPatterns = new List<Definition>(); try { LPatterns = (from def in StructuralModel.ModelDefinitions where def.Type == Definitions.Type.LoadPattern select def).ToList(); } catch (Exception) { } // Add Load Patterns to the SAP Model if (LPatterns.Count > 0) { foreach (LoadPattern lp in LPatterns) { //Call the AddLoadPattern method SAPConnection.LoadMapper.AddLoadPattern(ref mySapModel, lp.name, lp.type, lp.multiplier); } } List<Definition> LCases = new List<Definition>(); try { LCases = (from def in StructuralModel.ModelDefinitions where def.Type == Definitions.Type.LoadCase select def).ToList(); } catch { } if (LCases.Count > 0) { foreach (LoadCase lc in LCases) { List<string> types = new List<string>(); List<string> names = new List<string>(); List<double> SFs = new List<double>(); for (int i = 0; i < lc.loadPatterns.Count; i++) { types.Add("Load"); names.Add(lc.loadPatterns[i].name); SFs.Add(lc.sFs[i]); } string[] Dtypes = types.ToArray(); string[] Dnames = names.ToArray(); double[] DSFs = SFs.ToArray(); SAPConnection.LoadMapper.AddLoadCase(ref mySapModel, lc.name, types.Count(), ref Dtypes, ref Dnames, ref DSFs, lc.type); } } List<Definition> LCombo = new List<Definition>(); try { LCombo = (from def in StructuralModel.ModelDefinitions where def.Type == Definitions.Type.LoadCombo select def).ToList(); } catch { } if (LCombo.Count > 0) { foreach (LoadCombo lc in LCombo) { List<string> types = new List<string>(); List<string> names = new List<string>(); List<double> SFs = new List<double>(); for (int i = 0; i < lc.loadDefinitions.Count; i++) { if (lc.loadDefinitions[i].Type == Definitions.Type.LoadCase) { types.Add("LoadCase"); names.Add(((LoadCase)lc.loadDefinitions[i]).name); } else if (lc.loadDefinitions[i].Type == Definitions.Type.LoadCombo) { types.Add("LoadCombo"); names.Add(((LoadCombo)lc.loadDefinitions[i]).name); } SFs.Add(lc.sFs[i]); } string[] Dtypes = types.ToArray(); string[] Dnames = names.ToArray(); double[] DSFs = SFs.ToArray(); SAPConnection.LoadMapper.AddLoadCombo(ref mySapModel, lc.name, Dtypes, Dnames, DSFs, lc.type); } } // Set Loads foreach (var el in StructuralModel.StructuralElements) { if (el.Type == Structure.Type.Frame) { Frame frm = el as Frame; // Set Loads if (frm.Loads != null) { SetLoads(el as Frame, ref mySapModel); } } } // Create or Update Groups // Harvest the names of the groups// delete the ones not in the SAP Model SAPConnection.GroupMapper.GetSAPGroupList(ref mySapModel, ref SAPGroupList); List<Definition> Groups = new List<Definition>(); try { Groups = (from def in StructuralModel.ModelDefinitions where def.Type == Definitions.Type.Group select def).ToList(); } catch (Exception) { } // Update or Create new one and set assignments List<string> tempNames = new List<string>(); if (Groups.Count > 0) { foreach (Group g in Groups) { tempNames.Add(g.Name); bool update = false; if (SAPGroupList.Contains(g.Name)) { update = true; } CreateorUpdateGroup(g, ref mySapModel, update); } } if (delete) { foreach (var g in SAPGroupList) { // Delete from SAP Model if (!tempNames.Contains(g)) { SAPConnection.GroupMapper.Delete(ref mySapModel, g); } } } // refresh View //SAPConnection.StructureMapper.RefreshView(ref mySapModel); // Delete unconnected points at the SAP SAPConnection.StructureMapper.DeleteUnconnectedPts(ref mySapModel); // refresh View SAPConnection.StructureMapper.RefreshView(ref mySapModel); //if can't set to null, will be a hanging process mySapModel = null; mySapObject = null; }
public static Dictionary<string, object> Run(string FilePath, bool Run) { List<string> LoadCaseNames = new List<string>(); List<string> LoadPatternNames = new List<string>(); List<string> LoadComboNames = new List<string>(); StructuralModel Model = new StructuralModel(); if (Run) { string units = string.Empty; SAPConnection.Initialize.OpenSAPModel(FilePath, ref mySapModel, ref units); Read.StructuralModelFromSapFile(ref mySapModel, ref Model, units); // run analysis SAPConnection.AnalysisMapper.RunAnalysis(ref mySapModel, FilePath, ref LoadCaseNames, ref LoadPatternNames, ref LoadComboNames); } return new Dictionary<string, object> { {"Structural Model", Model}, {"Load Cases", LoadCaseNames}, {"Load Patterns", LoadPatternNames}, {"Load Combos", LoadComboNames} }; }
public static Dictionary<string, object> Run(bool Run) { List<string> LoadCaseNames = new List<string>(); List<string> LoadPatternNames = new List<string>(); List<string> LoadComboNames = new List<string>(); StructuralModel Model = new StructuralModel(); string SaveAs = ""; if (Run) { string modelunits = string.Empty; SAPConnection.Initialize.GrabOpenSAP(ref mySapModel, ref modelunits, ""); Read.StructuralModelFromSapFile(ref mySapModel, ref Model, modelunits); SaveAs = SAPConnection.Initialize.GetModelFilename(ref mySapModel); if (SaveAs == "") { throw new Exception("File has not been saved before. Please, go to SAP and save the file"); } if (mySapModel == null) { throw new Exception("SAP Model was not grabbed. Use run analysis with filepath"); } else { // run analysis SAPConnection.AnalysisMapper.RunAnalysis(ref mySapModel, SaveAs, ref LoadCaseNames, ref LoadPatternNames, ref LoadComboNames); } } return new Dictionary<string, object> { {"Structural Model", Model}, {"Load Cases", LoadCaseNames}, {"Load Patterns", LoadPatternNames}, {"Load Combos", LoadComboNames}, {"Filepath", SaveAs} }; }
internal static void StructuralModelFromSapFile(ref cSapModel SapModel, ref StructuralModel model, string SapModelUnits) { model.StructuralElements = new List<Element>(); model.ModelDefinitions = new List<Definition>(); List<LoadPattern> TempLPatterns = new List<LoadPattern>(); string error = string.Empty; if (SapModel != null) { // 1.a GET LOAD PATTERNS string[] LoadPatternNames = null; string[] LoadPatternTypes = null; double[] LoadPatternMultipliers = null; StructureMapper.GetLoadPatterns(ref SapModel, ref LoadPatternNames, ref LoadPatternTypes, ref LoadPatternMultipliers); if (LoadPatternNames != null) { foreach (string lpname in LoadPatternNames) { int pos = Array.IndexOf(LoadPatternNames, lpname); LoadPattern lp = new LoadPattern(lpname, LoadPatternTypes[pos], LoadPatternMultipliers[pos]); model.ModelDefinitions.Add(lp); TempLPatterns.Add(lp); } } // 1.b GET LOAD CASES string[] LoadCasesNames = null; string[] LoadCasesTypes = null; double[] LoadCasesMultipliers = null; //With this method we only get the name and the type of each load case StructureMapper.GetLoadCases(ref SapModel, ref LoadCasesNames, ref LoadCasesMultipliers, ref LoadCasesTypes); if (LoadCasesNames != null) { foreach (string lcname in LoadCasesNames) { int pos = Array.IndexOf(LoadCasesNames, lcname); //create a new load LoadCase lc = new LoadCase(); lc.name = lcname; lc.type = LoadCasesTypes[pos]; model.ModelDefinitions.Add(lc); } } //1.c GET LOAD COMBOS string[] LoadCombosNames = null; string[][] LoadCombosTypes = null; string[][] LoadCombosCases = null; string[][] LoadCombosDefinitions = null; double[][] LoadCombosMultipliers = null; StructureMapper.GetLoadCombos(ref SapModel, ref LoadCombosNames, ref LoadCombosTypes, ref LoadCombosCases, ref LoadCombosMultipliers, ref LoadCombosDefinitions); if (LoadCombosNames != null) { foreach (string lcname in LoadCombosNames) { int pos = Array.IndexOf(LoadCombosNames, lcname); List<Definition> LoadDefinitions = new List<Definition>(); foreach (string comboType in LoadCombosTypes[pos]) { int pos2 = Array.IndexOf(LoadCombosTypes[pos], comboType); Definition def = new Definition(); if (comboType == "LoadCase") { //find the existing Load Case foreach (Definition d in model.ModelDefinitions) { if (d.Type == Definitions.Type.LoadCase) { if (((LoadCase)d).name == LoadCombosDefinitions[pos][pos2]) { def = d; } } } } else { def.Type = Definitions.Type.LoadCombo; ((LoadCombo)def).name = comboType; } LoadDefinitions.Add(def); } //create a new load combo LoadCombo loadcombo = new LoadCombo(lcname, LoadCombosTypes[pos][0], LoadDefinitions, LoadCombosMultipliers[pos].ToList()); model.ModelDefinitions.Add(loadcombo); } } // 2. GET DYNAMO FRAMES ( get Loads and Releases that are assigned to that frame) //2.a GET LOADS that are Assigned to Frames Dictionary<int, string> DictFrm_PointLoads = new Dictionary<int, string>(); Dictionary<int, string> DictFrm_DistLoads = new Dictionary<int, string>(); //Get Point Loads string[] framesWithPointLoads = null; string[] PlPattern = null; int Pnumber = 0; int[] PmyType = null; string[] PCsys = null; int[] Pdir = null; double[] PRelDist = null; double[] PDist = null; double[] PVal = null; LoadMapper.GetPointLoads(ref SapModel, ref framesWithPointLoads, ref Pnumber, ref PlPattern, ref PmyType, ref PCsys, ref Pdir, ref PRelDist, ref PDist, ref PVal); if (framesWithPointLoads != null) { for (int i = 0; i < framesWithPointLoads.Count(); i++) { DictFrm_PointLoads.Add(i, framesWithPointLoads[i]); } } // Get Distributed Loads string[] framesWithDistributedLoads = null; string[] DlPattern = null; int Dnumber = 0; int[] DmyType = null; string[] DCsys = null; int[] Ddir = null; double[] DRD1 = null; double[] DRD2 = null; double[] DDist1 = null; double[] DDist2 = null; double[] DVal1 = null; double[] DVal2 = null; LoadMapper.GetDistributedLoads(ref SapModel, ref framesWithDistributedLoads, ref Dnumber, ref DlPattern, ref DmyType, ref DCsys, ref Ddir, ref DRD1, ref DRD2, ref DDist1, ref DDist2, ref DVal1, ref DVal2); if (framesWithDistributedLoads != null) { for (int i = 0; i < framesWithDistributedLoads.Count(); i++) { DictFrm_DistLoads.Add(i, framesWithDistributedLoads[i]); } } //2.b Get Frames // Calculate Length Scale Factor //Double SF = Utilities.UnitConversion("m", SapModelUnits); // Dynamo API Lenght Unit is 'meter' Double SF = 1; List<string> FrmIds = new List<string>(); StructureMapper.GetSAPFrameList(ref SapModel,ref FrmIds); for (int i = 0; i < FrmIds.Count; i++) { Point s = null; Point e = null; string matProp = "A992Fy50"; // default value string secName = "W12X14"; // default value string secCatalog = "AISC14"; // default value string Just = "MiddleCenter"; // default value double Rot = 0; // default value StructureMapper.GetFrm(ref SapModel, FrmIds[i], ref s, ref e, ref matProp, ref secName, ref Just, ref Rot, ref secCatalog, SF); SectionProp secProp = new SectionProp(secName, matProp, secCatalog); Frame d_frm = new Frame(s, e, secProp, Just, Rot); d_frm.Label = FrmIds[i]; model.StructuralElements.Add(d_frm); //LOADS // Frame might have multiple loads assigned to it... d_frm.Loads = new List<Load>(); //Check if the frame has distributed loads var outindexes = from obj in DictFrm_DistLoads where obj.Value == d_frm.Label select obj.Key; foreach(int index in outindexes) { LoadPattern Dlp = null; foreach (LoadPattern loadp in TempLPatterns) { if (loadp.name == DlPattern[index]) { Dlp = loadp; break; } } if (Dlp != null) { // using relDist as true, and using the relative distance values DRD1 and DRD2 bool relDist = true; Load l = new Load(Dlp, DmyType[index], Ddir[index], DRD1[index], DRD2[index], DVal1[index], DVal2[index], DCsys[index], relDist); l.LoadType = "DistributedLoad"; d_frm.Loads.Add(l); } } //Check if the frame has Point Loads var outindexesO = from obj in DictFrm_PointLoads where obj.Value == d_frm.Label select obj.Key; foreach (int index in outindexesO) { LoadPattern Plp = null; foreach (LoadPattern loadp in TempLPatterns) { if (loadp.name == PlPattern[index]) { Plp = loadp; break; } } if (Plp != null) { bool relativedist = true; Load l = new Load(Plp, PmyType[index], Pdir[index], PRelDist[index], PVal[index], PCsys[index], relativedist); l.LoadType = "PointLoad"; d_frm.Loads.Add(l); } } //RELEASES bool[] ii = new bool[6]; bool[] jj = new bool[6]; ReleaseMapper.Get(ref SapModel, FrmIds[i], ref ii, ref jj); // Populate if return releases if (ii.Contains(true) || jj.Contains(true)) { d_frm.Releases = Release.Set(ii[0], jj[0] , ii[1], jj[1] , ii[2], jj[2] , ii[3], jj[3] , ii[4], jj[4] , ii[5], jj[5]); } } // 2.b Get Shells from SAP Model List<string> AreaIds = new List<string>(); SAPConnection.StructureMapper.GetSAPAreaList(ref SapModel, ref AreaIds); for (int i = 0; i < AreaIds.Count; i++) { Surface S = null; string propName = string.Empty; SAPConnection.StructureMapper.GetShell(ref SapModel, AreaIds[i], ref S, SF, ref propName); int ShellType= 1; bool DOF = true; string MatProp = string.Empty; double MatAngle = 0; double Thickness = 0; double Bending = 0; SAPConnection.StructureMapper.GetShellProp(ref SapModel, propName, ref ShellType, ref DOF, ref MatProp, ref MatAngle, ref Thickness, ref Bending); ShellProp sP = new ShellProp(propName, ShellType, DOF, MatProp, MatAngle, Thickness * SF, Bending); Shell d_Shell = new Shell(S, sP); d_Shell.Label = AreaIds[i]; model.StructuralElements.Add(d_Shell); } // 3. GET RESTRAINTS int CountRes = RestraintMapper.Count(ref SapModel); if (CountRes > 0) { List<string> PtIds = new List<string>(); RestraintMapper.GetSupportedPts(ref SapModel, ref PtIds); // Populate Dynamo Restraints foreach (var PtId in PtIds) { Point Pti = null; bool[] restraints = new bool[6]; RestraintMapper.Get(ref SapModel, PtId, ref Pti, ref restraints, SF); Joint myj = new Joint(Pti); myj.Label = PtId; // Populate on Joint Restraints Restraint support = Restraint.Define(restraints[0], restraints[1], restraints[2], restraints[3], restraints[4], restraints[5]); myj.JointRestraint = support; model.StructuralElements.Add(myj); } } } else { throw new Exception("Make sure SAP Model is open!"); } // Get Groups List<String> SapGroups = new List<string>(); SAPConnection.GroupMapper.GetSAPGroupList(ref SapModel, ref SapGroups); int counter = 0; foreach (var g in SapGroups) { Group myG = new Group(); myG.Name = g; myG.GroupElements = new List<Element>(); // get assignments int[] types = null; string[] Labels = null; SAPConnection.GroupMapper.GetGroupAssignments(ref SapModel, g, ref types, ref Labels); if (Labels!=null && Labels.Count() > 0) { for (int i = 0; i < Labels.Length; i++) { if (types[i] == 1) // Joint { try { var gel = (from el in model.StructuralElements where el.Label == Labels[i] && el.Type == Structure.Type.Joint select el).First(); if (gel != null) { myG.GroupElements.Add(gel); } } catch (Exception) { } } else if (types[i] == 2) // frame { try { var gel = (from el in model.StructuralElements where el.Type == Structure.Type.Frame && el.Label == Labels[i] select el).First(); if (gel != null) { myG.GroupElements.Add(gel); } } catch (Exception) { } } else if (types[i] == 3) // cable { //TODO: After cable object defined } else if (types[i] == 5) // shell { var gel = (from el in model.StructuralElements where el.Type == Structure.Type.Shell && el.Label == Labels[i] select el).First(); if (gel != null) { myG.GroupElements.Add(gel); } } } } else { counter++; } //Add to Model definitions model.ModelDefinitions.Add(myG); } if (counter == SapGroups.Count) { //throw new Exception("The group(s) have no members assigned"); } }
/// <summary> /// Visualize forces and moments in the model for a specific case /// </summary> /// <param name="StructuralModel">Structural model to visualize results on</param> /// <param name="AnalysisResults">Use Analysis.Run and Analysis.GetResults to select a specific case to decompose</param> /// <param name="ForceType">Use Force Type dropdown</param> /// <param name="Scale">Scale of the visualization</param> /// <param name="Visualize">Set Boolean to True to draw the meshes</param> /// <returns>Forces and moments in the form of meshes for each station in each structural member in the model</returns> /// public static List<List<Mesh>> VisualizeResults(StructuralModel StructuralModel, Analysis AnalysisResults, string ForceType, bool Visualize, double Scale = 1.0) { List<List<double>> myForces = DecomposeResults(StructuralModel, AnalysisResults, ForceType); double max = 0.0; for (int i = 0; i < myForces.Count; i++) { for (int j = 0; j < myForces[i].Count; j++) { if (myForces[i][j] >= max) max = myForces[i][j]; } } // Define a coefficient to visualize the forces Frame fs = (Frame)StructuralModel.StructuralElements[0]; double lenght = 0.5 * fs.BaseCrv.Length; double coefficient = 0.0; if (max != 0) coefficient = lenght / max; List<List<Mesh>> VizMeshes = new List<List<Mesh>>(); List<Line> frameNormals = new List<Line>(); if (Visualize) { int j = 0; for (int i = 0; i < StructuralModel.StructuralElements.Count; i++) //for (int i = 0; i < AnalysisResults.FrameResults.Count; i++) { //List of meshes per structural element in the model List<Mesh> frameResultsMesh = new List<Mesh>(); // Linq inqury FrameResults frmresult = null; try { frmresult = (from frm in AnalysisResults.FrameResults where frm.ID == StructuralModel.StructuralElements[i].Label select frm).First(); } catch { } if (frmresult == null || StructuralModel.StructuralElements[i].Type!= Structure.Type.Frame) { //Add an empty list to match the tree that contains Joints VizMeshes.Add(frameResultsMesh); continue; } // Get the frame's curve specified by the frameID // Frame f = (Frame)StructuralModel.StructuralElements[i]; Frame f = (Frame)(from frame in StructuralModel.StructuralElements where frame.Label == frmresult.ID select frame).First(); Curve c = f.BaseCrv; //LOCAL COORDINATE SYSTEM Vector xAxis = c.TangentAtParameter(0.0); Vector yAxis = c.NormalAtParameter(0.0); //This ensures the right axis for the Z direction CoordinateSystem localCS = CoordinateSystem.ByOriginVectors(c.StartPoint, xAxis, yAxis); //LINES TO VISUALIZE THE NORMALS OF THE FRAME CURVES //Point middlePt = c.PointAtParameter(0.5); //Line ln = Line.ByStartPointDirectionLength(middlePt, localCS.ZAxis, 30.0); //frameNormals.Add(ln); //List to hold the points to make a mesh face List<Point> MeshPoints = new List<Point>(); // t value of the previous station double t1 = 0.0; // t value of the current station double t2 = 0.0; // Local Z value of the previous station double v1 = 0.0; // Local Z value of the current station double v2 = 0; // Integer to count the number of times there are stations with value=0 (no force) int zeroCount = 0; // Loop through each station (t value) in the analysis results dictionary foreach (double t in frmresult.Results[AnalysisResults.LCaseOrLPatternRun].Keys) { double newt = t; if (t < 0) newt = -t; Mesh m = null; Point tPoint = c.PointAtParameter(newt); // Point on the curve at the specified t2 Point vPoint = null; // Point that is translated from the cPoint according to the value v2 // Double to hold the local Z value of the station multiplied by the scale factor double translateCoord = 0.0; if (ForceType == "Axial") // Get Axial P { v2 = AnalysisResults.FrameResults[j].Results[AnalysisResults.LCaseOrLPatternRun][newt].P; translateCoord = v2 * coefficient * (-Scale); } else if (ForceType == "Shear22") // Get Shear V2 { v2 = AnalysisResults.FrameResults[j].Results[AnalysisResults.LCaseOrLPatternRun][newt].V2; translateCoord = v2 * coefficient * (-Scale); } else if (ForceType == "Shear33") // Get Shear V3 { v2 = AnalysisResults.FrameResults[j].Results[AnalysisResults.LCaseOrLPatternRun][newt].V3; translateCoord = v2 * coefficient * coefficient * Scale; } else if (ForceType == "Torsion") // Get Torsion T { v2 = AnalysisResults.FrameResults[j].Results[AnalysisResults.LCaseOrLPatternRun][newt].T; translateCoord = v2 * coefficient * (-Scale); } else if (ForceType == "Moment22") // Get Moment M2 { v2 = AnalysisResults.FrameResults[j].Results[AnalysisResults.LCaseOrLPatternRun][newt].M2; translateCoord = v2 * coefficient * (-Scale); } else if (ForceType == "Moment33") // Get Moment M3 { v2 = AnalysisResults.FrameResults[j].Results[AnalysisResults.LCaseOrLPatternRun][newt].M3; translateCoord = v2 * coefficient * Scale; } v2 = Math.Round(v2, 4, MidpointRounding.AwayFromZero); // if there is no value for the force (it is zero), add one to the count if (translateCoord == 0.0) zeroCount++; if (ForceType == "Moment22" || ForceType == "Shear33") { vPoint = (Point)tPoint.Translate(localCS.YAxis, translateCoord); // Translate in the Y direction to match the visualization of SAP } else { vPoint = (Point)tPoint.Translate(localCS.ZAxis, translateCoord); // All the other types must be translate in the Z direction} } //Point that results from the intersection of the line between two value Points and the frame curve Point pzero = null; IndexGroup ig3 = IndexGroup.ByIndices(0, 1, 2); IndexGroup ig4 = IndexGroup.ByIndices(0, 1, 2, 3); //if no points have been added yet, add the point on the curve and then the point representing the value if (MeshPoints.Count == 0) { MeshPoints.Add(tPoint); //index 0 // if the first value is not 0 if (v2 != 0.0) { MeshPoints.Add(vPoint); //index 1 } } // if a previous point(s) has been added else { // List to hold the indices for the mesh face List<IndexGroup> indices = new List<IndexGroup>(); //Parameter at which the value of the forces = 0. It is the X coordinate of the pzero double tzero; // Current t parameter of the point being visualized relative to the length of the frame curve t2 = newt * c.Length; // If there is a change in the force sign, calculate the intersection point // Then, add two trianglular mesh faces if ((v1 > 0 && v2 < 0) || (v1 < 0 && v2 > 0)) { // The function of the line is: y= (t2-t1)tzero/(d2-d1)+d1 This has to be equal to 0 double ml = (v2 - v1) / (t2 - t1); tzero = (0 - v1) / ml; // Add the X coordinate of the last mesh point tzero += t1; pzero = Point.ByCartesianCoordinates(localCS, tzero, 0.0, 0.0); //Add the third point for the first triangular mesh face MeshPoints.Add(pzero); //index 2 indices.Add(ig3); // ||| Color coding here m = Mesh.ByPointsFaceIndices(MeshPoints, indices); frameResultsMesh.Add(m); MeshPoints.Clear(); //Add the third point for the second triangular mesh face MeshPoints.Add(pzero); //new face index 0 // Add the current station's points MeshPoints.Add(tPoint); //new face index 1 MeshPoints.Add(vPoint); //new face index 2 // ||| Color coding here m = Mesh.ByPointsFaceIndices(MeshPoints, indices); frameResultsMesh.Add(m); } // Create a quad mesh face or a triangular mesh if the first value was 0 else { MeshPoints.Add(vPoint); //index 2 (note: vPoint before cPoint) MeshPoints.Add(tPoint); //index 3 if (MeshPoints.Count == 4) indices.Add(ig4); else indices.Add(ig3); // ||| Color coding here m = Mesh.ByPointsFaceIndices(MeshPoints, indices); frameResultsMesh.Add(m); } //Clear the temporary list MeshPoints.Clear(); // Add the current station's points MeshPoints.Add(tPoint); //new face index 0 MeshPoints.Add(vPoint); //new face index 1 } // Update the values for the next station t1 = newt * c.Length; v1 = v2; } // If all the values were zero, show empty list in output for that specific member if (zeroCount == AnalysisResults.FrameResults[j].Results[AnalysisResults.LCaseOrLPatternRun].Keys.Count) { frameResultsMesh.Clear(); } VizMeshes.Add(frameResultsMesh); j++; } } return VizMeshes; }
/// <summary> /// Decompose forces and moments in the model for a specific case /// </summary> /// <param name="StructuralModel">Structural model to get results from</param> /// <param name="AnalysisResults">Use Analysis.Run and Analysis.GetResults to select a specific case to decompose</param> /// <param name="ForceType">Use Force Type dropdown</param> /// <returns>Numerical values of forces and moments for each station in each structural member in the model </returns> public static List<List<double>> DecomposeResults(StructuralModel StructuralModel, Analysis AnalysisResults, string ForceType) { List<List<double>> Forces = new List<List<double>>(); for (int i = 0; i < StructuralModel.StructuralElements.Count; i++) { List<double> ff = new List<double>(); FrameResults frmresult = null; // linq inqury try { frmresult = (from frm in AnalysisResults.FrameResults where frm.ID == StructuralModel.StructuralElements[i].Label select frm).First(); } catch { } //if it is a joint, the element will not have frame results //Add 0.0 to maintain the order of the structural elements in the Structural Model if (frmresult == null || frmresult.Results.Count == 0) { ff.Add(0.0); Forces.Add(ff); continue; } foreach (FrameAnalysisData fad in frmresult.Results[AnalysisResults.LCaseOrLPatternRun].Values) { if (ForceType == "Axial") //Get Axial Forces P { ff.Add(fad.P); } else if (ForceType == "Shear22") // Get Shear V2 { ff.Add(fad.V2); } else if (ForceType == "Shear33") // Get Shear V3 { ff.Add(fad.V3); } else if (ForceType == "Torsion") // Get Torsion T { ff.Add(fad.T); } else if (ForceType == "Moment22") // Get Moment M2 { ff.Add(fad.M2); } else if (ForceType == "Moment33") // Get Moment M3 { ff.Add(fad.M3); } } Forces.Add(ff); } return Forces; }
public void Run(ref StructuralModel structure) { FEModel.Geometry geom = new FEModel.Geometry(); double H = structure.StoryHeight; for (int i = 0; i < structure.NumStories; i++) //for(int i = 0; i < 2; i++) { for (int j = 0; j < structure.Slabs.Count; j++) { List <MWPoint2D> pts = structure.Slabs[j].Points; Shell s = new Shell(pts.Select(p => new MWPoint3D(p.X, p.Y, (i + 1) * H)).ToList(), structure.SlabThickness, ShellType.Slab); s.Holes = structure.Openings.Select(o => o.Points.Select(p => new MWPoint3D(p.X, p.Y, (i + 1) * H)).ToList()).ToList(); geom.Shells.Add(s); } for (int j = 0; j < structure.Columns.Count; j++) { var col = structure.Columns[j]; MWPoint2D center = new MWPoint2D(0.5 * (col.Points[0].X + col.Points[2].X), 0.5 * (col.Points[0].Y + col.Points[2].Y)); List <MWPoint2D> secPts = col.Points.Select(p => new MWPoint2D(p.X - center.X, p.Y - center.Y)).ToList(); geom.Beams.Add(new Beam(new MWPoint3D(center.X, center.Y, i * structure.StoryHeight), new MWPoint3D(center.X, center.Y, (i + 1) * structure.StoryHeight), secPts)); } for (int j = 0; j < structure.Walls.Count; j++) { List <MWPoint2D> wall = structure.Walls[j].Points; List <MWPoint3D> wallPts = new List <MWPoint3D>() { new MWPoint3D(wall[0].X, wall[0].Y, i * structure.StoryHeight), new MWPoint3D(wall[1].X, wall[1].Y, i * structure.StoryHeight), new MWPoint3D(wall[1].X, wall[1].Y, (i + 1) * structure.StoryHeight), new MWPoint3D(wall[0].X, wall[0].Y, (i + 1) * structure.StoryHeight), }; geom.Shells.Add(new Shell(wallPts, structure.WallThickness, ShellType.Wall)); } } // Loads FEModel.Loads loads = new Loads() { LL = structure.sLoad.LL, SDL = structure.sLoad.SDL, CLAD = structure.sLoad.CLAD }; fem = new FEModel.FEModel(geom, loads); Stopwatch sw = new Stopwatch(); sw.Start(); Results = fem.Analyze(); TimeSpan ts = sw.Elapsed; Console.WriteLine("meshing time = {0}s", ts.TotalSeconds); BuildMesh(); ts = sw.Elapsed; Console.WriteLine("display time = {0}s", ts.TotalSeconds); sw.Stop(); }