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.2: Activation and Deactivation of Elements

Previous2.4.1: Cross section OptimizationNext2.5: Data Export from Karamba3D

Last updated 6 months ago

The example “ActivationDeactivationOfElements.gh” features a simplified version of Karamba3D’s “Tension/Compression Eliminator”-component. It repeatedly evaluates a structure and removes all elements with tensile normal force. Starting from an arbitrary structural model the script iteratively removes those elements which are under tension (see fig. 2.4.2.1).


#region Usings
using System;

#r "C:\Program Files\Rhino 8\Plug-ins\Karamba\KarambaCommon.dll"
#r "C:\Program Files\Rhino 8\Plug-ins\Karamba\Karamba.gha"

using System.Linq;
using System.Collections;
using System.Collections.Generic;
using System.Drawing;

using Rhino;
using Rhino.Geometry;

using Grasshopper;
using Grasshopper.Kernel;
using Grasshopper.Kernel.Data;
using Grasshopper.Kernel.Types;

using Karamba.Models;
using Karamba.GHopper.Models;
using Karamba.Utilities;
using Karamba.Loads.Combination;
using Karamba.Elements.States.Selectors;
using Karamba.Geometry;

#endregion

public class Script_Instance : GH_ScriptInstance
{
    private void RunScript(
	object Model_in,
	int maxiter,
	ref object Model_out,
	ref object isActive,
	ref object maxDisp)
    {
        var k3d = new KarambaCommon.Toolkit();
        IReadOnlyList<double> max_disp;
        IReadOnlyList<Vector3> out_force;
        IReadOnlyList<double> out_energy;
        string warning;

        var model = Model_in as Model;
        if (model == null) {
            throw new ArgumentException("The input in 'Model_in' is not of type karamba.Models.Model!");
        }

        // load case to consider for elimination of elements
        string lcName = "LC0";
        // get load-case combination
        LoadCaseCombination lcc;
        model.lcActivation.TryGetLoadCaseCombination(lcName, out lcc);
        // select load case 0 of load-case combination "LC0"
        var stateSelector = new StateElement1DSelectorIndex(model, lcc, 0);

        // clone the model and its list of elements to avoid side effects
        model = model.Clone();
        // clone its elements to avoid side effects
        model.cloneElements();

        // do the iteration and remove elements with tensile axial forces
        for (int iter = 0; iter < maxiter; iter++) {

            // create a deform and response object for calculating and retrieving results
            model = k3d.Algorithms.Analyze(model, new List<string>(){lcName}, out max_disp, out out_force, out out_energy, out warning);

            // check the normal force of each element and deactivate those under tension
            double N, V, M;
            bool has_changed = false;
            foreach (Karamba.Elements.ModelElement elem in model.elems) {
                // retrieve resultant cross section forces
                elem.resultantCroSecForces(model, stateSelector, 0.3, 3, out N, out V, out M);

                // check whether normal force is tensile
                if (N > 0) {
                    // set element inactive
                    elem.set_is_active(model, false);
                    has_changed = true;
                }
            }

            // leave iteration loop if nothing changed
            if (!has_changed) break;

            // rebuild the C++ model
            model.buildFEModel();
        }

        // update model to its final state
        model = k3d.Algorithms.Analyze(model, new List<string>(){lcName}, out max_disp, out out_force, out out_energy, out warning);

        // set up list of true/false values that corresponds to the elemment states
        List<bool> elem_activity = new List<bool>();
        foreach (var elem in model.elems) {
            elem_activity.Add(elem.IsActive);
        }

        isActive = elem_activity;
        maxDisp = max_disp;
        Model_out = new GH_Model(model);

        Print("Everything OK");
    }
}
```

At the beginning of the script, the input variable Model_in is type-cast to Karamba.Models.Model. If the provided object does not match the expected type, an ArgumentException is thrown.

The load case name is fixed as "LC0" in line 51. The associated LoadCaseCombination object is retrieved from the model in line 54 and utilized in line 56 to create a result selector. This selector extracts the first (and only) load-case item of the load-case combination. In Karamba3D, a load case is equivalent to a load-case combination containing a single load-case item.

To prevent side effects, data must be copied before any modifications occur. Line 59 performs this operation for the Karamba3D model. Since the model contains references to objects, these objects must also be copied. The element activation state is modified within the script, so the list referencing these elements is copied as shown in line 61.

The model is analyzed repeatedly for the specified load-case combination "LC0" in line 67.

In lines 72–82, the algorithm iterates through all elements in the system, extracts their resultant section forces, and deactivates any members under tension (where N ≥0).

The loop terminates when no further changes are detected (line 85) or when the maximum number of iterations is reached. At this point, the model is updated one final time.

An iteration over all elements generates a list of boolean values corresponding to their activation states (lines 96–98). This list is assigned to the output variable in line 100. Finally, line 102 wraps the model containing the final results in a GH_Model wrapper object.

33KB
ActivationDeactivationOfElements_GH7.gh
30KB
ActivationDeactivationOfElements_GH8.gh
Fig. 2.4.2.1: From the initial truss only those elements without tensile forces survive.