3.5: Adding Functionality to a GH Component
protected override void SolveInstance(IGH_DataAccess DA)
{
GH_Model in_gh_model = null;
if (!DA.GetData<GH_Model>(0, ref in_gh_model)) return;
var model = in_gh_model.Value;
// maximum number of iterations
int max_iter = 10;
DA.GetData<int>(1, ref max_iter);
// load case to consider for elimination of elements
int lc_num = 0;
// clone model to avoid side effects
model = (Karamba.Models.Model)model.Clone();
// clone its elements to avoid side effects
model.cloneElements();
// clone the feb-model to avoid side effects
model.deepCloneFEModel();
string singular_system_msg = "The stiffness matrix of the system is singular.";
// do the iteration and remove elements with tensile axial forces
for (int iter = 0; iter < max_iter; iter++)
{
// create an analysis and response object for calculating and retrieving results
feb.Deform analysis = new feb.Deform(model.febmodel);
feb.Response response = new feb.Response(analysis);
try
{
// calculate the displacements
response.updateNodalDisplacements();
// calculate the member forces
response.updateMemberForces();
}
catch
{
// send an error message in case something went wrong
throw new Exception(singular_system_msg);
}
// check the normal force of each element and deactivate those under tension
double N, V, M;
bool has_changed = false;
foreach (var elem in model.elems)
{
// retrieve resultant cross section forces
elem.resultantCroSecForces(model, new LCSuperPosition(lc_num, model),
out N, out V, out M);
// check whether normal force is tensile
if (!(N >= 0)) continue;
// set element inactive
elem.set_is_active(model, false);
has_changed = true;
}
// leave iteration loop if nothing changed
if (!has_changed) break;
// if something changed inform the feb-model about it (otherwise it won't recalculate)
model.febmodel.touch();
// this guards the objects from being freed prematurely
GC.KeepAlive(analysis);
GC.KeepAlive(response);
}
// update model to its final state
double max_disp = 0;
try
{
// create an analysis and response object for calculating and retrieving results
feb.Deform analysis = new feb.Deform(model.febmodel);
feb.Response response = new feb.Response(analysis);
// calculate the displacements
response.updateNodalDisplacements();
// calculate the member forces
response.updateMemberForces();
max_disp = response.maxDisplacement();
// this guards the objects from being freed prematurely
GC.KeepAlive(analysis);
GC.KeepAlive(response);
}
catch
{
// send an error message in case something went wrong
throw new Exception(singular_system_msg);
}
// set up list of true/false values that corresponds to the element states
List<bool> elem_activity = new List<bool>();
foreach (var elem in model.elems)
{
elem_activity.Add(elem.IsActive);
}
DA.SetData(0, new GH_Model(model));
DA.SetDataList(1, elem_activity);
DA.SetData(2, max_disp);
}
Last updated