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); } }