2.4.2: Activation and Deactivation of Elements
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. In the source-code one finds an alternative approach to changing model properties as compared to the above example. Starting from an arbitrary structural model the script iteratively removes those elements which are under tension (see fig. 2.4.2.1). In order to improve computational efficiency model-modifications occur on the level of the C++ model. This spares the C++ model creation, however introduces additional complexity with regards to model-handling.
Fig. 2.4.2.1: From the initial truss only those elements without tensile forces survive.
1
...
2
using Karamba.Models;
3
using Karamba.GHopper.Models;
4
using Karamba.Loads.Combinations;
5
...
6
private void RunScript(object Model_in, int maxiter, ref object Model_out, ref object isActive, ref object maxDisp)
7
{
8
var model = Model_in as Model;
9
if (model == null) {
10
throw new ArgumentException("The input in 'Model_in' is not of type karamba.Models.Model!");
11
}
12
13
// load case to consider for elimination of elements
14
int lc_num = 0;
15
16
// clone the model and its list of elements to avoid side effects
17
model = model.Clone();
18
// clone its elements to avoid side effects
19
model.cloneElements();
20
// clone the feb-model to avoid side effects
21
model.deepCloneFEModel();
22
23
string singular_system_msg = "The stiffness matrix of the system is singular.";
24
25
// do the iteration and remove elements with tensile axial forces
26
for (int iter = 0; iter < maxiter; iter++) {
27
28
// create a deform and response object for calculating and retrieving results
29
feb.Deform deform = new feb.Deform(model.febmodel);
30
feb.Response response = new feb.Response(deform);
31
32
try
33
{
34
// calculate the displacements
35
response.updateNodalDisplacements();
36
// calculate the member forces
37
response.updateMemberForces();
38
}
39
catch
40
{
41
// send an error message in case something went wrong
42
throw new Exception(singular_system_msg);
43
}
44
45
// check the normal force of each element and deactivate those under tension
46
double N, V, M;
47
bool has_changed = false;
48
foreach (Karamba.Elements.ModelElement elem in model.elems) {
49
// retrieve resultant cross section forces
50
elem.resultantCroSecForces(model, new LCSuperPosition(lc_num, model),
51
out N, out V, out M);
52
// check whether normal force is tensile
53
if (N >= 0) {
54
// set element inactive
55
elem.set_is_active(model, false);
56
has_changed = true;
57
}
58
}
59
60
// leave iteration loop if nothing changed
61
if (!has_changed) break;
62
63
// if something changed inform the feb-model about it (otherwise it won't recalculate)
64
model.febmodel.touch();
65
66
// this guards the objects from being freed prematurely
67
GC.KeepAlive(deform);
68
GC.KeepAlive(response);
69
}
70
71
// update model to its final state
72
try
73
{
74
// create a deform and response object for calculating and retrieving results
75
feb.Deform deform = new feb.Deform(model.febmodel);
76
feb.Response response = new feb.Response(deform);
77
78
// calculate the displacements
79
response.updateNodalDisplacements();
80
// calculate the member forces
81
response.updateMemberForces();
82
83
maxDisp = response.maxDisplacement();
84
85
// this guards the objects from being freed prematurely
86
GC.KeepAlive(deform);
87
GC.KeepAlive(response);
88
}
89
catch
90
{
91
// send an error message in case something went wrong
92
throw new Exception(singular_system_msg);
93
}
94
95
// set up list of true/false values that corresponds to the elemment states
96
List<bool> elem_activity = new List<bool>();
97
foreach (var elem in model.elems) {
98
elem_activity.Add(elem.IsActive);
99
}
100
101
isActive = elem_activity;
102
Model_out = new GH_Model(model);
103
104
Print("Everything OK");
105
}
Copied!
As usual at the beginning of the above script the input variable “Model_in” gets type-cast to “Karamba.Models.Model”. In case the supplied object does not fit an “ArgumentException” gets thrown.
The index of the load case to consider is hard-wired to “0” in line 13. In order to avoid side-effects, the data needs to be copied before any modifications take place. Line 16 effects this for the Karamba3D- model. Since the model-object itself contains objects these need to be copied as well. Since the script changes the element’s activation state, the list referencing them needs to be copied as done in line 18. The same is true for the C++-model which gets cloned in line 20.
The C++ model contains all the predefined data like geometry, materials, supports, loads, and the like. It lives in the “feb”-namespace which stands for finite element basis. In order to perform an analysis on it, one needs to configure a corresponding object. In line 28 a simple “Deform” object gets created which calculates static deflections. A response object lets you query the analysis for results. It gets created in line 29. One has to make sure that a new set of Deform- and Response-objects is created for every new state of the model. This is the reason why their creation occurs inside the loop for changing the activation state of the model elements.
Lines 34 and 36 contain the calls for calculating the model displacements and cross section forces. In case the system can not be evaluated (e.g. due to being kinematic) an exception will fly.
In lines 47 to 56 the algorithm iterates over all elements in the system, reads out their resultant section forces and sets all members inactive that are under tension (N0). The “set_is_active” method sets the “is_active”-flag both in the C#-model and the C++-model. If properties get only changed in the C#-model the C++-model gets out of sync and thus would calculate a wrong structure. A way to avoid this would be to rebuild the C++-model completely from the C#-model (as demonstrated in the previous section) after having changed the latter. As this step can be time-consuming it is better avoided whenever possible.
Each time the C++-model changes it needs to be made aware of that. In order to invalidate its state, the “touch()”-function gets invoked. When leaving out this command the C++-model will not recalculate in the next iteration as it assumes that its results from the previous cycle are still valid.
As soon as there are no more changes (line 59) or the maximum number of iterations is reached the program leaves the loop and the model gets updated for a last time.
The “GC.KeepAlive” commands in lines 84 and 85 make sure that the automatic garbage collection in C# does not prematurely free the “deform” and “response” objects. As “deform” is internally referenced by “response” freeing the former object would lead to a dangling pointer and undefined behavior “response”.
An iteration over all elements creates a list of boolean values that corresponds to their activation state(lines 94 to 97). In line 99 this list is handed over to the output variable. Line 100 puts a GH_Model wrapper object around the model-object that contains the final results.
In line 81 the response object is queried for the maximum deflection in the model. Its value is then handed over to the “maxDisp” output variable.
ActivationDeactivationOfElements.gh
23KB
Binary
Last modified 16d ago
Copy link