コード例 #1
0
ファイル: GeneticsSearch.cs プロジェクト: NVSarge/TF
            }/**/

            for (int inner = 0; inner < 1; inner++)
            {
                var      Ukx = skx.FE_inded(WX, WY, g.Genom, SelectedUs, penal);
                var      ke  = skx.KE;
                double   c   = 0.0;
                double[] dc  = new double[WX * WY];
                for (int elx = 0; elx < WX; elx++)
                {
                    for (int ely = 0; ely < WY; ely++)
                    {
                        int      n1   = (WY + 1) * elx + ely;
                        int      n2   = (WY + 1) * (elx + 1) + ely;
                        var      edof = np.array(2 * n1, 2 * n1 + 1, 2 * n2, 2 * n2 + 1, 2 * n2 + 2, 2 * n2 + 3, 2 * n1 + 2, 2 * n1 + 3);
                        double[] Ue   = new double[8];
                        for (int i = 0; i < edof.size; i++)
                        {
                            Ue[i] = Ukx[edof[i]];
                        }
                        double   xp    = Math.Pow(g.Genom[ely + elx * WY], penal);
                        double[] KEUe  = MatrixMath.MatVecProd(ke, Ue);
                        double   UEKUE = 0;
                        for (int i = 0; i < KEUe.Length; i++)
                        {
                            UEKUE += Ue[i] * KEUe[i];
                        }
                        c += xp * UEKUE;
                        dc[ely + elx * WY] = -penal *Math.Pow(g.Genom[ely + elx * WY], penal - 1) * UEKUE;
                    }
                }

                dc      = skx.Check(WX, WY, 1.5, g.Genom, dc);
                g.Genom = skx.OC(WX, WY, g.Genom, volfraq, dc);
            }

            return(AFC.ToArray());
        }

        public static double[] Test_eval_simp(Genome <double> g, int WX, int WY, double volfraq, double f1, double f2, double f3)
        {
            double[] retval = new double[1];
            int      penal  = 3;


            KXMSolvers skx = new KXMSolvers();
            var        U   = skx.FE(WX, WY, g.Genom, penal);
            var        ke  = skx.KE;
            double     c   = 0.0;

            double[] dc = new double[WX * WY];
            for (int elx = 0; elx < WX; elx++)
            {
                for (int ely = 0; ely < WY; ely++)
                {
                    int      n1   = (WY + 1) * elx + ely;
                    int      n2   = (WY + 1) * (elx + 1) + ely;
                    var      edof = np.array(2 * n1, 2 * n1 + 1, 2 * n2, 2 * n2 + 1, 2 * n2 + 2, 2 * n2 + 3, 2 * n1 + 2, 2 * n1 + 3);
                    double[] Ue   = new double[8];
                    for (int i = 0; i < edof.size; i++)
                    {
                        Ue[i] = U[edof[i]];
                    }
                    double   xp    = Math.Pow(g.Genom[ely + elx * WY], penal);
                    double[] KEUe  = MatrixMath.MatVecProd(ke, Ue);
                    double   UEKUE = 0;
                    for (int i = 0; i < KEUe.Length; i++)
                    {
                        UEKUE += Ue[i] * KEUe[i];
                    }
                    c += xp * UEKUE;
                    dc[ely + elx * WY] = -penal *Math.Pow(g.Genom[ely + elx *WY], penal - 1) * UEKUE;
                }
            }
            dc      = skx.Check(WX, WY, 1.5, g.Genom, dc);
            g.Genom = skx.OC(WX, WY, g.Genom, volfraq, dc);
            double sumV = 0;

            foreach (var gg in g.Genom)
            {
                sumV += (double)gg;
            }
            sumV      = sumV - WX * WY * volfraq;
            retval[0] = c;
            return(retval);
        }

        public static double Test_eval(Genome <double> g, int WX, int WY, double volfraq)
        {
            double retval = 0.0f;
            int    penal  = 3;


            KXMSolvers skx = new KXMSolvers();
            var        U   = skx.FE(WX, WY, g.Genom, penal);

            var    ke = skx.KE;
            double c  = 0.0;

            for (int elx = 0; elx < WX; elx++)
            {
                for (int ely = 0; ely < WY; ely++)
                {
                    int      n1   = (WY + 1) * elx + ely;
                    int      n2   = (WY + 1) * (elx + 1) + ely;
                    var      edof = np.array(2 * n1, 2 * n1 + 1, 2 * n2, 2 * n2 + 1, 2 * n2 + 2, 2 * n2 + 3, 2 * n1 + 2, 2 * n1 + 3);
                    double[] Ue   = new double[8];
                    for (int i = 0; i < edof.size; i++)
                    {
                        Ue[i] = U[edof[i]];
                    }
                    double   xp    = Math.Pow(g.Genom[ely + elx * WY], penal);
                    double[] KEUe  = MatrixMath.MatVecProd(ke, Ue);
                    double   UEKUE = 0;
                    for (int i = 0; i < KEUe.Length; i++)
                    {
                        UEKUE += Ue[i] * KEUe[i];
                    }
                    c += xp * UEKUE;
                }
            }
            //  g.Genom = skx.Check(WX, WY, 1.5, g.Genom);
            double sumV = 0;

            foreach (var gg in g.Genom)
            {
                sumV += (double)gg;
            }
            sumV   = sumV - WX * WY * volfraq;
            retval = c * c + sumV * sumV * 2.0;
            return(retval);
        }

        /**/
        public static double Test_eval_weave(Genome <int> g, int WX, int WY, double volfraq)
        {
            double retval = 0;
            int    penal  = 3;

            var        ge  = convertWeaverToField(g, WX, WY);
            KXMSolvers skx = new KXMSolvers();
            var        U   = skx.FE(WX, WY, ge, penal);

            var    ke = skx.KE;
            double c  = 0.0;

            for (int elx = 0; elx < WX; elx++)
            {
                for (int ely = 0; ely < WY; ely++)
                {
                    int      n1   = (WY + 1) * elx + ely;
                    int      n2   = (WY + 1) * (elx + 1) + ely;
                    var      edof = np.array(2 * n1, 2 * n1 + 1, 2 * n2, 2 * n2 + 1, 2 * n2 + 2, 2 * n2 + 3, 2 * n1 + 2, 2 * n1 + 3);
                    double[] Ue   = new double[8];
                    for (int i = 0; i < edof.size; i++)
                    {
                        Ue[i] = U[edof[i]];
                    }
                    double xp = Math.Pow(ge[ely + elx * WY], penal);

                    double[] KEUe  = MatrixMath.MatVecProd(ke, Ue);
                    double   UEKUE = 0;
                    for (int i = 0; i < KEUe.Length; i++)
                    {
                        UEKUE += Ue[i] * KEUe[i];
                    }

                    c += xp * UEKUE;
                }
            }
            double sumV = ge.Sum();

            sumV   = sumV - (double)(WX * WY) * volfraq;
            retval = c * c * 1.0 + sumV * sumV * 0.0;
            return(retval);
        }
コード例 #2
0
ファイル: KXMSolvers.cs プロジェクト: NVSarge/TF
        public double[] Modal(int nelx,
                              int nely,
                              double[] x,
                              double p,
                              double q,
                              out double[,] V)
        {
            var ke = K_Plain_strain(1e10, 0.3);
            var me = M_Plain_strain(1000, 1);
            int N  = 2 * (nelx + 1) * (nely + 1);

            double[][] K = new double[N][];
            double[][] M = new double[N][];
            for (int i = 0; i < N; i++)
            {
                K[i] = new double[N];
                M[i] = new double[N];
            }
            for (int elx = 0; elx < nelx; elx++)
            {
                for (int ely = 0; ely < nely; ely++)
                {
                    int n1   = (nely + 1) * elx + ely;
                    int n2   = (nely + 1) * (elx + 1) + ely;
                    var edof = np.array(2 * n1, 2 * n1 + 1, 2 * n2, 2 * n2 + 1, 2 * n2 + 2, 2 * n2 + 3, 2 * n1 + 2, 2 * n1 + 3);
                    for (int i = 0; i < edof.size; i++)
                    {
                        for (int j = 0; j < edof.size; j++)
                        {
                            K[edof[i]][edof[j]] = K[edof[i]][edof[j]] + Math.Pow(x[ely + elx * (nely)], p) * ke[i][j];
                            M[edof[i]][edof[j]] = M[edof[i]][edof[j]] + Math.Pow(x[ely + elx * (nely)], q) * me[i][j];
                        }
                    }
                }
            }

            int[] inds = new int[4 * (nely + 1)];
            //left and right border fix
            for (int i = 0; i < 2 * (nely + 1); i++)
            {
                inds[i] = i;
                inds[i + 2 * (nely + 1)] = N - 2 * (nely + 1) + i - 1;
            }


            double[,] Kmm = MatrixMath.To2D <double>(K);
            double[,] Mmm = MatrixMath.To2D <double>(M);


            Kmm = MatrixMath.CrossOut(Kmm, inds);
            Mmm = MatrixMath.CrossOut(Mmm, inds);


            int reducedN = Kmm.GetLength(0);

            double[] wr = new double[reducedN];
            //solve
            alglib.smatrixgevd(Kmm, reducedN, false, Mmm, false, 1, 1, out wr, out V);
            for (int i = 0; i < V.GetLength(0); i++)
            {
                for (int j = 0; j < V.GetLength(1); j++)
                {
                    V[i, j] = Math.Cos(wr[i]) * V[i, j];
                }
            }
            V = MatrixMath.FillOnWeird(V, inds);


            return(wr);
        }
コード例 #3
0
ファイル: KXMSolvers.cs プロジェクト: NVSarge/TF
        public double[] FE(int nelx, int nely, double[] x, double p)
        {
            var ke = KE;
            int N  = 2 * (nelx + 1) * (nely + 1);

            double[][] K_m = new double[N][];
            for (int i = 0; i < N; i++)
            {
                K_m[i] = new double[N];
            }
            for (int elx = 0; elx < nelx; elx++)
            {
                for (int ely = 0; ely < nely; ely++)
                {
                    int n1   = (nely + 1) * elx + ely;
                    int n2   = (nely + 1) * (elx + 1) + ely;
                    var edof = np.array(2 * n1, 2 * n1 + 1, 2 * n2, 2 * n2 + 1, 2 * n2 + 2, 2 * n2 + 3, 2 * n1 + 2, 2 * n1 + 3);
                    for (int i = 0; i < edof.size; i++)
                    {
                        for (int j = 0; j < edof.size; j++)
                        {
                            K_m[edof[i]][edof[j]] = K_m[edof[i]][edof[j]] + Math.Pow(x[ely + elx * (nely)], p) * ke[i][j]; //?diagonal
                        }
                    }
                }
            }


            int[] inds = new int[2 * (nely + 1)];
            //left and right border fix
            for (int i = 0; i < 2 * (nely + 1); i++)
            {
                inds[i] = i;
            }
            Random r = new Random(123);

            double[,] Kmm = MatrixMath.To2D <double>(K_m);
            Kmm           = MatrixMath.CrossOut(Kmm, inds);
            int reducedN = Kmm.GetLength(0);

            double[] F = new double[reducedN];
            double[] X = new double[N];
            for (int i = 0; i < nely; i++)
            {
                F[(2 * nely + 1) * nelx + i * 2 - 1] = -1;
            }
            F[reducedN - nely - 1] = r.NextDouble();
            alglib.rmatrixsolvefast(Kmm, reducedN, ref F, out _);
            int c = 0;

            for (int i = 0; i < N; i++)
            {
                if (c < inds.Length && inds[c] == i)
                {
                    X[i] = 0;
                    c++;
                }
                else
                {
                    X[i] = F[i - c];
                }
            }
            return(X);
        }
コード例 #4
0
ファイル: KXMSolvers.cs プロジェクト: NVSarge/TF
        public double[] FE_inded(int nelx, int nely, double[] x, Dictionary <int, double> f_map, double p)
        {
            var ke = KE;
            int N  = 2 * (nelx + 1) * (nely + 1);

            double[][] K_m = new double[N][];
            for (int i = 0; i < N; i++)
            {
                K_m[i] = new double[N];
            }
            for (int elx = 0; elx < nelx; elx++)
            {
                for (int ely = 0; ely < nely; ely++)
                {
                    int n1   = (nely + 1) * elx + ely;
                    int n2   = (nely + 1) * (elx + 1) + ely;
                    var edof = np.array(2 * n1, 2 * n1 + 1, 2 * n2, 2 * n2 + 1, 2 * n2 + 2, 2 * n2 + 3, 2 * n1 + 2, 2 * n1 + 3);
                    for (int i = 0; i < edof.size; i++)
                    {
                        for (int j = 0; j < edof.size; j++)
                        {
                            K_m[edof[i]][edof[j]] = K_m[edof[i]][edof[j]] + Math.Pow(x[ely + elx * (nely)], p) * ke[i][j]; //?diagonal
                        }
                    }
                }
            }


            int[] inds = new int[2 * (nely + 1)];
            //left and right border fix
            for (int i = 0; i < 2 * (nely + 1); i++)
            {
                inds[i] = i;
            }
            Random r = new Random(123);

            double[,] Kmm = MatrixMath.To2D <double>(K_m);
            Kmm           = MatrixMath.CrossOut(Kmm, inds);
            int           reducedN = Kmm.GetLength(0);
            List <double> F_full   = Enumerable.Repeat(0.0, N).ToList();

            double[] X = new double[N];
            double[] F = new double[reducedN];
            //index crossout
            int c = 0;

            foreach (var q in f_map)
            {
                F_full[q.Key] = q.Value;
            }

            for (int i = 0; i < N; i++)
            {
                if (c < inds.Length && inds[c] == i)
                {
                    c++;
                }
                else
                {
                    F[i - c] = F_full[i];
                }
            }
            // F[reducedN -1] = -1e6;

            alglib.rmatrixsolvefast(Kmm, reducedN, ref F, out _);
            //index backfill
            c = 0;
            for (int i = 0; i < N; i++)
            {
                if (c < inds.Length && inds[c] == i)
                {
                    X[i] = 0;
                    c++;
                }
                else
                {
                    X[i] = F[i - c];
                }
            }
            return(X);
        }
コード例 #5
0
ファイル: KXMSolvers.cs プロジェクト: NVSarge/TF
        public double[] Harmonic(int nelx, int nely, double[] x, double p, double q, double wmega)
        {
            var ke = K_Plain_strain(1e10, 0.3);
            var me = M_Plain_strain(1000, 1);
            int N  = 2 * (nelx + 1) * (nely + 1);

            double[][] K = new double[N][];
            double[][] M = new double[N][];
            for (int i = 0; i < N; i++)
            {
                K[i] = new double[N];
                M[i] = new double[N];
            }
            for (int elx = 0; elx < nelx; elx++)
            {
                for (int ely = 0; ely < nely; ely++)
                {
                    int n1   = (nely + 1) * elx + ely;
                    int n2   = (nely + 1) * (elx + 1) + ely;
                    var edof = np.array(2 * n1, 2 * n1 + 1, 2 * n2, 2 * n2 + 1, 2 * n2 + 2, 2 * n2 + 3, 2 * n1 + 2, 2 * n1 + 3);
                    for (int i = 0; i < edof.size; i++)
                    {
                        for (int j = 0; j < edof.size; j++)
                        {
                            K[edof[i]][edof[j]] = K[edof[i]][edof[j]] + Math.Pow(x[ely + elx * (nely)], p) * ke[i][j];
                            M[edof[i]][edof[j]] = M[edof[i]][edof[j]] + Math.Pow(x[ely + elx * (nely)], q) * me[i][j];
                        }
                    }
                }
            }

            int[] inds = new int[2 * (nely + 1)];
            //left border fix
            for (int i = 0; i < 2 * (nely + 1); i++)
            {
                inds[i] = i;
            }


            double[,] Kmm = MatrixMath.To2D <double>(K);
            double[,] Mmm = MatrixMath.To2D <double>(M);


            Kmm = MatrixMath.CrossOut(Kmm, inds);
            Mmm = MatrixMath.CrossOut(Mmm, inds);

            List <double> X        = new List <double>();
            int           reducedN = Kmm.GetLength(0);

            double[,] DSW = new double[reducedN, reducedN];

            for (int ik = 0; ik < Kmm.GetLength(0); ik++)
            {
                for (int jk = 0; jk < Kmm.GetLength(1); jk++)
                {
                    double l = wmega * 2 * Math.PI;
                    l           = l * l;
                    DSW[ik, jk] = Kmm[ik, jk] - l * Mmm[ik, jk];
                }
            }
            double[] F = new double[reducedN];
            double[] U = new double[reducedN];
            F[reducedN - 1] = -1e6;
            alglib.rmatrixsolve(DSW, reducedN, F, out _, out _, out U);
            int c = 0;

            for (int i = 0; i < N; i++)
            {
                if (c < inds.Length && inds[c] == i)
                {
                    X.Add(0);
                    c++;
                }
                else
                {
                    X.Add(U[i - c]);
                }
            }
            return(X.ToArray());
        }
コード例 #6
0
ファイル: SectionalSearch.cs プロジェクト: NVSarge/TF
        public static double[,] GoSearch(IProgress <Image> progress, int WX, int WY, double volfraq, IProgress <double> prog)
        {
            Random r = new Random();

            double[,] retval = new double[WX, WY];
            QuadTree <double> SearchTree = new QuadTree <double>();

            SearchTree.Root.BB        = new System.Windows.Rect(0, 0, WX, WY);
            SearchTree.Root.NodeValue = 1.0;
            List <double> Graph     = new List <double>();
            float         MultySize = 20.0f;
            Image         MyImage   = new Bitmap((int)((WX * 4) * MultySize), (int)((WY * 4) * MultySize));
            Graphics      g         = Graphics.FromImage(MyImage);

            for (int h = 0; h < 10000; h++)
            {
                var           SearchRootList = SearchTree.getLeafs();
                double        step           = 0.3 * r.NextDouble() - 0.1;
                List <double> Gradient       = new List <double>();
                retval = convertTree2Mesh(SearchTree, WX, WY);
                int    penal = 3;
                double Fzero = CalcTree(WX, WY, volfraq, retval, penal);
                Graph.Insert(0, Fzero);


                foreach (var q in SearchRootList)
                {
                    var oldVal = q.NodeValue;
                    q.NodeValue = Math.Min(1.0, Math.Max(0.001, q.NodeValue + step));
                    retval      = convertTree2Mesh(SearchTree, WX, WY);

                    double F   = CalcTree(WX, WY, volfraq, retval, penal);
                    double Sum = MatrixMath.To1D(retval).Sum();

                    Gradient.Add((F - Fzero) / step);
                    q.NodeValue = oldVal;
                    ///

                    for (int ix = 0; ix < WX; ix++)
                    {
                        for (int iy = 0; iy < WY; iy++)
                        {
                            double H = 1.0 - (float)retval[ix, iy];
                            H = Math.Max(0, Math.Min(1.0, H));
                            if (double.IsNaN(H))
                            {
                                H = 0;
                            }

                            H = H * 255;
                            Color      customColor = Color.FromArgb(255, (int)H, (int)H, (int)H);
                            SolidBrush shadowBrush = new SolidBrush(customColor);
                            g.FillRectangle(shadowBrush, ix * MultySize, iy * MultySize, MultySize, MultySize);
                        }
                    }

                    for (int ix = 0; ix < WX; ix++)
                    {
                        for (int iy = 0; iy < WY; iy++)
                        {
                            double H = 1.0 - (float)retval[ix, iy];
                            H = Math.Max(0, Math.Min(1.0, H));
                            if (double.IsNaN(H))
                            {
                                H = 0;
                            }

                            H = H * 255;
                            Color      customColor = Color.FromArgb(255, (int)H, (int)H, (int)H);
                            SolidBrush shadowBrush = new SolidBrush(customColor);
                            g.FillRectangle(shadowBrush, ix * MultySize + MultySize * WX + 5, iy * MultySize, MultySize, MultySize);
                        }
                    }
                    progress.Report(MyImage);
                }
                float dY = 500;
                g.FillRectangle(new SolidBrush(Color.White), 0, dY - 150, 500, dY + 150);
                g.DrawLine(new Pen(Color.Black, 2), 0, dY, 500, dY);
                double data    = Graph[Graph.Count - 1];
                double olddata = Graph[Graph.Count - 1];
                float  MaxG    = (float)(Graph.Max() + 0.00001f);
                Debug.WriteLine(Graph.First());
                for (int i = 0; i < Math.Min(500, Graph.Count); i++)
                {
                    if (!double.IsNaN(Graph[i]))
                    {
                        data = Graph[i];
                        g.DrawLine(new Pen(Color.Blue, 2), Math.Min(500, Graph.Count) - i, dY - 150.0f * (float)olddata / MaxG, Math.Min(500, Graph.Count) - i - 1.0f, dY - 150.0f * (float)data / MaxG);
                        olddata = data;
                        progress.Report(MyImage);
                    }
                }
                SearchRootList = SearchRootList.OrderBy(d => (Gradient[SearchRootList.IndexOf(d)])).ToList();
                KXMSolvers kx   = new KXMSolvers();
                var        xnew = kx.OC(Gradient.Count, 1, SearchTree.GetLeafsValues().ToArray(), 0.5, Gradient.ToArray());
                double     gMx  = Gradient.Max();
                double     gMn  = Gradient.Min();
                foreach (var q in SearchRootList)
                {
                    double delta = -Gradient[SearchRootList.IndexOf(q)];
                    if (!q.IsLast)
                    {
                        //q.NodeValue = Math.Min(1.0, Math.Max(0.001, xnew[SearchRootList.IndexOf(q)]));
                        //q.NodeValue = Math.Min(1.0, Math.Max(0.001, q.NodeValue*Math.Sqrt(delta)));
                        q.NodeValue = Math.Min(1.0, Math.Max(0.001, q.NodeValue + step));
                        if (Math.Abs(q.NodeValue - 1.0) < 0.1)
                        {
                            q.SubDivide(q.NodeValue / 2);
                        }
                        break;
                    }
                    else
                    {
                        q.NodeValue = Math.Min(1.0, Math.Max(0.001, q.NodeValue + step));
                    }
                }
            }
            g.Dispose();
            retval = convertTree2Mesh(SearchTree, WX, WY);
            return(retval);
        }