|
730 | 730 | }, |
731 | 731 | { |
732 | 732 | "cell_type": "code", |
733 | | - "execution_count": 41, |
| 733 | + "execution_count": 51, |
734 | 734 | "id": "110b9543", |
735 | 735 | "metadata": {}, |
736 | 736 | "outputs": [], |
|
807 | 807 | }, |
808 | 808 | { |
809 | 809 | "cell_type": "code", |
810 | | - "execution_count": 42, |
| 810 | + "execution_count": 52, |
811 | 811 | "id": "b842ad4e", |
812 | 812 | "metadata": {}, |
813 | 813 | "outputs": [ |
814 | 814 | { |
815 | 815 | "data": { |
816 | 816 | "application/vnd.jupyter.widget-view+json": { |
817 | | - "model_id": "a6c5a1f819054a769f275840f0fb97f9", |
| 817 | + "model_id": "bd0f27ce2f1048d3b4c8d23fff809a5c", |
818 | 818 | "version_major": 2, |
819 | 819 | "version_minor": 0 |
820 | 820 | }, |
|
880 | 880 | }, |
881 | 881 | { |
882 | 882 | "cell_type": "code", |
883 | | - "execution_count": 43, |
| 883 | + "execution_count": 53, |
884 | 884 | "id": "e2876471", |
885 | 885 | "metadata": {}, |
886 | 886 | "outputs": [ |
887 | 887 | { |
888 | 888 | "data": { |
889 | 889 | "application/vnd.jupyter.widget-view+json": { |
890 | | - "model_id": "83c35f21b9d54774994c17ae25e3af18", |
| 890 | + "model_id": "ee3f4dcd64ac4d78b2798e130b74482e", |
891 | 891 | "version_major": 2, |
892 | 892 | "version_minor": 0 |
893 | 893 | }, |
|
951 | 951 | }, |
952 | 952 | { |
953 | 953 | "cell_type": "code", |
954 | | - "execution_count": 44, |
| 954 | + "execution_count": 54, |
955 | 955 | "id": "61e1f71d", |
956 | 956 | "metadata": {}, |
957 | 957 | "outputs": [ |
958 | 958 | { |
959 | 959 | "data": { |
960 | 960 | "application/vnd.jupyter.widget-view+json": { |
961 | | - "model_id": "90631f9d30e14e7da3cb93ff1fc18c67", |
| 961 | + "model_id": "1e57ad8657ed4ab9839680be6e63dd34", |
962 | 962 | "version_major": 2, |
963 | 963 | "version_minor": 0 |
964 | 964 | }, |
|
1023 | 1023 | }, |
1024 | 1024 | { |
1025 | 1025 | "cell_type": "code", |
1026 | | - "execution_count": 45, |
| 1026 | + "execution_count": 55, |
1027 | 1027 | "id": "2670205b", |
1028 | 1028 | "metadata": {}, |
1029 | 1029 | "outputs": [ |
1030 | 1030 | { |
1031 | 1031 | "data": { |
1032 | 1032 | "application/vnd.jupyter.widget-view+json": { |
1033 | | - "model_id": "097e234d52ab474fa93ae5dd0b98fec8", |
| 1033 | + "model_id": "5f9900f2cef14d1f9a6b6d378d3a2595", |
1034 | 1034 | "version_major": 2, |
1035 | 1035 | "version_minor": 0 |
1036 | 1036 | }, |
|
1106 | 1106 | }, |
1107 | 1107 | { |
1108 | 1108 | "cell_type": "code", |
1109 | | - "execution_count": 46, |
| 1109 | + "execution_count": 57, |
1110 | 1110 | "id": "c127fa0c", |
1111 | 1111 | "metadata": { |
1112 | 1112 | "scrolled": false |
|
1115 | 1115 | { |
1116 | 1116 | "data": { |
1117 | 1117 | "application/vnd.jupyter.widget-view+json": { |
1118 | | - "model_id": "647b9af802ed4bdca3250797935e3442", |
| 1118 | + "model_id": "2a89c0152afd4008ba517d0da49309d8", |
1119 | 1119 | "version_major": 2, |
1120 | 1120 | "version_minor": 0 |
1121 | 1121 | }, |
|
1219 | 1219 | "ax.relim()\n", |
1220 | 1220 | "ax.autoscale_view()\n", |
1221 | 1221 | "\n", |
1222 | | - "# # Solve the LP\n", |
1223 | | - "# def run_pulp(cost_MV1, cost_MV2, MV1_Lo=-limits, MV2_Lo=-limits):\n", |
1224 | | - "# def run_lp(values):\n", |
1225 | | - "# prob = LpProblem(\"DMC_problem\",LpMinimize)\n", |
1226 | | - "# MV1=LpVariable(\"MV1\",-limits)\n", |
1227 | | - "# MV2=LpVariable(\"MV2\",-limits)\n", |
1228 | | - "# prob += values[2]*MV1 + values[3]*MV2, \"Cost function of MVs\"\n", |
| 1222 | + "# Solve the LP\n", |
| 1223 | + "def run_lp(values_dict):\n", |
| 1224 | + " '''\n", |
| 1225 | + " Run pulp solver for LP problem with the same gain matrix and CV limits as the example. Returns a tuple with:\n", |
| 1226 | + " (LP solution array [MV1_solution, MV2_solution], objective_value)\n", |
| 1227 | + " ''' \n", |
| 1228 | + " prob = LpProblem(\"DMC_problem\",LpMinimize)\n", |
| 1229 | + " \n", |
| 1230 | + " nMVs = 2\n", |
| 1231 | + " nCVs = 2\n", |
| 1232 | + " \n", |
| 1233 | + " # How many MVs\n", |
| 1234 | + " MVs = []\n", |
| 1235 | + " for i in range(nMVs):\n", |
| 1236 | + " MVs.append(LpVariable(f\"MV{i+1}\",-limits))\n", |
| 1237 | + " \n", |
| 1238 | + " # the objective function\n", |
| 1239 | + " obj = 0\n", |
| 1240 | + " for indx, MV in enumerate(MVs):\n", |
| 1241 | + " obj += values_dict[f\"MV{indx+1} Cost\"]*MV\n", |
| 1242 | + " \n", |
| 1243 | + " prob += obj, \"Cost function of MVs\"\n", |
| 1244 | + " \n", |
| 1245 | + " # constraint formulation in terms of MV1 and MV2\n", |
| 1246 | + " CV_contraint_lo = []\n", |
| 1247 | + " CV_contraint_hi = []\n", |
| 1248 | + " \n", |
| 1249 | + " for i in range(nCVs):\n", |
| 1250 | + " c = 0\n", |
| 1251 | + " for indx, MV in enumerate(MVs):\n", |
| 1252 | + " c += G[i][indx]*MV\n", |
| 1253 | + " prob += c <= values_dict[f'CV{i+1} Limits'][1], f'CV{i+1} High Limit'\n", |
| 1254 | + " prob += c >= values_dict[f'CV{i+1} Limits'][0], f'CV{i+1} Low Limit'\n", |
| 1255 | + " \n", |
| 1256 | + " for indx, MV in enumerate(MVs):\n", |
| 1257 | + " prob += MV <= values_dict[f'MV{indx+1} Limits'][1], f'MV{indx+1} High Limit'\n", |
| 1258 | + " prob += MV >= values_dict[f'MV{indx+1} Limits'][0], f'MV{indx+1} Low Limit' \n", |
1229 | 1259 | " \n", |
1230 | | - "# # constraint formulation in terms of MV1 and MV2\n", |
1231 | | - "# prob += G11*MV1+G12*MV2 <= values[0][1], \"CV1 High Limit\"\n", |
1232 | | - "# prob += G11*MV1+G12*MV2 >= values[0][0], \"CV1 Low Limit\"\n", |
1233 | | - "# prob += G21*MV1+G22*MV2 <= values[1][1], \"CV2 High Limit\"\n", |
1234 | | - "# prob += G21*MV1+G22*MV2 >= values[1][0], \"CV2 Low Limit\"\n", |
1235 | | - "# if (prob.solve(PULP_CBC_CMD(msg=0)) == 1):\n", |
1236 | | - "# return [v.varValue for v in prob.variables()], value(prob.objective)\n", |
1237 | | - "# else:\n", |
1238 | | - "# print(\"NOT SOLVED - Infeasibility!\")\n", |
1239 | | - "# return [0,0], 0\n", |
| 1260 | + " if (prob.solve(PULP_CBC_CMD(msg=0)) == 1):\n", |
| 1261 | + " return [v.varValue for v in prob.variables()], value(prob.objective)\n", |
| 1262 | + " else:\n", |
| 1263 | + " print(\"NOT SOLVED - Infeasibility!\")\n", |
| 1264 | + " return np.zeros(nMVs), 0\n", |
1240 | 1265 | "\n", |
1241 | 1266 | "def handle_slider_change(change):\n", |
1242 | 1267 | " ## grab slider values for CV contraints\n", |
1243 | 1268 | " values = [slider.value for slider in sliders]\n", |
| 1269 | + " values_dict = {}\n", |
| 1270 | + " values_dict['CV1 Limits'] = values[0]\n", |
| 1271 | + " values_dict['CV2 Limits'] = values[1]\n", |
| 1272 | + " values_dict['MV1 Limits'] = values[4]\n", |
| 1273 | + " values_dict['MV2 Limits'] = values[5]\n", |
| 1274 | + " values_dict['MV1 Cost'] = values[2]\n", |
| 1275 | + " values_dict['MV2 Cost'] = values[3]\n", |
| 1276 | + " \n", |
1244 | 1277 | " cost_MV1 = values[2]\n", |
1245 | 1278 | " cost_MV2 = values[3]\n", |
1246 | 1279 | " \n", |
|
1275 | 1308 | " q.set_UVC(-cost_MV1, -cost_MV2, z_obj)\n", |
1276 | 1309 | " \n", |
1277 | 1310 | " # Find the LP soln\n", |
1278 | | - " soln, V = run_pulp(cost_MV1, cost_MV2, MV1_Lo=values[4][0], MV1_Hi=values[4][1], MV2_Lo=values[5][0], MV2_Hi=values[5][1])\n", |
| 1311 | + " soln, V = run_lp(values_dict)\n", |
1279 | 1312 | " \n", |
1280 | 1313 | " if (V == None):\n", |
1281 | 1314 | " V = 0\n", |
|
1405 | 1438 | }, |
1406 | 1439 | { |
1407 | 1440 | "cell_type": "code", |
1408 | | - "execution_count": null, |
| 1441 | + "execution_count": 58, |
1409 | 1442 | "id": "94dd4426", |
1410 | 1443 | "metadata": {}, |
1411 | 1444 | "outputs": [], |
|
1460 | 1493 | }, |
1461 | 1494 | { |
1462 | 1495 | "cell_type": "code", |
1463 | | - "execution_count": null, |
| 1496 | + "execution_count": 59, |
1464 | 1497 | "id": "dea575d4", |
1465 | 1498 | "metadata": {}, |
1466 | | - "outputs": [], |
| 1499 | + "outputs": [ |
| 1500 | + { |
| 1501 | + "name": "stdout", |
| 1502 | + "output_type": "stream", |
| 1503 | + "text": [ |
| 1504 | + "\n", |
| 1505 | + "\u001b[0;31mNameError: \u001b[0mname 'n_frames' is not defined\n" |
| 1506 | + ] |
| 1507 | + }, |
| 1508 | + { |
| 1509 | + "data": { |
| 1510 | + "application/vnd.jupyter.widget-view+json": { |
| 1511 | + "model_id": "e7cbddc90f454ac99ec1980582ed5c70", |
| 1512 | + "version_major": 2, |
| 1513 | + "version_minor": 0 |
| 1514 | + }, |
| 1515 | + "text/plain": [ |
| 1516 | + "Button(description='Click to show stack trace', layout=Layout(height='auto', width='auto'), style=ButtonStyle(…" |
| 1517 | + ] |
| 1518 | + }, |
| 1519 | + "metadata": {}, |
| 1520 | + "output_type": "display_data" |
| 1521 | + } |
| 1522 | + ], |
1467 | 1523 | "source": [ |
1468 | 1524 | "from matplotlib import animation\n", |
1469 | 1525 | "anim = animation.FuncAnimation(fig, drawframe, frames=n_frames, interval=200)\n", |
1470 | 1526 | "from IPython.display import HTML\n", |
1471 | 1527 | "HTML(anim.to_jshtml())" |
1472 | 1528 | ] |
| 1529 | + }, |
| 1530 | + { |
| 1531 | + "cell_type": "code", |
| 1532 | + "execution_count": null, |
| 1533 | + "id": "5ef2ab86", |
| 1534 | + "metadata": {}, |
| 1535 | + "outputs": [], |
| 1536 | + "source": [] |
1473 | 1537 | } |
1474 | 1538 | ], |
1475 | 1539 | "metadata": { |
|
0 commit comments