/// <summary> /// Add SurfaceReinforcement to slab. /// Internal method use by GH components and Dynamo nodes. /// </summary> public static Shells.Slab AddReinforcementToSlab(Shells.Slab slab, List <SurfaceReinforcement> srfReinfs) { // deep clone. downstreams objs will contain changes made in this method, upstream objs will not. // downstream and uppstream objs will share guid. Shells.Slab clone = slab.DeepClone(); // check if slab material is concrete if (clone.Material.Concrete == null) { throw new System.ArgumentException("Material of slab must be concrete"); } // check if mixed layers if (SurfaceReinforcement.MixedLayers(srfReinfs)) { throw new System.ArgumentException("Can't add mixed layers to the same slab"); } if (SurfaceReinforcement.AllStraight(srfReinfs)) { return(SurfaceReinforcement.AddStraightReinfToSlab(clone, srfReinfs)); } else if (SurfaceReinforcement.AllCentric(srfReinfs)) { return(SurfaceReinforcement.AddCentricReinfToSlab(clone, srfReinfs)); } else { throw new System.ArgumentException("Can't add mixed surface reinforcement layouts to the same slab."); } }
/// <summary> /// Straight reinforcement layout on slab. /// </summary> public static SurfaceReinforcementParameters Straight(Shells.Slab slab, bool singleLayerReinforcement = false) { GuidListType baseShell = new GuidListType(slab.SlabPart.Guid); Center center = Center.Straight(); Geometry.FdVector3d xDirection = slab.SlabPart.LocalX; Geometry.FdVector3d yDirection = slab.SlabPart.LocalY; return(new SurfaceReinforcementParameters(singleLayerReinforcement, baseShell, center, xDirection, yDirection)); }
private static Shells.Slab AddCentricReinfToSlab(Shells.Slab slab, List <SurfaceReinforcement> srfReinfs) { if (SurfaceReinforcement.AllCentric(srfReinfs)) { throw new System.ArgumentException("Method to add centric surface reinforcement is not implemented yet."); } else { throw new System.ArgumentException("Not all passed surface reinforcement objects are of layout type centric"); } }
protected override void SolveInstance(IGH_DataAccess DA) { Shells.Slab slab = null; List <Shells.EdgeConnection> shellEdgeConnections = new List <Shells.EdgeConnection>(); List <int> indices = new List <int>(); if (!DA.GetData(0, ref slab)) { return; } if (!DA.GetDataList(1, shellEdgeConnections)) { return; } if (!DA.GetDataList(2, indices)) { return; } if (slab == null) { return; } Shells.Slab obj; if (shellEdgeConnections.Count == 0) { AddRuntimeMessage(GH_RuntimeMessageLevel.Warning, $"No shell edge connection added to shell {slab.Name}"); return; } else if (shellEdgeConnections.Count == 1) { var shellEdgeConnection = shellEdgeConnections[0]; obj = Shells.Slab.EdgeConnection(slab, shellEdgeConnection, indices); } else if (shellEdgeConnections.Count == indices.Count) { obj = Shells.Slab.EdgeConnection(slab, shellEdgeConnections[0], indices[0]); for (int i = 1; i < shellEdgeConnections.Count; i++) { obj = Shells.Slab.EdgeConnection(obj, shellEdgeConnections[i], indices[i]); } } else { throw new ArgumentException($"The number of shellEdgeConnections must be 1 or eqal to the number of indices provided. Recieved {shellEdgeConnections.Count} and {indices.Count}"); } DA.SetData(0, obj); }
static void Main() { // EXAMPLE 4: EDITING AN EXISTING MODEL // In this example, we will edit an existing model by isolating a floor and replacing supporting // walls and pillars with appropriate supports. Using height as a point of comparison we can find // which elements to reuse from the old model, and create a new model with our selected elements. // This example was last updated 2022-04-13, using the ver. 21.1.0 FEM-Design API. // READ THE MODEL: // Deserialize the current model to access all the data in the .struxml file. FemDesign.Model model = FemDesign.Model.DeserializeFromFilePath("Example 4 - model.struxml"); // ISOLATE A FLOOR: // Choose which floor will be singled out. int floor = 3; FemDesign.StructureGrid.Storey storey = model.Entities.Storeys.Storey[floor]; List <GenericClasses.IStructureElement> storeyAsList = new List <GenericClasses.IStructureElement> { storey }; double zCoord = storey.Origo.Z; // POINT SUPPORTS: // Find all pillars supporting the chosen floor, and place point supports in their place. // We can use the fact that point [1] of any pillar is always the highest one. var supports = new List <GenericClasses.ISupportElement>(); for (int i = 0; i < model.Entities.Bars.Count; i++) { Bars.Bar tempBar = model.Entities.Bars[i]; if (tempBar.BarPart.Type != Bars.BarType.Column) { continue; } if (Math.Abs(tempBar.BarPart.Edge.Points[1].Z - zCoord) < Tolerance.LengthComparison) { var tempSupport = new Supports.PointSupport( point: new Geometry.FdPoint3d(tempBar.BarPart.Edge.Points[1].X, tempBar.BarPart.Edge.Points[1].Y, zCoord), motions: Releases.Motions.RigidPoint(), rotations: Releases.Rotations.Free() ); supports.Add(tempSupport); } } // ELEMENTS: // The model only contains plates and walls, so we will not be looking for beams etc. // We are looking for the floor plate at the right height, and the walls below it to // replace them with line supports. var elements = new List <GenericClasses.IStructureElement>(); // TESTING SLABS: // Slabs have a property which indicates if they are floors (plate) or walls (wall). // Based on this, we can sort out if we want to use them as an element or place a // line support in their stead. for (int i = 0; i < model.Entities.Slabs.Count; i++) { Shells.Slab tempSlab = model.Entities.Slabs[i]; if (tempSlab.Type == Shells.SlabType.Plate && Math.Abs(tempSlab.SlabPart.LocalPos.Z - zCoord) < Tolerance.LengthComparison) { elements.Add(tempSlab); } else if (tempSlab.Type == Shells.SlabType.Wall) { if (Math.Abs(tempSlab.SlabPart.Region.Contours[0].Edges[2].Points[0].Z - zCoord) < Tolerance.LengthComparison) { // Creating supports with translational stiffnes in the Z direction only. var tempSupport = new Supports.LineSupport( edge: tempSlab.SlabPart.Region.Contours[0].Edges[2], motions: new Releases.Motions(0, 0, 0, 0, 10E7, 10E7), rotations: new Releases.Rotations(0, 0, 0, 0, 0, 0), movingLocal: true ); supports.Add(tempSupport); } } } // TESTING PANELS: // Panels do not have the same property as slabs. Instead, we compare the height of all the // edge curves of the panel to discern if it is horizontal or not. for (int i = 0; i < model.Entities.Panels.Count; i++) { Shells.Panel tempPanel = model.Entities.Panels[i]; bool isSlab = true; for (int j = 0; j < tempPanel.Region.Contours[0].Edges.Count; j++) { if (tempPanel.Region.Contours[0].Edges[j].Points[0].Z != tempPanel.Region.Contours[0].Edges[j].Points[1].Z) { isSlab = false; break; } } if (isSlab && Math.Abs(tempPanel.Region.Contours[0].Edges[0].Points[0].Z - zCoord) < Tolerance.LengthComparison) { elements.Add(tempPanel); } else if (!isSlab && Math.Abs(tempPanel.Region.Contours[0].Edges[2].Points[0].Z - zCoord) < Tolerance.LengthComparison) { // Creating supports with translational stiffnes in the Z direction only. var tempSupport = new Supports.LineSupport( edge: tempPanel.Region.Contours[0].Edges[2], motions: new Releases.Motions(0, 0, 0, 0, 10E7, 10E7), rotations: new Releases.Rotations(0, 0, 0, 0, 0, 0), movingLocal: true ); supports.Add(tempSupport); } } // LOADS: // Similar to supports and elements, we will reuse loads from the model if they are on the correct height var loads = new List <GenericClasses.ILoadElement>(); for (int i = 0; i < model.Entities.Loads.LineLoads.Count; i++) { if (Math.Abs(model.Entities.Loads.LineLoads[i].Edge.XAxis.Z - zCoord) < Tolerance.LengthComparison) { loads.Add(model.Entities.Loads.LineLoads[i]); } } for (int i = 0; i < model.Entities.Loads.SurfaceLoads.Count; i++) { Loads.SurfaceLoad tempLoad = model.Entities.Loads.SurfaceLoads[i]; if (Math.Abs(tempLoad.Region.Contours[0].Edges[0].Points[0].Z - zCoord) < Tolerance.LengthComparison) { loads.Add(tempLoad); } } // CREATE NEW MODEL: // With a new model, we can add all our gathered elements to it. We can also take load cases, // load combinations, and the storey marker directly from the old model. FemDesign.Model newModel = new FemDesign.Model(Country.S); newModel.AddElements(elements); newModel.AddSupports(supports); newModel.AddLoads(loads); newModel.AddLoadCases(model.Entities.Loads.LoadCases); newModel.AddLoadCombinations(model.Entities.Loads.LoadCombinations); newModel.AddElements(storeyAsList); // SAVE AND RUN: // Create a file path for the new model, serialize it, and run the script! string path = Path.GetFullPath("output/edited_model.struxml"); if (!Directory.Exists("output")) { Directory.CreateDirectory("output"); } newModel.SerializeModel(path); Console.WriteLine($"Opening file at {path}"); var app = new Calculate.Application(); app.OpenStruxml(path, false); }
public static Shells.Slab AddToSlab(Shells.Slab slab, List <SurfaceReinforcement> surfaceReinforcement) { // return return(SurfaceReinforcement.AddReinforcementToSlab(slab, surfaceReinforcement)); }
private static Shells.Slab AddStraightReinfToSlab(Shells.Slab slab, List <SurfaceReinforcement> srfReinfs) { // assert layout if (SurfaceReinforcement.AllStraight(srfReinfs)) { } else { throw new System.ArgumentException("Not all passed surface reinforcement objects are of layout type straight"); } // assert layers if (SurfaceReinforcement.MixedLayers(srfReinfs)) { throw new System.ArgumentException("Can't add mixed layers to the same slab"); } // single layer? var singleLayer = SurfaceReinforcement.AllSingleLayer(srfReinfs); // check if surface reinf parameters are set to slab SurfaceReinforcementParameters srfReinfParams; if (slab.SurfaceReinforcementParameters == null) { srfReinfParams = SurfaceReinforcementParameters.Straight(slab, singleLayer); slab.SurfaceReinforcementParameters = srfReinfParams; } // any surfaceReinforcementParameter set to slab will be overwritten // any surfaceReinforcement with option "centric" will be removed else if (slab.SurfaceReinforcementParameters.Center.PolarSystem == true) { srfReinfParams = SurfaceReinforcementParameters.Straight(slab); slab.SurfaceReinforcementParameters = srfReinfParams; foreach (SurfaceReinforcement item in slab.SurfaceReinforcement) { if (item.Centric != null) { slab.SurfaceReinforcement.Remove(item); } } } // use surface parameters already set to slab else { srfReinfParams = slab.SurfaceReinforcementParameters; } // add surface reinforcement GuidListType baseShell = new GuidListType(slab.SlabPart.Guid); FemDesign.GuidListType surfaceReinforcementParametersGuidReference = new FemDesign.GuidListType(slab.SurfaceReinforcementParameters.Guid); foreach (SurfaceReinforcement item in srfReinfs) { // add references to item item.BaseShell = baseShell; item.SurfaceReinforcementParametersGuid = surfaceReinforcementParametersGuidReference; // check if region item exists if (item.Region == null) { item.Region = Geometry.Region.FromSlab(slab); } // add item to slab slab.SurfaceReinforcement.Add(item); } // return return(slab); }
/// <summary> /// Get region from a Slab. /// </summary> public static Region FromSlab(Shells.Slab slab) { return(slab.SlabPart.Region); }
/// <summary> /// Construct post-tension cable /// </summary> /// <param name="slab">Reference slab element</param> /// <param name="line">Cable line</param> /// <param name="shape"></param> /// <param name="losses"></param> /// <param name="manufacturing"></param> /// <param name="strand"></param> /// <param name="numberOfStrands"></param> /// <param name="identifier"></param> public Ptc(Shells.Slab slab, Geometry.LineSegment line, PtcShapeType shape, PtcLosses losses, PtcManufacturingType manufacturing, PtcStrandLibType strand, JackingSide jackingSide, double jackingStress, int numberOfStrands = 3, string identifier = "PTC") { Initialize(line.StartPoint, line.EndPoint, slab.SlabPart.Guid, shape, losses, manufacturing, strand, jackingSide, jackingStress, numberOfStrands, identifier); }
static void Main() { // PRACTICAL EXAMPLE: PARAMETRIC STUDY - REACTIONS // In this example, we will analyse how different E-modules will result // in different reaction forces in the supports holding a concrete plate. // This example was last updated 2022-05-03, using the ver. 21.1.0 FEM-Design API. // FILE PATH SETUP // Set the different paths and folders relevant to the example string struxmlPath = "sample_slab.struxml"; string outFolder = "output/"; if (!Directory.Exists(outFolder)) { Directory.CreateDirectory(outFolder); } string bscPath = Path.GetFullPath("pointsupportreactions.bsc"); List <string> bscPaths = new List <string>(); bscPaths.Add(bscPath); // READ MODEL Model model = Model.DeserializeFromFilePath(struxmlPath); // READ SLAB TO ANALYSE // In this example, the slab is card-coded to no. 5; if you make any personal applications, // it is probably better to look for a slab with a certain name, eg. P.1, to avoid confusion. Shells.Slab slab = model.Entities.Slabs[4]; Materials.Material material = model.Entities.Slabs[4].Material; double Ecm = Convert.ToDouble(material.Concrete.Ecm); // ITERATION & ANALYSIS PROCESS // Iterate over model using different E-modulus for the slab for (int i = 1; i < 6; i++) { // Change E-modulus double new_Ecm = Math.Round(0.2 * i * Ecm); material.Concrete.Ecm = Convert.ToString(new_Ecm); // Save struxml string outPathIndividual = Path.GetFullPath(outFolder + "sample_slab_out" + Convert.ToString(new_Ecm) + ".struxml"); model.SerializeModel(outPathIndividual); // Run analysis Calculate.Analysis analysis = new Calculate.Analysis(null, null, null, null, calcCase: true, false, false, false, false, false, false, false, false, false, false, false, false); FemDesign.Calculate.FdScript fdScript = FemDesign.Calculate.FdScript.Analysis(outPathIndividual, analysis, bscPaths, "", true); Calculate.Application app = new Calculate.Application(); app.RunFdScript(fdScript, false, true, true); string pointSupportReactionsPath = Path.Combine(outFolder, "pointsupportreactions.csv"); // Reading results (This method is only available for some result types as of now, but more will be added) var results = Results.ResultsReader.Parse(pointSupportReactionsPath); var pointSupportReactions = results.Cast <Results.PointSupportReaction>().ToList(); // Print results Console.WriteLine(); Console.WriteLine($"Emean: {new_Ecm}"); Console.WriteLine("Id | Reaction "); foreach (var reaction in pointSupportReactions) { Console.WriteLine($"{reaction.Id,10} | {reaction.Fz,10}"); } } // ENDING THE PROGRAM Console.WriteLine("\nPress any key to close console."); Console.ReadKey(); }