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.