/// <summary>
        /// This is the method that actually does the work.
        /// </summary>
        /// <param name="DA">The DA object can be used to retrieve data from input parameters and
        /// to store data in output parameters.</param>
        protected override void SolveInstance(IGH_DataAccess DA, EvaluationUnit unit)
        {
            // RFEM variables
            var        modelName = "";
            IModel     model     = null;
            IModelData data      = null;

            //Additional variables
            var dicMat  = new Dictionary <int, Material>();
            var dicMass = new Dictionary <int, List <double> >();
            var dicVol  = new Dictionary <int, List <double> >();
            var dicGeo  = new Dictionary <int, List <Brep> >();

            // Input
            var msg  = "";
            var msgs = new List <string>();
            var run  = false;

            DA.GetData(0, ref run);


            if (run)
            {
                if (!DA.GetData(1, ref modelName))
                {
                    Component_GetData.ConnectRFEM(ref model, ref data);
                }
                else
                {
                    Component_GetData.ConnectRFEM(modelName, ref model, ref data);
                }
                _materials.Clear();
                _massTree.Clear();
                _volumeTree.Clear();
                _brepTree.Clear();
                try
                {
                    // Get Surfaces
                    var sfcs = Component_GetData.GetRFSurfaces(data.GetSurfaces().ToList(), data);
                    foreach (var sfc in sfcs)
                    {
                        // Add material to dictionary
                        if (!dicMat.ContainsKey(sfc.MaterialNo))
                        {
                            dicMat.Add(sfc.MaterialNo, data.GetMaterial(sfc.MaterialNo, ItemAt.AtNo).GetData());
                            dicMass.Add(sfc.MaterialNo, new List <double>());
                            dicVol.Add(sfc.MaterialNo, new List <double>());
                            dicGeo.Add(sfc.MaterialNo, new List <Brep>());
                        }
                        // Add mass to output list
                        dicVol[sfc.MaterialNo].Add(sfc.Area * sfc.Thickness);
                        dicMass[sfc.MaterialNo].Add(sfc.Area * sfc.Thickness * dicMat[sfc.MaterialNo].SpecificWeight / 10.0);

                        // Add Geometry to output list
                        dicGeo[sfc.MaterialNo].Add(sfc.ToBrep());
                    }
                    // Get Members
                    var members    = Component_GetData.GetRFMembers(data.GetMembers().ToList(), data);
                    var crosecs    = Component_GetData.GetRFCroSecs(data.GetCrossSections().ToList(), model, ref msgs);
                    var cs_indeces = crosecs.Select(x => x.No).ToList();
                    foreach (var member in members)
                    {
                        var mat_index = crosecs.Where(x => x.No == member.StartCrossSectionNo).ToList()[0].MatNo;


                        // Add material to dictionary
                        if (!dicMat.ContainsKey(mat_index))
                        {
                            dicMat.Add(mat_index, data.GetMaterial(mat_index, ItemAt.AtNo).GetData());
                            dicMass.Add(mat_index, new List <double>());
                            dicVol.Add(mat_index, new List <double>());
                            dicGeo.Add(mat_index, new List <Brep>());
                        }

                        // Add mass to output list
                        if (member.EndCrossSectionNo == 0) // In case of tension members, etc.
                        {
                            member.EndCrossSectionNo = member.StartCrossSectionNo;
                        }
                        if (!(cs_indeces.Contains(member.StartCrossSectionNo)) || (!(cs_indeces.Contains(member.EndCrossSectionNo))))
                        {
                            AddRuntimeMessage(GH_RuntimeMessageLevel.Warning, $"Provide cross sections for member No {member.No}.");
                            continue;
                        }
                        var startCroSec = crosecs[cs_indeces.IndexOf(member.StartCrossSectionNo)];
                        var endCroSec   = crosecs[cs_indeces.IndexOf(member.EndCrossSectionNo)];
                        var volume      = (startCroSec.A + endCroSec.A) / 2 * member.Length;
                        dicVol[mat_index].Add(volume);
                        dicMass[mat_index].Add(member.Weight);

                        // Add Geometry to output list
                        var memberShape = Component_ExtrudeMembers.ExtrudeMembersToBrep(member, crosecs, member.Length / 8.0, out msg);
                        if (memberShape == null)
                        {
                            dicGeo[mat_index].Add(null);
                        }
                        else
                        {
                            dicGeo[mat_index].Add(memberShape[0]);
                        }
                    }
                    // Prepare Output
                    var matSorted = dicMat.Values.OrderBy(x => x.No).ToList();
                    _materials = matSorted.Select(x => x.Description).ToList();
                    for (int i = 0; i < matSorted.Count; i++)
                    {
                        var path = new GH_Path(i);
                        _volumeTree.EnsurePath(path);
                        _volumeTree.Branch(path).AddRange(dicVol[matSorted[i].No]);
                        _massTree.EnsurePath(path);
                        _massTree.Branch(path).AddRange(dicMass[matSorted[i].No]);
                        _brepTree.EnsurePath(path);
                        _brepTree.Branch(path).AddRange(dicGeo[matSorted[i].No]);
                    }
                }
                catch (Exception ex)
                {
                    Component_GetData.DisconnectRFEM(ref model, ref data);
                    _materials.Clear();
                    _massTree.Clear();
                    _volumeTree.Clear();
                    _brepTree.Clear();
                    throw ex;
                }
                Component_GetData.DisconnectRFEM(ref model, ref data);
                if (msgs.Count > 0)
                {
                    AddRuntimeMessage(GH_RuntimeMessageLevel.Warning, String.Join(System.Environment.NewLine, msg.ToArray()));
                }
                if (msg != "")
                {
                    AddRuntimeMessage(GH_RuntimeMessageLevel.Warning, msg);
                }
            }
            DA.SetDataList(0, _materials);
            DA.SetDataTree(1, _brepTree);
            DA.SetDataTree(2, _massTree);
            DA.SetDataTree(3, _volumeTree);
        }