Example #1
0
        public void computeForceDiagram(List<leaf> _listLeaf, List<node> _listNode)
        {
            //variable settings
            int numvar = _listNode.Count * 2;
            int numcon = 0;
            double infinity = 0;
            numcon += _listNode.Count;  //finite element matrix

            foreach (var leaf in _listLeaf)
            {
                leaf.conOffset = numcon;
                leaf.varOffset = numvar;
                numcon += leaf.tuples.Length * 1; //grad(detF)dx>-detF
            }
            mosek.boundkey[] bkx = new mosek.boundkey[numvar];
            double[] blx = new double[numvar];
            double[] bux = new double[numvar];
            for (int i = 0; i < _listNode.Count; i++)
            {
                if (_listNode[i].forceNodeType== node.type.fx)
                {
                    bkx[i * 2 + 0] = mosek.boundkey.fx;
                    blx[i * 2 + 0] = 0;// _listNode[i].X;
                    bux[i * 2 + 0] = 0;//_listNode[i].X;
                    bkx[i * 2 + 1] = mosek.boundkey.fx;
                    blx[i * 2 + 1] = 0;//_listNode[i].Y;
                    bux[i * 2 + 1] = 0;//_listNode[i].Y;
                }
                else
                {
                    bkx[i * 2 + 0] = mosek.boundkey.fr;
                    blx[i * 2 + 0] = -infinity;
                    bux[i * 2 + 0] = infinity;
                    bkx[i * 2 + 1] = mosek.boundkey.fr;
                    blx[i * 2 + 1] = -infinity;
                    bux[i * 2 + 1] = infinity;
                }
            }
            for (int t = 0; t < 10; t++)
            {
                init(_listLeaf);
                double[] x = new double[_listNode.Count * 2];
                foreach (var leaf in _listLeaf)
                {
                    for (int j = 0; j < leaf.nV; j++)
                    {
                        for (int i = 0; i < leaf.nU; i++)
                        {
                            int indexX = leaf.globalIndex[i + j * leaf.nU] * 2 + 0;
                            int indexY = leaf.globalIndex[i + j * leaf.nU] * 2 + 1;
                            var Q = leaf.forceSrf.Points.GetControlPoint(i, j);
                            x[indexX] = Q.Location.X;
                            x[indexY] = Q.Location.Y;
                        }
                    }

                }
                using (mosek.Env env = new mosek.Env())
                {
                    // Create a task object.
                    using (mosek.Task task = new mosek.Task(env, 0, 0))
                    {
                        // Directs the log task stream to the user specified
                        // method msgclass.streamCB
                        task.set_Stream(mosek.streamtype.log, new msgclass(""));
                        task.appendcons(numcon);
                        task.appendvars(numvar);
                        for (int j = 0; j < numvar; ++j)
                        {
                            task.putvarbound(j, bkx[j], blx[j], bux[j]);
                        }
                        
                        ShoNS.Array.SparseDoubleArray mat = new SparseDoubleArray(_listNode.Count, _listNode.Count * 2);
                        
                        
                        foreach (var leaf in _listLeaf)
                        {
                            foreach (var tup in leaf.tuples)
                            {
                                for(int i = 0; i < tup.nNode; i++)
                                {
                                    int indexI = leaf.globalIndex[tup.internalIndex[i]];
                                    for (int j = 0; j < tup.nNode; j++)
                                    {
                                        int indexJx = leaf.globalIndex[tup.internalIndex[j]] * 2 + 0;
                                        int indexJy = leaf.globalIndex[tup.internalIndex[j]] * 2 + 1;
                                        var d0 = tup.d0;
                                        var d1 = tup.d1;
                                        var G1 = tup.refGi[0];
                                        var G2 = tup.refGi[1];
                                        var val0 = (d0[j] * d1[0][i] * G1[1] + d0[j] * d1[1][i] * G2[1]) * tup.refDv * tup.area;
                                        var val1 = -(d0[j] * d1[0][i] * G1[0] + d0[j] * d1[1][i] * G2[0]) * tup.refDv * tup.area;
                                        mat[indexI, indexJx] += val0;
                                        mat[indexI, indexJy] += val1;
                                    }
                                }
                            }
                        }
                        
                        for (int i = 0; i < _listNode.Count; i++)
                        {
                            var val = 0d;
                            for (int j = 0; j < _listNode.Count * 2; j++)
                            {
                                val += mat[i, j] * x[j];
                            }
                            task.putconbound(i, mosek.boundkey.fx, -val, -val);
                            for (int j = 0; j < _listNode.Count*2; j++)
                            {
                                task.putaij(i, j, mat[i, j]);
                            }
                        }
                        
                        foreach (var leaf in _listLeaf)
                        {
                            int offsetC = 0;
                            foreach (var tup in leaf.tuples)
                            {
                                //compute current detF
                                //x,y; referece, X,Y; forceDiagram
                                var FXx = tup.gi[0][0] * tup.refGi[0][0] + tup.gi[1][0] * tup.refGi[1][0];
                                var FYy = tup.gi[0][1] * tup.refGi[0][1] + tup.gi[1][1] * tup.refGi[1][1];
                                var FXy = tup.gi[0][0] * tup.refGi[0][1] + tup.gi[1][0] * tup.refGi[1][1];
                                var FYx = tup.gi[0][1] * tup.refGi[0][0] + tup.gi[1][1] * tup.refGi[1][0];
                                var detF = FXx * FYy- FXy * FYx;
                                task.putconbound(leaf.conOffset + offsetC, mosek.boundkey.lo, -detF,infinity);
                                var G1 = tup.refGi[0];
                                var G2 = tup.refGi[1];
                                for (int i = 0; i < tup.nNode; i++)
                                {
                                    int indexX = leaf.globalIndex[tup.internalIndex[i]] * 2 + 0;
                                    int indexY = leaf.globalIndex[tup.internalIndex[i]] * 2 + 1;

                                    double val1 = (tup.d1[0][i] * G1[0] + tup.d1[1][i] * G2[0]) * FYy;
                                    double val2 = (tup.d1[0][i] * G1[1] + tup.d1[1][i] * G2[1]) * FYx;

                                    task.putaij(leaf.conOffset + offsetC, indexX, -val2);
                                    val1 = (tup.d1[0][i] * G1[1] + tup.d1[1][i] * G2[1]) * FXx;
                                    val2 = (tup.d1[0][i] * G1[0] + tup.d1[1][i] * G2[0]) * FXy;
                                    task.putaij(leaf.conOffset + offsetC, indexY, val1- val2);
                                }
                                offsetC ++;
                            }
                        }
                        for (int i = 0; i < _listNode.Count; i++)
                        {
                            task.putqobjij(i * 2 + 0, i * 2 + 0, 1);
                            task.putqobjij(i * 2 + 1, i * 2 + 1, 1);
                        }
                        task.optimize();
                        // Print a summary containing information
                        //   about the solution for debugging purposes
                        task.solutionsummary(mosek.streamtype.msg);

                        mosek.solsta solsta;
                        task.getsolsta(mosek.soltype.itr, out solsta);

                        double[] dx = new double[numvar];

                        task.getxx(mosek.soltype.itr, // Basic solution.     
                                        dx);

                        switch (solsta)
                        {
                            case mosek.solsta.optimal:
                                System.Windows.Forms.MessageBox.Show("Optimal primal solution\n");
                                break;
                            case mosek.solsta.near_optimal:
                                System.Windows.Forms.MessageBox.Show("Near Optimal primal solution\n");
                                break;
                            case mosek.solsta.dual_infeas_cer:
                                System.Windows.Forms.MessageBox.Show("Primal or dual infeasibility.\n");
                                break;
                            case mosek.solsta.prim_infeas_cer:
                                System.Windows.Forms.MessageBox.Show("Primal or dual infeasibility.\n");
                                break;
                            case mosek.solsta.near_dual_infeas_cer:
                                System.Windows.Forms.MessageBox.Show("Primal or dual infeasibility.\n");
                                break;
                            case mosek.solsta.near_prim_infeas_cer:
                                System.Windows.Forms.MessageBox.Show("Primal or dual infeasibility.\n");
                                break;
                            case mosek.solsta.unknown:
                                System.Windows.Forms.MessageBox.Show("Unknown solution status\n");
                                break;
                            default:
                                System.Windows.Forms.MessageBox.Show("Other solution status\n");
                                break;

                        }
                        foreach (var leaf in _listLeaf)
                        {
                            for (int j = 0; j < leaf.nV; j++)
                            {
                                for (int i = 0; i < leaf.nU; i++)
                                {
                                    int indexX = leaf.globalIndex[i + j * leaf.nU] * 2 + 0;
                                    int indexY = leaf.globalIndex[i + j * leaf.nU] * 2 + 1;
                                    var Q = leaf.forceSrf.Points.GetControlPoint(i, j);
                                    var P = new Point3d(Q.Location.X + dx[indexX] * 1d, Q.Location.Y + dx[indexY] * 1d, 0);
                                    leaf.forceSrf.Points.SetControlPoint(i, j, P);
                                }
                            }
                        }
                    }
                }
                ExpirePreview(true);
            }
        }