예제 #1
0
        public static void Input(ref List <Point3d> gp, ref List <Curve> tp, ref List <Curve> sp, ref List <int> lp, ref List <Vector3d> lv, ref int[] fix, ref int[] free, ref ln.Vector <double> Pfix, ref ln.Matrix <double> C, ref int[] istart, ref int[] iend, ref double[] rfload)
        {
            int nk = gp.Count; //number of nodes
            int nm = tp.Count; //number of members

            C = ln.Matrix <double> .Build.Dense(nm, nk);

            istart = new int[nm];
            iend   = new int[nm];

            for (int i = 0; i < nm; i++)
            {
                istart[i]       = Rhino.Collections.Point3dList.ClosestIndexInList(gp, tp[i].PointAtStart);
                iend[i]         = Rhino.Collections.Point3dList.ClosestIndexInList(gp, tp[i].PointAtEnd);
                C[i, istart[i]] = -1;
                C[i, iend[i]]   = 1;
            }

            ///definition of support input
            ///supports are defined by curve objects
            int nsp = sp.Count;

            ///fix0 is an index of supported & loaded points
            System.Collections.ArrayList fix0 = new System.Collections.ArrayList();
            //add supported points' indices into fix0
            for (int i = 0; i < nk; i++)
            {
                for (int j = 0; j < nsp; j++)
                {
                    double  t       = new double();
                    bool    scparam = sp[j].ClosestPoint(gp[i], out t);
                    Point3d scp     = sp[j].PointAt(t);
                    if ((gp[i] - scp).IsTiny())
                    {
                        fix0.Add(i);
                    }
                }
            }

            //add loaded points' indices into fix0
            int nl = lp.Count;//number of nodal loads

            for (int i = 0; i < nl; i++)
            {
                fix0.Add(lp[i]);
            }

            fix0.Sort();//maybe unnecessary??
            //convert to integer array "fix1"
            int[] fix1 = (int[])fix0.ToArray(typeof(int));
            //convert to HashSet(HashSet can remove overlapping values and sort automatically and quickly)
            HashSet <int> fix2 = new HashSet <int>(fix1);

            //convert to integer array "fix"
            fix = new int[fix2.Count];
            //int[] fix = new int[fix2.Count];
            fix2.CopyTo(fix, 0);

            int nfix = fix.Length;
            int ifix = 0;

            free = new int[nk - nfix];
            int nfree = 0;

            for (int i = 0; i < nk; i++)
            {
                if (ifix != nfix)
                {
                    if (i == fix[ifix])
                    {
                        ifix++;
                    }
                    else
                    {
                        free[nfree] = i;
                        nfree++;
                    }
                }

                else
                {
                    free[nfree] = i;
                    nfree++;
                }
            }

            Pfix = ln.Vector <double> .Build.Dense(nfix * 3);

            int iload = 0;

            for (int i = 0; i < nfix; i++)
            {
                if (iload == nl)
                {
                    break;
                }
                if (fix[i] == lp[iload])
                {
                    Pfix[i]            = lv[iload].X;
                    Pfix[nfix + i]     = lv[iload].Y;
                    Pfix[nfix * 2 + i] = lv[iload].Z;
                    iload++;
                }
            }

            rfload = new double[nl * 3];
        }
예제 #2
0
        /// <summary>
        /// free nodal coordinates as a function of force density method
        /// </summary>

        public static void Sens(ref double[] q, ref List <Point3d> gp, ref List <Curve> tp, ref List <int> lp, ref double[] cs, ref double compliance, ref double[] rfload, ref int[] fix, ref int[] free, ref ln.Vector <double> Pfix, ref ln.Matrix <double> C, ref int[] istart, ref int[] iend, ref double[] scompliance, ref List <double[]> srfload)
        {
            int nk    = gp.Count;
            int nm    = tp.Count;
            int nfree = free.Length;
            int nfix  = fix.Length;

            ln.Matrix <double> Ct = C.Transpose();

            double[] x = new double[nk];
            double[] y = new double[nk];
            double[] z = new double[nk];

            for (int i = 0; i < nk; i++)
            {
                x[i] = gp[i].X;
                y[i] = gp[i].Y;
                z[i] = gp[i].Z;
            }

            ln.Matrix <double> qd = ln.Matrix <double> .Build.DenseOfDiagonalArray(q);

            List <ln.Matrix <double> > sqd = new List <ln.Matrix <double> >(nm);

            for (int i = 0; i < nm; i++)
            {
                var sq = ln.Vector <double> .Build.Dense(nm);

                sq[i] = 1.0;
                sqd.Add(ln.Matrix <double> .Build.DenseOfDiagonalVector(sq));
            }

            ln.Matrix <double> Q0 = Ct * qd * C;
            var sQ0 = new List <ln.Matrix <double> >(nm);

            for (int i = 0; i < nm; i++)
            {
                sQ0.Add(Ct * sqd[i] * C);
            }

            ///Qfree & sQfree
            var Qfree0 = Q0.Clone();

            for (int i = nfix - 1; i >= 0; i--)
            {
                Qfree0 = Qfree0.RemoveColumn(fix[i]).RemoveRow(fix[i]);
            }
            var sQfree0 = new List <ln.Matrix <double> >(nm);

            foreach (ln.Matrix <double> m in sQ0)
            {
                sQfree0.Add(m);
            }
            for (int j = 0; j < nm; j++)
            {
                for (int i = nfix - 1; i >= 0; i--)
                {
                    sQfree0[j] = sQfree0[j].RemoveColumn(fix[i]).RemoveRow(fix[i]);
                }
            }

            ///Qfix & sQfix
            var Qfix0 = Q0.Clone();

            for (int i = nfree - 1; i >= 0; i--)
            {
                Qfix0 = Qfix0.RemoveColumn(free[i]).RemoveRow(free[i]);
            }
            var sQfix0 = new List <ln.Matrix <double> >(nm);

            foreach (ln.Matrix <double> m in sQ0)
            {
                sQfix0.Add(m);
            }
            for (int j = 0; j < nm; j++)
            {
                for (int i = nfree - 1; i >= 0; i--)
                {
                    sQfix0[j] = sQfix0[j].RemoveColumn(free[i]).RemoveRow(free[i]);
                }
            }

            ///Qlink & sQlink
            var Qlink0 = Q0.Clone();

            for (int i = nfree - 1; i >= 0; i--)
            {
                Qlink0 = Qlink0.RemoveColumn(free[i]);
            }
            for (int i = nfix - 1; i >= 0; i--)
            {
                Qlink0 = Qlink0.RemoveRow(fix[i]);
            }
            var sQlink0 = new List <ln.Matrix <double> >(nm);

            foreach (ln.Matrix <double> m in sQ0)
            {
                sQlink0.Add(m);
            }
            for (int j = 0; j < nm; j++)
            {
                for (int i = nfree - 1; i >= 0; i--)
                {
                    sQlink0[j] = sQlink0[j].RemoveColumn(free[i]);
                }
                for (int i = nfix - 1; i >= 0; i--)
                {
                    sQlink0[j] = sQlink0[j].RemoveRow(fix[i]);
                }
            }


            var Qfree = ln.Matrix <double> .Build.Dense(nfree * 3, nfree * 3);

            var Qfix = ln.Matrix <double> .Build.Dense(nfix * 3, nfix * 3);

            var Qlink = ln.Matrix <double> .Build.Dense(nfree * 3, nfix * 3);

            for (int i = 0; i < 3; i++)
            {
                Qfree.SetSubMatrix(nfree * i, nfree * i, Qfree0);
                Qfix.SetSubMatrix(nfix * i, nfix * i, Qfix0);
                Qlink.SetSubMatrix(nfree * i, nfix * i, Qlink0);
            }

            var sQfree = new List <ln.Matrix <double> >(nm);
            var sQfix  = new List <ln.Matrix <double> >(nm);
            var sQlink = new List <ln.Matrix <double> >(nm);

            for (int i = 0; i < nm; i++)
            {
                sQfree.Add(ln.Matrix <double> .Build.Dense(nfree * 3, nfree * 3));
                sQfix.Add(ln.Matrix <double> .Build.Dense(nfix * 3, nfix * 3));
                sQlink.Add(ln.Matrix <double> .Build.Dense(nfree * 3, nfix * 3));
            }

            for (int j = 0; j < nm; j++)
            {
                for (int i = 0; i < 3; i++)
                {
                    sQfree[j].SetSubMatrix(nfree * i, nfree * i, sQfree0[j]);
                    sQfix[j].SetSubMatrix(nfix * i, nfix * i, sQfix0[j]);
                    sQlink[j].SetSubMatrix(nfree * i, nfix * i, sQlink0[j]);
                }
            }

            var Xfree = ln.Vector <double> .Build.Dense(nfree * 3);

            var Xfix = ln.Vector <double> .Build.Dense(nfix * 3);

            for (int i = 0; i < nfix; i++)
            {
                Xfix[i]            = gp[fix[i]].X;
                Xfix[nfix + i]     = gp[fix[i]].Y;
                Xfix[nfix * 2 + i] = gp[fix[i]].Z;
            }

            Xfree = -(Qfree).Inverse() * Qlink * Xfix;

            var sQfreeXfree = ln.Matrix <double> .Build.Dense(nfree * 3, nm);

            for (int i = 0; i < nm; i++)
            {
                sQfreeXfree.SetColumn(i, sQfree[i] * Xfree);
            }

            var sQlinkXfix = ln.Matrix <double> .Build.Dense(nfree * 3, nm);

            for (int i = 0; i < nm; i++)
            {
                sQlinkXfix.SetColumn(i, sQlink[i] * Xfix);
            }

            var sXfree = ln.Matrix <double> .Build.Dense(nfree * 3, nm);

            sXfree = -Qfree.Inverse() * (sQfreeXfree + sQlinkXfix);

            ///return nodal coordinates
            for (int i = 0; i < nfree; i++)
            {
                x[free[i]] = Xfree[i];
                y[free[i]] = Xfree[nfree + i];
                z[free[i]] = Xfree[nfree * 2 + i];
            }
            double[,] sx = new double[nk, nm];
            double[,] sy = new double[nk, nm];
            double[,] sz = new double[nk, nm];
            for (int j = 0; j < nm; j++)
            {
                for (int i = 0; i < nfree; i++)
                {
                    sx[free[i], j] = sXfree[i, j];
                    sy[free[i], j] = sXfree[nfree + i, j];
                    sz[free[i], j] = sXfree[nfree * 2 + i, j];
                }
            }

            for (int i = 0; i < nfree; i++)
            {
                gp[free[i]] = new Point3d(x[free[i]], y[free[i]], z[free[i]]);
            }

            for (int i = 0; i < nm; i++)
            {
                tp[i] = new LineCurve(gp[istart[i]], gp[iend[i]]);
            }

            double[] length  = new double[nm];
            double[] length2 = new double[nm];
            double[,] slength2 = new double[nm, nm];

            for (int i = 0; i < nm; i++)
            {
                length[i]  = Math.Sqrt(Math.Pow(x[iend[i]] - x[istart[i]], 2) + Math.Pow(y[iend[i]] - y[istart[i]], 2) + Math.Pow(z[iend[i]] - z[istart[i]], 2));
                length2[i] = Math.Pow(length[i], 2);
            }

            for (int j = 0; j < nm; j++)
            {
                for (int i = 0; i < nm; i++)
                {
                    slength2[i, j] = 2 * ((x[iend[i]] - x[istart[i]]) * (sx[iend[i], j] - sx[istart[i], j]) + (y[iend[i]] - y[istart[i]]) * (sy[iend[i], j] - sy[istart[i], j]) + (z[iend[i]] - z[istart[i]]) * (sz[iend[i], j] - sz[istart[i], j]));
                }
            }

            var sQlinkXfree = ln.Matrix <double> .Build.Dense(nfix * 3, nm);

            var QlinksXfree = ln.Matrix <double> .Build.Dense(nfix * 3, nm);

            var sQfixXfix = ln.Matrix <double> .Build.Dense(nfix * 3, nm);

            for (int i = 0; i < nm; i++)
            {
                sQlinkXfree.SetColumn(i, sQlink[i].Transpose() * Xfree);
                QlinksXfree.SetColumn(i, Qlink.Transpose() * sXfree.Column(i));
                sQfixXfix.SetColumn(i, sQfix[i] * Xfix);
            }

            ///reaction force
            var rf = ln.Vector <double> .Build.Dense(nfix * 3);

            var srf = ln.Matrix <double> .Build.Dense(nfix * 3, nm);

            rf  = Qlink.Transpose() * Xfree + (Qfix) * Xfix;
            srf = sQlinkXfree + QlinksXfree + sQfixXfix;

            int iload = 0;
            int nl    = lp.Count;

            for (int i = 0; i < nfix; i++)
            {
                if (iload == nl)
                {
                    break;
                }
                if (fix[i] == lp[iload])
                {
                    rfload[0 + 3 * iload] = rf[i] - Pfix[i];
                    rfload[1 + 3 * iload] = rf[nfix + i] - Pfix[nfix + i];
                    rfload[2 + 3 * iload] = rf[nfix * 2 + i] - Pfix[nfix * 2 + i];
                    iload++;
                }
            }

            iload   = 0;
            srfload = new List <double[]>(nl * 3);
            for (int i = 0; i < nl * 3; i++)
            {
                srfload.Add(new double[nm]);
            }
            for (int j = 0; j < nm; j++)
            {
                for (int i = 0; i < nfix; i++)
                {
                    if (iload == nl)
                    {
                        break;
                    }
                    if (fix[i] == lp[iload])
                    {
                        srfload[0 + 3 * iload][j] = srf[i, j];
                        srfload[1 + 3 * iload][j] = srf[nfix + i, j];
                        srfload[2 + 3 * iload][j] = srf[nfix * 2 + i, j];
                        iload++;
                    }
                }
            }

            ///cross-sectional area
            cs = new double[nm];
            for (int i = 0; i < nm; i++)
            {
                cs[i] = Math.Sqrt(Math.Pow(q[i], 2) + .1e-5) * length[i];
            }

            ///volume
            double vol = 0;

            for (int i = 0; i < nm; i++)
            {
                vol += Math.Sqrt(Math.Pow(q[i], 2) + .1e-5) * length2[i];
            }

            ///strain energy
            double se = 0;

            double[] sse = new double[nm];
            for (int i = 0; i < nm; i++)
            {
                se += .5e0 * length2[i] * Math.Sqrt(Math.Pow(q[i], 2) + .1e-5) / ee;
            }
            for (int j = 0; j < nm; j++)
            {
                for (int i = 0; i < nm; i++)
                {
                    sse[j] += .5e0 * slength2[i, j] * Math.Sqrt(Math.Pow(q[i], 2) + .1e-5) / ee;
                    sse[j] += .5e0 * length2[i] * q[i] / Math.Sqrt(Math.Pow(q[i], 2) + .1e-5) * ee;
                }
            }

            ///compliance
            compliance  = se * .2e1;
            scompliance = new double[nm];
            for (int j = 0; j < nm; j++)
            {
                scompliance[j] = sse[j] * .2e1;
            }
        }