public void Opt(ref double[] q, ref List <Point3d> gp, ref List <Curve> tp, ref List <Curve> sp, ref List <int> lp, ref List <Vector3d> lv, ref double[] cs, ref double compliance, ref double[] rfload, ref int seed)
        {
            FDMinput.Input(ref gp, ref tp, ref sp, ref lp, ref lv, ref fix, ref free, ref Pfix, ref C, ref istart, ref iend, ref rfload);
            uint nm = (uint)tpinit.Count;

            //FDMfunc.Sens(ref q, ref gp, ref tp, ref lp, ref cs, ref compliance, ref rfload, ref fix, ref free, ref Pfix, ref C, ref istart, ref iend, ref scompliance, ref srfload);

            using (var solver = new NLoptSolver(NLoptAlgorithm.LD_SLSQP, nm, .1e-5, 100))
            {
                var qmin = new double[nm];
                for (int i = 0; i < nm; i++)
                {
                    qmin[i] = q[i] - .1e3;
                }
                var qmax = new double[nm];
                for (int i = 0; i < nm; i++)
                {
                    qmax[i] = q[i] + .1e3;
                }
                solver.SetLowerBounds(qmin);
                solver.SetUpperBounds(qmax);


                solver.SetMinObjective(SObjFun);

                solver.AddEqualZeroConstraint(sConFun0, .1e-5);
                solver.AddEqualZeroConstraint(sConFun1, .1e-5);

                Random Random = new Random(seed);
                for (int i = 0; i < nm; i++)
                {
                    q[i] += (Random.NextDouble() - 0.5) * 10;
                }

                double?finalScore = 0;
                var    result     = solver.Optimize(q, out finalScore);

                FDMfunc.Sens(ref q, ref gp, ref tp, ref lp, ref cs, ref compliance, ref rfload, ref fix, ref free, ref Pfix, ref C, ref istart, ref iend, ref scompliance, ref srfload);
                Console.WriteLine("============================================");
                Console.WriteLine(result);
                for (int i = 0; i < nm; i++)
                {
                    Console.WriteLine("q[{0}]={1}", i, q[i]);
                }
                Console.WriteLine("compliance={0}", compliance);
                Console.WriteLine("rfload[0]={0}", rfload[0]);
                Console.WriteLine("rfload[1]={0}", rfload[1]);
            }
        }
        /// <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)
        {
            if (iterating == 0)
            {
                if (!DA.GetDataList(0, gpinit))
                {
                    return;
                }
                if (!DA.GetDataList(1, tpinit))
                {
                    return;
                }
                if (!DA.GetDataList(2, spinit))
                {
                    return;
                }
                if (!DA.GetDataList(3, lpinit))
                {
                    return;
                }
                if (!DA.GetDataList(4, lvinit))
                {
                    return;
                }

                ///make HARD copy where original and copy are independent
                //gp = new List<Point3d>();
                foreach (Point3d p in gpinit)
                {
                    gp.Add(new Point3d(p));
                }

                //tp = new List<Curve>();
                foreach (Curve c in tpinit)
                {
                    tp.Add(c);
                }

                //sp = new List<Curve>();
                foreach (Curve c in spinit)
                {
                    sp.Add(c);
                }

                //lp = new List<int>();
                foreach (int i in lpinit)
                {
                    lp.Add(i);
                }

                //lv = new List<Vector3d>();
                foreach (Vector3d v in lvinit)
                {
                    lv.Add(new Vector3d(v));
                }

                int nl  = lp.Count; //number of nodal loads
                int nl2 = lv.Count; //number of loaded vectors
                if (nl != nl2)
                {
                    AddRuntimeMessage(GH_RuntimeMessageLevel.Error, "The number of LP should be equal to that of LV");
                    return;
                }

                double[] q = new double[tpinit.Count];
                FDMinit.Init(ref q, ref gpinit, ref tpinit, ref spinit, ref lpinit, ref lvinit);
                for (int i = 0; i < gpinit.Count; i++)
                {
                    if (gpinit[i].Z != 0)
                    {
                        break;
                    }
                    if (i == gpinit.Count - 1)
                    {
                        FDMinit.Init2D(ref q, ref gpinit, ref tpinit, ref spinit, ref lpinit, ref lvinit);
                    }
                }
                FDMinput.Input(ref gp, ref tp, ref sp, ref lp, ref lv, ref fix, ref free, ref Pfix, ref C, ref istart, ref iend, ref rfload);

                DA.SetDataList(0, gpinit);
                DA.SetDataList(1, tpinit);
                DA.SetDataList(2, q);
                DA.SetData(3, compliance);
                DA.SetDataList(4, cs);
            }

            if (iterating == 1)
            {
                if (!DA.GetData(5, ref seed))
                {
                    return;
                }

                double[] q = new double[tpinit.Count];
                FDMinit.Init(ref q, ref gpinit, ref tpinit, ref spinit, ref lpinit, ref lvinit);
                for (int i = 0; i < gpinit.Count; i++)
                {
                    if (gpinit[i].Z != 0)
                    {
                        break;
                    }
                    if (i == gpinit.Count - 1)
                    {
                        FDMinit.Init2D(ref q, ref gpinit, ref tpinit, ref spinit, ref lpinit, ref lvinit);
                    }
                }

                Opt(ref q, ref gp, ref tp, ref sp, ref lp, ref lv, ref cs, ref compliance, ref rfload, ref seed);

                DA.SetDataList(0, gp);
                DA.SetDataList(1, tp);
                DA.SetDataList(2, q);
                DA.SetData(3, compliance);
                DA.SetDataList(4, cs);
            }
        }