2.3: How to Create Structural Models

Karamba3D-components are split in two parts: one manages the graphical user interface, unit conversions and default values, the other handles the functionality.

Let’s take the “LineToBeam”-component as an example:

  • The class “Component_LineToBeam_GUI” in namespace “Karamba.GHopper.Elements” derives from Grasshopper’s “GH_Component” and provides the visual component properties.

  • “LineToBeam”, a static class in namespace “Karamba.Elements” features the static method “solve(...)” which executes the actual tasks and gets used by “Component_LineToBeam_GUI”.

Generally the names of classes which belong to the GUI start with “Component” and belong to the namespace “Karamba.GHopper”. Since there are static solve-methods for all components it would be possible to build a model using only these. This would entail two disadvantages:

  • The solve-methods do not provide default values for their arguments, so one has to provide them explicitly.

  • In later versions of Karamba3D the order and number of arguments of the solve-methods might change.

One way to mitigate these problems is to refrain from direct object creation and use a factory-pattern instead. See [2] for further information on this topic. In the script below a structural model gets assembled and output: it consists of a vertical cantilever-beam with a point-load on top (see fig. 2.3.1).

Fig. 2.3.1: A model can be created from scratch using a C# script.

This is the source-code inside the C#-component (see example “ModelCreation.gh”):

using Karamba.Utilities;
using Karamba.Geometry;
using Karamba.CrossSections;
using Karamba.Supports;
using Karamba.Loads;
private void RunScript(ref object Model_out)
var logger = new MessageLogger();
var k3d = new KarambaCommon.Toolkit();
var p0 = new Point3(0, 0, 0);
var p1 = new Point3(0, 0, 5);
var L0 = new Line3(p0, p1);
var nodes = new List<Point3>();
var elems = k3d.Part.LineToBeam(new List<Line3>(){L0}, new List<string>(){ "B1" },
new List<CroSec>(), logger, out nodes);
var cond = new List<bool>(){ true, true, true, true, true, true};
var support = k3d.Support.Support(0, cond);
var supports = new List<Support>(){support};
var pload = k3d.Load.PointLoad(1, new Vector3(0, 0, -10), new Vector3());
var ploads = new List<Load>(){pload};
double mass;
Point3 cog;
bool flag;
string info;
var model = k3d.Model.AssembleModel(elems, supports, ploads,
out info, out mass, out cog, out info, out flag);
// calculate Th.I response
List<double> max_disp;
List<double> out_g;
List<double> out_comp;
string message;
model = k3d.Algorithms.AnalyzeThI(model, out max_disp, out out_g, out out_comp, out message);
var ucf = UnitsConversionFactories.Conv();
UnitConversion cm = ucf.cm();
Print("max disp: " + cm.toUnit(max_disp[0]) + cm.unitB);
Model_out = new Karamba.GHopper.Models.GH_Model(model);

As a means of reporting problems a “logger”-objects gets instantiated in line 10. This class limits the amount of text to a preset maximum so that in case of multiple errors the log-file does not grow without limits. Next comes the factory “k3d” which further on serves as the main hub of object creation. The classes “Point3” and “Line3” represent the Karamba3D equivalent of Grasshopper’s “Point3d” and “Line”. Their instantiations “p0”, “p1” and “L0” make up the model’s geometry. In line 19 the k3d-factory creates a list of objects of type “BuilderBeam” – with one entry in this case. This is not yet an element which forms part of a model – this would be “ModelBeam”. It rather represents a recipe for creating them. This concept applies to all elements in Karamba3D: Via the assemble-step objects of type “BuilderBeam” or “BuilderShell” produce “ModelBeams”-, “ModelTruss”-, “ModelSpring” and “ModelShell”-objects which form part of the C# structural model. What the user sees as “Element” in the Grasshopper GUI are the element-builders not the model-elements. Since C# structural models can be disassembled and reassembled the model-elements need to keep a reference to their builder-elements. This is achieved via the protected property “builder_element”.

The creation of supports and loads works similarly as for the element-builder. In Line 33 follows the model-assemble step, in line 41 the first order theory calculation of the model-response.

User defined objects that get piped through grasshopper definitions need to be wrapped: In line 47 a GH_Model wrapper object is created from the model-object that contains the final results. Similar wrapper classes exist for all Karamba3D entities that can populate a Grasshopper definition. Their names start with “GH_” which makes them easy to find.