> For the complete documentation index, see [llms.txt](https://scripting-2.karamba3d.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://scripting-2.karamba3d.com/2.-scripting/2.3-how-to-create-structural-models.md).

# 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\]](/bibliography.md) 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.](/files/-MXH_8YK8Xgq4TshBhlr)

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

```csharp
...
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.

{% file src="/files/72gYsWmAQddnfgZ9DJDL" %}
