Scripting Guide 3.1.4
  • Welcome to Karamba3D Scripting Guide
  • 1. Introduction
    • 1.1: Scripting with Karamba3D
    • 1.2: Basics
  • 2. Scripting with Karamba3D inside Grasshopper
    • 2.1: Hello Karamba3D
    • 2.2: Data Retrieval from Models
    • 2.3: How to Create Structural Models
    • 2.4: How to Modify Structural Models
      • 2.4.1: Cross section Optimization
      • 2.4.2: Activation and Deactivation of Elements
    • 2.5: Data Export from Karamba3D
    • 2.6: The VB Script Component
    • 2.7: The IronPython Component
      • 2.7.1: Results Retrieval on Shells
      • 2.7.2: A Simplified ESO-Procedure on Shells
    • 2.8: The Python 3 Component
      • 2.8.1: Hello Karamba3D
      • 2.8.2: Data Retrieval from Models
      • 2.8.3: How to Create Structural Models
      • 2.8.4: How to Modify Structural Models
        • 2.8.4.1: Cross section Optimization
        • 2.8.4.2: Activation and Deactivation of Elements
  • 3. How to create your own Karamba3D Grasshopper-component
    • 3.1: Setting up a Visual Studio Project for GH Plug-ins
    • 3.2: Basic Component Setup
    • 3.3: How to Reference Karamba3D Assemblies
    • 3.4: Input- and Output-Plugs
    • 3.5: Adding Functionality to a GH Component
  • Bibliography
Powered by GitBook
On this page
  1. 2. Scripting with Karamba3D inside Grasshopper
  2. 2.4: How to Modify Structural Models

2.4.1: Cross section Optimization

Previous2.4: How to Modify Structural ModelsNext2.4.2: Activation and Deactivation of Elements

Last updated 6 months ago

When it comes to modifying an existing Karamba3D model keep to these general rules:

  • In order to avoid side-effects, clone objects before modifying them. This applies recursively to the objects which contain objects to be modified.

  • The Karamba3D API for modifications allows for changes which can make the C++-model crash. So make it a habit to regularly save your work.

The example “CrossSectionOptimization.gh” (see fig. 2.4.1.1) shows how to optimize beam cross sections under arbitrary loads. The C#-component takes a model and an ordered list of cross sections as the main input, chooses the optimum cross sections according to the given cross section forces and outputs the optimized model as well as its maximum displacement. The input-plug “niter” lets one chose the number of iteration steps. Each consists of model evaluation and cross section selection. With “lcName” the name of a load-case to be considered for cross section optimization can be selected. The algorithm inside the component neglects buckling and calculates the maximum stress in the cross section based on the assumption that there are only normal forces and bending moments about the local Y-axis.

...
using Karamba.Models;
using Karamba.CrossSections;
using Karamba.Elements;
using Karamba.Results;
using Karamba.Geometry;
...
private void RunScript(
	object Model_in,
	List<object> CroSecs_in,
	int niter,
	string lcName,
	ref object Model_out,
	ref object Disp_out)
    {
        var model = Model_in as Model;
        if (model == null) {
          throw new ArgumentException("The input in 'Model_in' is not of type Karamba.Models.Model!");
        }

        var crosecs = new List<CroSec_Beam>(CroSecs_in.Count);
        foreach (var item in CroSecs_in) {
            var crosec = item as CroSec_Beam;
            if (crosec == null) {
                throw new ArgumentException("The input in 'CroSecs_in' contains objects which are not of type Karamba.CrossSections.CroSec_Beam!");
            }
            crosecs.Add(crosec);
        }

        var k3d = new KarambaCommon.Toolkit();
        IReadOnlyList<double> max_disp;
        IReadOnlyList<Vector3> out_force;
        IReadOnlyList<double> out_energy;
        string warning;
        List<List<double>> N;
        List<List<double>> V;
        List<List<double>> M;

        // avoid side effects
        model = model.Clone();
        model.cloneElements();

        for (int i = 0; i < niter; ++i) 
        {
            model = k3d.Algorithms.Analyze(model, new List<string>(){lcName}, out max_disp, out out_force, out out_energy, out warning);

            for (int elem_ind = 0; elem_ind < model.elems.Count; ++elem_ind) {
                var beam = model.elems[elem_ind] as ModelBeam;
                if (beam == null) continue;

                // avoid side effects
                beam = (ModelBeam) beam.Clone();
                model.elems[elem_ind] = beam;

                BeamResultantForces.solve(model, new List<string> {"" + elem_ind}, lcName, 100, 1,
                    out N, out V, out M);

                for (int crosec_ind = 0; crosec_ind < crosecs.Count; ++crosec_ind) {
                    var crosec = crosecs[crosec_ind];
                    beam.crosec = crosec;
                    var max_sigma = Math.Abs(N[0][0]) / crosec.A + M[0][0] / crosec.Wely_z_pos;
                    if (max_sigma < crosec.material.ft()) break;
                }
            }

            model.initMaterialCroSecLists();
            model.buildFEModel();
        }

        model = k3d.Algorithms.Analyze(model, new List<string>(){lcName}, out max_disp, out out_force, out out_energy, out warning);

        Disp_out = new GH_Number(max_disp[0]);

        Model_out = new Karamba.GHopper.Models.GH_Model(model);
    }

Here the detailed account of the above algorithm:

1. Input Type Validation

  • The first two blocks of code check the data types of the Model_in and CroSecs_in inputs. This ensures the inputs are valid and compatible with subsequent operations.

2. Object Instantiations

  • The third code section initializes objects that are required later during the iterative optimization loop. These objects facilitate efficient data handling and manipulation.

3. Reference Management in C#:

  • In C#, assigning an object to a variable actually assigns a reference. This means changes made to the object are reflected in all variables that reference it.

  • This behavior conflicts with Grasshopper’s data flow logic, where objects should only be influenced by upstream operations.

  • To prevent unintended data flow and ensure independent object manipulation:

    • Clone the model using model = model.Clone();.

    • Clone the model's elements with model.cloneElements();.

4. Optimization Loop

  • The main optimization loop performs the following steps:

    1. System Response Calculation:

      • At the start of each iteration, the structural response is calculated.

    2. Beam Element Handling:

      • All elements in the model are checked to identify beam elements.

      • Beam elements are cloned to avoid side effects and re-added to the model.

    3. Cross Section Forces Calculation:

      • The resultant forces for each beam’s cross section are determined using BeamResultantForces.solve.

      • Alternatively, Karamba.Results.BeamForces.solve() could be used for more complex scenarios, such as considering bi-axial bending.

    4. Cross Section Selection:

      • The loop iterates through the user-provided list of cross sections.

      • An appropriate cross section is selected by comparing the maximum stress in the cross section with the material's strength.

    5. Model Update:

      • After selecting cross sections, the model's lists of cross sections and materials are re-initialized.

      • The C++ model, which the C# model relies on for result evaluation, is recreated.

5. Finalization

  • Before the model is passed to the output plug:

    • An analysis step updates the structural response.

    • The maximum displacement of the model is determined.

6. Potential Improvements

  • The script is kept simple for clarity, but it can be enhanced in several ways:

    • Stop Criteria: Implementing a mechanism to terminate the optimization loop when convergence is reached.

    • Advanced Design Procedures: Incorporating more detailed methods to evaluate the load-bearing capacity of elements.

    • Enhanced Analysis: Including additional considerations such as buckling or multi-axis forces for more robust designs.

This structured approach to code ensures clarity and minimizes unintended interactions between components, making the process easier to follow and adapt for complex scenarios.

41KB
CrossSectionOptimization_RH7.gh
44KB
CrossSectionOptimization_RH8.gh
Fig. 2.4.1.1: Modification of cross sections.