2.4.2: Activation and Deactivation of Elements
Last updated
Last updated
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.
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 (N ≥0). 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.