protected override void SolveInstance(IGH_DataAccess DA) { // Declare a variable for the input GH_Model model = null; // Use the DA object to retrieve the data inside the first input parameter. // If the retieval fails (for example if there is no data) we need to abort. if (!DA.GetData(0, ref model)) { return; } List <Vector3d> displacementVectors = new List <Vector3d>(); List <Point3d> displacedPoints = new List <Point3d>(); List <GeometryBase> displacedElements = new List <GeometryBase>(); foreach (IFiniteElementNode node in model.Model) { Point3d location = node.ToPoint3d(); Vector3d vector = model.GetNodeDisplacement(node); Point3d point = model.GetDisplacedPoint(node); displacementVectors.Add(vector); displacedPoints.Add(point); } foreach (GH_Element element in model.Elements) { displacedElements.Add(element.GetDeformedGeometry(model)); } DA.SetDataList(0, displacementVectors); DA.SetDataList(1, displacedPoints); DA.SetDataList(2, displacedElements); }
protected override void SolveInstance(IGH_DataAccess DA) { List <GH_Element> elements = new List <GH_Element>(); List <GH_Support> supports = new List <GH_Support>(); List <GH_Load> loads = new List <GH_Load>(); int modelType = 1; if (!DA.GetDataList <GH_Element>(0, elements)) { return; } if (!DA.GetDataList <GH_Support>(1, supports)) { return; } if (!DA.GetDataList <GH_Load>(2, loads)) { return; } if (!DA.GetData(3, ref modelType)) { return; } //Clear current structure... Perhaps change this for a more parametric approach, or opening existing files GH_Model model = null; switch (modelType) { case 0: model = new GH_Model(ModelType.Truss2D, elements, loads, supports); break; case 1: model = new GH_Model(ModelType.Full3D, elements, loads, supports); break; case 2: model = new GH_Model(ModelType.Membrane3D, elements, loads, supports); break; default: throw new Exception("Model type does not exist or not yet implemented"); } model.AssembleSharpModel(); DA.SetData(0, model); }
public void Truss() { model = new GH_Model(ModelType.Full3D); GH_CrossSection crossSection = new GH_RectangularCrossSection(100, 100); GH_Material material = new GH_ElasticMaterial(100, 100, 100, 100); Point3d p1 = new Point3d(-10, 0, 0); Point3d p2 = new Point3d(0, 0, 0); Point3d p3 = new Point3d(10, 0, 0); Point3d p4 = new Point3d(-10, 0, 10); Point3d p5 = new Point3d(0, 0, 10); Point3d p6 = new Point3d(10, 0, 10); model.Elements.Add(new GH_Beam(p1, p2, crossSection, material)); model.Elements.Add(new GH_Beam(p2, p3, crossSection, material)); model.Elements.Add(new GH_Beam(p4, p5, crossSection, material)); model.Elements.Add(new GH_Beam(p5, p6, crossSection, material)); model.Elements.Add(new GH_Beam(p1, p4, crossSection, material)); model.Elements.Add(new GH_Beam(p2, p5, crossSection, material)); model.Elements.Add(new GH_Beam(p3, p6, crossSection, material)); model.Elements.Add(new GH_Beam(p4, p2, crossSection, material)); model.Elements.Add(new GH_Beam(p2, p6, crossSection, material)); model.Supports.Add(new GH_NodeSupport(p1, true, true, true, true, true, true)); model.Supports.Add(new GH_NodeSupport(p3, true, true, true, true, true, true)); model.Loads.Add(new GH_NodalLoad(p5, new Vector3d(0, 0, -1000), new Vector3d(0, 0, 0))); model.AssembleSharpModel(); Assert.AreEqual(9, model.Model.ElementCount); model.Solve(); Assert.NotNull(model.Results); Vector3d displacement = model.GetNodeDisplacement(1); //Displacement at point2 (index 1) Assert.NotNull(displacement); Assert.AreEqual(0.0, displacement.X, 0.001); Assert.AreEqual(0.0, displacement.Y, 0.001); Assert.AreNotEqual(0.0, displacement.Z); //TODO Calculate real value }
protected override void SolveInstance(IGH_DataAccess DA) { // Declare a variable for the input GH_Model model = null; // Use the DA object to retrieve the data inside the first input parameter. // If the retieval fails (for example if there is no data) we need to abort. if (!DA.GetData(0, ref model)) { return; } model.Solve(); DA.SetData(0, model); }
public void Setup() { model = new GH_Model(ModelType.Truss2D, new List <GH_Element>(), new List <GH_Load>(), new List <GH_Support>()); springConstant = 10; force = new Vector3d(0, 0, 10); moment = new Vector3d(0, 0, 0); point1 = new Point3d(0, 0, 0); point2 = new Point3d(0, 0, 10); point3 = new Point3d(0, 0, 20); spring1 = new GH_Spring(point1, point2, springConstant); spring2 = new GH_Spring(point2, point3, springConstant); nodalLoad1 = new GH_NodalLoad(point2, force, moment); nodalLoad2 = new GH_NodalLoad(point3, force, moment); nodeSupport1 = new GH_NodeSupport(point1, true, true, true, true, true, true); nodeSupport2 = new GH_NodeSupport(point2, true, true, false, true, true, true); }
public void Setup() { model = new GH_Model(ModelType.Full3D, new List <GH_Element>(), new List <GH_Load>(), new List <GH_Support>()); crossSection = new GH_RectangularCrossSection(0.5, 0.2); material = new GH_ElasticMaterial(0, 2000, 0.1, 1000); force = new Vector3d(10, 0, 0); moment = new Vector3d(0, 0, 0); point1 = new Point3d(0, 0, 0); point2 = new Point3d(0, 0, 1); point3 = new Point3d(1, 0, 1); point4 = new Point3d(1, 0, 0); beam1 = new GH_Beam(point1, point2, crossSection, material); beam2 = new GH_Beam(point2, point3, crossSection, material); beam3 = new GH_Beam(point3, point4, crossSection, material); nodalLoad1 = new GH_NodalLoad(point2, force, moment); nodeSupport1 = new GH_NodeSupport(point1, true, true, true, true, true, true); nodeSupport2 = new GH_NodeSupport(point4, true, true, true, true, true, true); }
protected override void SolveInstance(IGH_DataAccess DA) { // Declare a variable for the input GH_Model GH_RobotApplication = null; Point3d node = new Point3d(); // Use the DA object to retrieve the data inside the first input parameter. // If the retieval fails (for example if there is no data) we need to abort. if (!DA.GetData(0, ref GH_RobotApplication)) { return; } if (!DA.GetData(1, ref node)) { return; } throw new NotImplementedException("Reaction result component"); }
// This is the method that actually does the work. protected override void SolveInstance(IGH_DataAccess DA) { // Some variables string output = ""; // The file output string status = "Starting component...\n"; // The debug output // Several arrays where the data is stored List <Material> materials = new List <Material>(); List <CrossSection> crossSections = new List <CrossSection>(); List <Node> nodes = new List <Node>(); List <Beam> beams = new List <Beam>(); List <Load> loads = new List <Load>(); // We need to reset some variables because the objects are not freed until Grasshopper is unloaded Parser.id_count = 1; bool iSofistik = false; string sofistikPath = ""; bool iTeddy = false; bool AccessDatabase = false; DA.GetData(1, ref beamSplit); DA.GetData(3, ref iSofistik); DA.GetData(4, ref iTeddy); DA.GetData(5, ref AccessDatabase); if (!Directory.Exists(@"C:/Program Files/SOFiSTiK/2018/SOFiSTiK 2018")) { DA.GetData(6, ref sofistikPath); } if (AccessDatabase) { AccessSofistik.AccessSofData.Main(); } try { // Load the data from Karamba // Retrieve and clone the input model GH_Model in_gh_model = null; if (!DA.GetData <GH_Model>(0, ref in_gh_model)) { return; } Model model = in_gh_model.Value; model = (Karamba.Models.Model)model.Clone(); // If the model is not cloned a modification to this variable will imply modification of the input model, thus modifying behavior in other components. if (model == null) { status += "ERROR: The input model is null."; output = "Nothing to convert"; } else { string path = null; if (!DA.GetData <string>(2, ref path)) { path = ""; } if (path == "") { status += "No file path specified. Will not save data to a .dat file.\n"; filePath = path; } // Retrieve and store the data // Materials for (int i = 0; i < model.materials.Count; i++) { materials.Add(new Material(model.materials[i], i + 1)); } status += materials.Count + " materials loaded...\n"; // Cross sections for (int i = 0; i < model.crosecs.Count; i++) { crossSections.Add(new CrossSection(model.crosecs[i], i + 1)); } //Add beam ID's to crossections/materials/loads foreach (Karamba.Elements.ModelBeam beam in model.elems) { foreach (CrossSection crosec in crossSections) { if (beam.crosec.name == crosec.name) { crosec.ids.Add(beam.ind.ToString()); } } foreach (Material material in materials) { if (beam.crosec.material.name == material.name) { material.ids.Add(beam.ind.ToString()); } } } // Nodes foreach (Karamba.Nodes.Node node in model.nodes) { nodes.Add(new Node(node)); } status += nodes.Count + " nodes loaded...\n"; // Supports foreach (Karamba.Supports.Support support in model.supports) { nodes[support.node_ind].addConstraint(support); } status += "Support constraints added to " + model.supports.Count + " nodes.\n"; // Beams foreach (Karamba.Elements.ModelElement beam in model.elems) { Beam curBeam = new Beam(beam); // Adding the start and end nodes curBeam.start = nodes[curBeam.ids[0]]; curBeam.end = nodes[curBeam.ids[1]]; beams.Add(curBeam); } status += beams.Count + " beams loaded...\n"; // Loads foreach (KeyValuePair <int, Karamba.Loads.GravityLoad> load in model.gravities) { loads.Add(new Load(load)); } status += model.gravities.Count + " gravity loads added.\n"; foreach (Karamba.Loads.PointLoad load in model.ploads) { Load current = new Load(load); current.node = nodes[load.node_ind]; loads.Add(current); } status += model.ploads.Count + " point loads added.\n"; foreach (Karamba.Loads.ElementLoad load in model.eloads) { // Create a load variable base on the load type Load current = new Load(); Karamba.Loads.UniformlyDistLoad line = load as Karamba.Loads.UniformlyDistLoad; //Karamba.Loads.PreTensionLoad pret = load as Karamba.Loads.PreTensionLoad; Karamba.Loads.TemperatureLoad temp = load as Karamba.Loads.TemperatureLoad; //else if (pret != null) { // current = new Load(pret); //} //If there is not target element, apply the load to the whole structure if (load.beamIds[0] == "") { current.beam_id = ""; loads.Add(current); } else { // We search the element foreach (string beamid in load.beamIds) { if (line != null) { current = new Load(line); } // Very important to check Temperature BEFORE Pretension becaus Temperature derivates from Pretension else if (temp != null) { current = new Load(temp); } current.beam.user_id = beamid; current.beam_id = (beamid); loads.Add(current); } } } // ID matching // Karamba and Sofistik use different ID systems // Karamba's materials and cross sections are pointing to an element ID // Sofistik's elements need a cross section ID which needs a material ID foreach (Material material in materials) { // If the IDs list is empty, it means that we want to apply the material to the whole structure (whichi is the default behavior: the default material is set by the constructors of all elements) bool test = false; foreach (string id in material.ids) { if (id != "") { test = true; } } if (test) { foreach (CrossSection crosec in crossSections) { if (material.ids.Contains((crosec.id).ToString())) { crosec.material = material; } } } } status += "Matching with material IDs...\n"; foreach (CrossSection crosec in crossSections) { // If the IDs list is empty, it means that we want to apply the cross section to the whole structure (which is the default behavior: the default cross section is set by the constructors of all elements) bool test = false; foreach (string id in crosec.ids) { if (id != "") { test = true; } } if (test) { foreach (Beam beam in beams) { if (crosec.ids.Contains((beam.id - 1).ToString())) { beam.sec = crosec; } } } } status += "Matching with cross section IDs...\n"; // Write the data into a .dat file format Parser parser = new Parser(materials, crossSections, nodes, beams, loads); output = parser.file; if (path != "") { status += "Saving file to " + path + "\n"; System.IO.File.WriteAllText(@path, output); status += "File saved!\n"; } if (iSofistik == true && Directory.Exists(@"C:/Program Files/SOFiSTiK/2018/SOFiSTiK 2018") && path != "") { string targetPath = Path.GetFullPath(path); System.Diagnostics.Process process = new System.Diagnostics.Process(); System.Diagnostics.ProcessStartInfo startInfo = new System.Diagnostics.ProcessStartInfo(); startInfo.FileName = "cmd.exe"; startInfo.Arguments = "/k cd C:/Program Files/SOFiSTiK/2018/SOFiSTiK 2018/ & sps -B " + targetPath; process.StartInfo = startInfo; process.Start(); } else if (Directory.Exists(@"C:/Program Files/SOFiSTiK/2018/SOFiSTiK 2018") == false) { string targetPath = Path.GetFullPath(path); string sofPath = Path.GetFullPath(sofistikPath); System.Diagnostics.Process process = new System.Diagnostics.Process(); System.Diagnostics.ProcessStartInfo startInfo = new System.Diagnostics.ProcessStartInfo(); startInfo.FileName = "cmd.exe"; startInfo.Arguments = "/k cd " + sofPath + " & sps -B " + targetPath; process.StartInfo = startInfo; process.Start(); } if (iTeddy) { string targetPath = Path.GetFullPath(path); System.Diagnostics.Process process = new System.Diagnostics.Process(); System.Diagnostics.ProcessStartInfo startInfo = new System.Diagnostics.ProcessStartInfo(); startInfo.FileName = "cmd.exe"; startInfo.Arguments = "/c" + targetPath; process.StartInfo = startInfo; process.Start(); } } } catch (Exception e) { status += "\nERROR!\n" + e.ToString() + "\n" + e.Data; } Rhino.Collections.RhinoList <string> oBeamForces = new Rhino.Collections.RhinoList <string>(); foreach (string force in AccessSofistik.AccessSofData.SofBeamForces) { oBeamForces.Add(force.ToString()); } // Return data DA.SetData(0, output); DA.SetData(1, status); DA.SetDataList(2, AccessSofistik.AccessSofData.SofBeamForces); }
// This is the method that actually does the work. protected override void SolveInstance(IGH_DataAccess DA) { // Some variables string output = ""; // The file output string status = "Starting component...\n"; // The debug output // Several arrays where the data is stored List <Material> materials = new List <Material>(); List <CrossSection> crossSections = new List <CrossSection>(); List <Node> nodes = new List <Node>(); List <Beam> beams = new List <Beam>(); List <Load> loads = new List <Load>(); // We need to reset some variables because the objects are not freed until Grasshopper is unloaded Parser.id_count = 1; try { // Load the data from Karamba // Retrieve and clone the input model GH_Model in_gh_model = null; if (!DA.GetData <GH_Model>(0, ref in_gh_model)) { return; } Model model = in_gh_model.Value; model = (Karamba.Models.Model)model.Clone(); // If the model is not cloned a modification to this variable will imply modification of the input model, thus modifying behavior in other components. if (model == null) { status += "ERROR: The input model is null."; output = "Nothing to convert"; } else { string path = null; if (!DA.GetData <string>(1, ref path)) { path = ""; } if (path == "") { status += "No file path specified. Will not save data to a .dat file.\n"; } // Retrieve and store the data // Materials foreach (Karamba.Materials.FemMaterial material in model.materials) { // The first material seems to be wong but I don't know why it exists if (model.materials.IndexOf(material) != 0) { materials.Add(new Material(material)); } } /*Disabled for forward compatibility * // Check for material duplicates * // This is necessary because karamba uses a preset material that is added every time that a model is assembled * // As a consequence a model can get a great amount of redundant materials that will flood the output * * // Furthermore karamba seems to create a buggy material at index 0 during the cloning operation * materials.RemoveAt(0); * // Using a for loop because a collection used in foreach is immutable * for (int i = 0; i < materials.Count; i++) { * materials.RemoveAll(delegate(Material test_material) { * return test_material.id != materials[i].id && materials[i].duplicate(test_material); * }); * } */ status += materials.Count + " materials loaded...\n"; // Cross sections foreach (Karamba.CrossSections.CroSec crosec in model.crosecs) { crossSections.Add(new CrossSection(crosec)); } /*Disabled for forward compatibility * // The same happens with Cross Sections * crossSections.RemoveAt(0); * for (int i = 0; i < crossSections.Count; i++) { * crossSections.RemoveAll(delegate(CrossSection test_crosec) { * return test_crosec.id != crossSections[i].id && crossSections[i].duplicate(test_crosec); * }); * } * status += crossSections.Count + " cross sections loaded...\n"; */ // Nodes foreach (Karamba.Nodes.Node node in model.nodes) { nodes.Add(new Node(node)); } status += nodes.Count + " nodes loaded...\n"; foreach (Karamba.Supports.Support support in model.supports) { nodes[support.node_ind].addConstraint(support); } status += "Support constraints added to " + model.supports.Count + " nodes.\n"; // Beams foreach (Karamba.Elements.ModelElement beam in model.elems) { Beam curBeam = new Beam(beam); // Adding the start and end nodes curBeam.start = nodes[curBeam.ids[0]]; curBeam.end = nodes[curBeam.ids[1]]; beams.Add(curBeam); } status += beams.Count + " beams loaded...\n"; // Loads foreach (KeyValuePair <int, Karamba.Loads.GravityLoad> load in model.gravities) { loads.Add(new Load(load)); } status += model.gravities.Count + " gravity loads added.\n"; foreach (Karamba.Loads.PointLoad load in model.ploads) { Load current = new Load(load); current.node = nodes[load.node_ind]; loads.Add(current); } status += model.ploads.Count + " point loads added.\n"; foreach (Karamba.Loads.ElementLoad load in model.eloads) { // Create a load variable base on the load type Load current = new Load(); Karamba.Loads.UniformlyDistLoad line = load as Karamba.Loads.UniformlyDistLoad; Karamba.Loads.PreTensionLoad pret = load as Karamba.Loads.PreTensionLoad; Karamba.Loads.TemperatureLoad temp = load as Karamba.Loads.TemperatureLoad; if (line != null) { current = new Load(line); } // Very important to check Temperature BEFORE Pretension becaus Temperature derivates from Pretension else if (temp != null) { current = new Load(temp); } else if (pret != null) { current = new Load(pret); } // If there is not target element, apply the load to the whole structure if (load.beamId == "") { current.beam_id = ""; loads.Add(current); } else { // We search the element current.beam = beams.Find(delegate(Beam beam) { return(beam.user_id == load.beamId); }); loads.Add(current); } } status += model.eloads.Count + " line loads added.\n"; // ID matching // Karamba and Sofistik use different ID systems // Karamba's materials and cross sections are pointing to an element ID // Sofistik's elements need a cross section ID which needs a material ID foreach (Material material in materials) { // If the IDs list is empty, it means that we want to apply the material to the whole structure (whichi is the default behavior: the default material is set by the constructors of all elements) bool test = false; foreach (string id in material.ids) { if (id != "") { test = true; } } if (test) { foreach (CrossSection crosec in crossSections) { if (material.ids.Contains((crosec.id - 1).ToString())) { crosec.material = material; } } } } status += "Matching with material IDs...\n"; foreach (CrossSection crosec in crossSections) { // If the IDs list is empty, it means that we want to apply the cross section to the whole structure (which is the default behavior: the default cross section is set by the constructors of all elements) bool test = false; foreach (string id in crosec.ids) { if (id != "") { test = true; } } if (test) { foreach (Beam beam in beams) { if (crosec.ids.Contains((beam.id - 1).ToString())) { beam.sec = crosec; } } } } status += "Matching with cross section IDs...\n"; // Write the data into a .dat file format Parser parser = new Parser(materials, crossSections, nodes, beams, loads); output = parser.file; if (path != "") { status += "Saving file to " + path + "\n"; System.IO.File.WriteAllText(@path, output); status += "File saved!\n"; } } } catch (Exception e) { status += "\nERROR!\n" + e.ToString() + "\n" + e.Data; } // Return data DA.SetData(0, output); DA.SetData(1, status); }