paramak
Advanced tools
| <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="100" height="100" viewBox="0 0 1170 1063"> | ||
| <metadata><?xpacket begin="" id="W5M0MpCehiHzreSzNTczkc9d"?> | ||
| <x:xmpmeta xmlns:x="adobe:ns:meta/" x:xmptk="Adobe XMP Core 5.6-c138 79.159824, 2016/09/14-01:09:01 "> | ||
| <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"> | ||
| <rdf:Description rdf:about=""/> | ||
| </rdf:RDF> | ||
| </x:xmpmeta> | ||
| <?xpacket end="w"?></metadata> | ||
| <image width="1170" height="1063" xlink:href="data:image/png;base64,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JEEQSZIkCCJJkgRBJEmSIIgkSRIEkSRJgiCSJEkQRJIkCYJIkiRBEEmSJAgiSZIEQSRJkiCIJEkSBJEkSYIgkiRJEESSJAmCSJIkQRBJkiQIIkmSBEEkSZIgiCRJEgSRJEmCIJIkSRBEkiQJgkiSJEEQSZIkCCJJkgRBJEmSIIgkSRIEkSRJgiCSJEkQRJIkCYJIkiRBEEmSJAgiSZIEQSRJkiCIJEkSBJEkSYIgkiRJEESSJAmCSJIkQRBJkiQIIkmSBEEkSZIgiCRJEgSRJEmCIJIkSRBEkiQJgkiSJEEQSZIkCCJJkgRBJEmSIIgkSRIEkSRJgiCSJEkQRJIkCYJIkiRBEEmSJAgiSZIEQSRJkiCIJEkSBJEkSYIgkiRJEESSJAmCSJIkQRBJkiQIIkmSBEEkSZIgiCRJEgSRJEmCIJIkSRBEkiQJgkiSJEEQSZIkCCJJkgRBJEmSIIgkSRIEkSRJgiCSJEkQRJIkCYJIkiRBEEmSJAgiSZIEQSRJkiCIJEkSBJEkSYIgkiRJEESSJAmCSJIkQRBJkiQIIkmSBEEkSZIgiCRJEgSRJEmCIJIkSRBEkiQJgkiSJEEQSZIkCCJJkgRBJEmSIIgkSRIEkSRJgiCSJEkQRJIkCYJIkiRBEEmSJAgiSZIEQSRJkiCIJEkSBJEkSYIgkiRJEESSJAmCSJIkQRBJkiQIIkmSBEEkSZIgiCRJEgSRJEmCIJIkSRBEkiQJgkiSJEEQSZIkCCJJkgRBJEmSIIgkSRIEkSRJgiCSJEkQRJIkCYJIkiRBEEmSJAgiSZIEQSRJkiCIJEkSBJEkSYIgkiRJEESSJAmCSJIkQRBJkiQIIkmSBEEkSZIgiCRJEgSRJEmCIJIkSRBEkiQJgkiSJEEQSZIkCCJJkgRBJEmSIIgkSRIEkSRJgiCSJEkQRJIkCYJIkiRBEEmSJAgiSZIEQSRJkiCIJEkSBJEkSYIgkiRJEESSJAmCSJIkQRBJkiQIIkmSBEEkSZIgiCRJEgSRJEmCIJIkSRBEkiQJgkiSJEEQSZIkCCJJkgRBJEmSIIgkSRIEkSRJgiCSJEkQRJIkCYJIkiRBEEmSJAgiSZIEQSRJkiCIJEkSBJEkSYIgkiRJEESSJAmCSJIkQRBJkiQIIkmSBEEkSZIgiCRJEgSRJEmCIJIkSRBEkiQJgkiSJEEQSZIkCCJJkgRBJEmSIIgkSRIEkSRJgiCSJEkQRJIkCYJIkiRBEEmSJAgiSZIEQSRJkiCIJEkSBJEkSYIgkiRJEESSJAmCSJIkQRBJkiQIIkmSBEEkSZIgiCRJEgSRJEmCIJIkSRBEkiQJgkiSJEEQSZIkCCJJkgRBJEmSIIgkSRIEkSRJgiCSJEkQRJIkCYJIkiRBEEmSJAgiSZIEQSRJkiCIJEkSBJEkSYIgkiRJEESSJAmCSJIkQRBJkiQIIkmSBEEkSZIgiCRJEgSRJEmCIJIkSRBEkiQJgkiSJEEQSZIkCCJJkgRBJEmSIIgkSRIEkSRJgiCSJEkQRJIkCYJIkiRBEEmSJAgiSZIEQSRJkiCIJEkSBJEkSYIgkiRJEESSJAmCSJIkQRBJkiQIIkmSBEEkSZIgiCRJEgSRJEmCIJIkSRBEkiQJgkiSJEEQSZIkCCJJkgRBJEmSIIgkSRIEkSRJgiCSJEkQRJIkCYJIkiRBEEmSJAgiSZIEQSRJkiCIJEkSBJEkSYIgkiRJEESSJAmCSJIkQRBJkiQIIkmSBEEkSZIgiCRJEgSRJEmCIJIkSRBEkiQJgkiSJEEQSZIkCCJJkgRBJEmSIIgkSRIEkSRJgiCSJEkQRJIkCYJIkiRBEEmSJAgiSZIEQSRJkiCIJEkSBJEkSYIgkiRJEESSJAmCSJIkQRBJkiQIIkmSBEEkSZIgiCRJEgSRJEmCIJIkSRBEkiQJgkiSJEEQSZIkCCJJkgRBJEmSIIgkSRIEkSRJgiCSJEkQRJIkCYJIkiRBEEmSJAgiSZIEQSRJkiCIJEkSBJEkSYIgkiRJEESSJAmCSJIkQRBJkiQIIkmSBEEkSZIgiCRJEgSRJEmCIJIkSRBEkiQJgkiSJEEQSZIkCCJJkgRBJEmSIIgkSRIEkSRJgiCSJEkQRJIkCYJIkiRBEEmSJAgiSZIEQSRJkiCIJEkSBJEkSYIgkiRJEESSJAmCSJIkQRBJkiQIIkmSBEEkSZIgiCRJEgSRJEmCIJIkSRBEkiQJgkiSJEEQSZIkCCJJkgRBJEmSIIgkSRIEkSRJgiCSJEkQRJIkCYJIkiRBEEmSJAgiSZIEQSRJkiCIJEkSBJEkSYIgkiRJEESSJAmCSJIkQRBJkiQIIkmSBEEkSZIgiCRJEgSRJEmCIJIkSRBEkiQJgkiSJEEQSZIkCCJJkgRBJEmSIIgkSRIEkSRJgiCSJEkQRJIkCYJIkiRBEEmSJAgiSZIEQSRJkiCIJEkSBJEkSYIgkiRJEESSJAmCSJIkQRBJkiQIIkmSBEEkSZIgiCRJEgSRJEmCIJIkSRBEkiQJgkiSJEEQSZIkCCJJkgRBJEmSIIgkSRIEkSRJgiCSJEkQRJIkCYJIkiRBEEmSJAgiSZIEQSRJkiCIJEkSBJEkSYIgkiRJEESSJAmCSJIkQRBJkiQIIkmSBEEkSZIgiCRJEgSRJEmCIJIkSRBEkiQJgkiSJEEQSZIkCCJJkgRBJEmSIIgkSRIEkSRJgiCSJEkQRJIkCYJIkiRBEEmSJAgiSZIEQSRJkiCIJEkSBJEkSYIgkiRJEESSJAmCSJIkQRBJkiQIIkmSBEEkSZIgiCRJEgSRJEmCIJIkSRBEkiQJgkiSJEEQSZIkCCJJkgRBJEmSIIgkSRIEkSRJgiCSJEkQRJIkCYJIkiSd5/7m9d3dm9snd3d3NzfVE51mevvvTA8ZM43TTA//zvQ2Yaa/iSRJ0rNevX64/dUP7t37u7J9e/X24fbxVzPd3t3cF810//bulzM93t69rZrp7yNJkvRnb9+8++NP7/bDx+NnevjzTJ/ujp/p5uHTn2d6cLl0FkmSpD94+/6cH+C7h1dHzvTm8ayZjqzSzVkzPb5RpedJkiT9zquHc/bsyafXB8109+7smd59OOZu6T5wpr+YJEnSr93cXvZTfLxbv2w3by6c6YDLt1cXzvT5zZGXlH8hSZKkX7k0SCero3TNTKsDcHGQDpjpLydJkvRfH69Z/s9ro/TqrMdav/CwcKZrgnQiSr8nSZL0s/trF+0f794umukFB/Xxw6If1N35z9r+M5ND9zuSJEk/eXv9op3crrgAuDn/AfIvZ1rx6dvNpxfN9Mmnb78mSZL0g/tr74++eZz+4dv9w4v/jedfKL18JufulyTJ0fjezcsukZ68n/v05uPLLpGe3E6e6WWXSE8+Hf9C519AkiTpO5OOw7uZu/Z6zkyPM2+UXs8o9z8zLXry9leTJEn65uU3bV9NvHl7wbP2n8yb6eU3bc7eb0mSY/HV/Yybkck/1KkzvZk007xK/jOTt7l/IkmS9H8f59yMfDVl/6cWKXOmT5r0I0mSpCeTizRl/6c82P7ehP2fXCRN+pkkSdIX04s0oUkLZnrx/k8vkib9RJIk6WTB9r+4Sfezr5FOPr1wpvlF0qQfSZIk/ePViiK9sElLtj9zJk36jiRJ0rJNe9lL06tmekmTZn7WNmum3UiSJI1x5Rf/z3D9u4Crtv8l7yet2xZn8BtJchwmvvn3H4/Xvsf9YeE/+LUzvV04k/e4v5IkSVq5adc+Jvm4cqbH62Za9MDt/zP5DUr/J0ntk7R00z5/frhmpiUftv3r/VU/qFUPt5688KPAfUhS+ySte5D05JpbkmlftvuNax67r16V5sfwG0nqfhZWPrT54orbpKW3kl9muvw2aemt5Bd+VckXktQ8SYtv204uvnVbfNt2cnvxD2rtbduJW7cvJKl5klbfIp1c+puKFn4C+M2lt5NHLMqq3xH+d5Gk3km6OeIHfOF//6+OmOndZbeT9+svJq/+JHAzktQ7SetvR04uezlx9fP2a/7V1724+T0vcQ9JOmmcpEm/RPY57y6Z6ZALtwsvSQ65cPuHl5Mk6aRxktY/R35yyWXSMRdJl/2zH3OR5DLpRJI6J+mgi6SLLpMOuki66DLpqIskl0lDkk76JumYJ0kn518mHfER4KX/7kddJLlMGpJ00jZJh12QXPCh23EXJOdfuh3ycdsTH7pJ0ufGSTruP//zX00+4p2kr869dFv+gvt3vJskSX2TdH/kD/ncO5LjLkjO//btUR8CnFz04eSWJKlvko78z//z43kzLf922w/Oe5i8/ttt32v/TTdJ6puk4x5un5x3l3Tcw+2T8+6SjryXvPKXuexEktom6cAHySdn3SUdei957kP3I+/b3LlJ0ue2STr0vu3MO7dj79vOu3M79r7NnZsktU3SsfdI5333/sjPAE/OuZs8ekWaHseyn/d/jeoBup6Bo3/M5zwkOfYe6by7yWMfuV3zq5z2Ikldk3Tge5JPznhwc/DjrbPuJg9+vPWP6pNRTJK6Jun4f/nnX0w+7Dt33zz/4ObwdF/8G+82I0ldk3TUF+7/9fyqHftx+8nzD5OO35Ce57HwB/6zUT1A0yNw5GvS5/6cj8/k8w+4jv4U4No/6bQNSWqapOMfkZzxnZLjZ3r+WfLRT9zbv5kkSU2TdPwjkufX//Cn2+c83z5+ps/VZ6OWJDVN0sEvSj79Uz+jIJPPznT0i5InvV+WlKSmSar4h39upopMPvfMvSKTvT9yk6SmSTr6PemT51at4jAmztT7dyZJUtMkHf/h1vPrf/w7AM+/BVCxIC0PZOlP/EejeoCeJyAxSRUzPfePL0lHk6SmJyBx/RNnqrjB7f03ASSpaZISf9CJSaqYqfcXbyVJkmJ+0JL0RJJqjeoBJCnlBy1JTySp1qgeQJJSftCS9ESSao3qASQp5QctSU8kqdaoHqBnkqz/eTP5xO1okiRJh/Fe0pyZ9iZJTU9AYpK8vf2k5YEs/Yn/aFQP0PME+I7beTNVfBXYd9xqjeoBeibJbwJ44jcBpJGkpkk6/jfv+31J5/L7kmqN6gF6JslvlfzCb5WMI0lNk+R3b3+R+Lu3z/iDdzuTpKZJ8hdKvvAXSuJIUtckHb9q/o7beXqex8If+M9G9QBNj8Dx//LPz3T8M/dXz87kr90eTJK6JunwVTvjEcnhz7fP+ZNpR8/0ufpkFJOkrkk6/Of+/GOb458ln/NtsqMfcPX+0q0knTRN0tEPk865Hzn6nfLnHyUdvyJNj2PZz/u/RvUAXc/Awe9KP/8G0D/eHvxPf3/GTEe/LNn7RUlJOmmapIMf3Jz3GzeOfTXhvDeAjr2bPOfx1tYkqW2SxqdDf8pvz5rp2Du3877feuyrCec8ctuaJPVN0qEfuZ9133b0ndvzrwCcHHvn1v2+TZI+903Sod8pOfc3JR5553bua9JHXk42/zbJkKSTrkk69C7p3P/8j7xLOu9e8tgPAs75DHBvktQ4SQe+LXn2yzYHPnQ/+0Hy/XGXbo/nfAa4N0lqnKQD3wI8/z//4y7dzv/ljcddurV/uC1JJ32TdNgD7gs+2T7s0u2CC5LjLt3Oe+C+NUnqnKTDXrm55AnJUZdul/yzH3Xp1vvPJT2RpNZJOugy6aLX/w66TLroqc1Rl0kukiTppHGSDrokuexjpGO+fHfZv/oxT5M8SRqSdNI5SYdcklz43fZDLkku/N7GIR+6+bjtRJJ6J+mQpySXvpB8xKE8952kr454N6n332/7SpKaJ+mA//4vvh25X//U/fLfb73+FW4vbn8hSc2TtP6//3eX344sv518vPw58vpvurX/dtsTSeqepOVPk6/5VdKrnyZf87WN1avS/Bh+I0ntz8LiW7erPkW6X3ubdN2fJVo7U/ffb/uNJLVP0trbpCsfkCy9TbriVvLk1cp2X3EruSlJkqSVh+DqTVv4EufjtQ9tVv4yp+Z/Kek7kiRJKx8nXb9p695OuP73f6z7KMDn/99IkiQtfHTzkt/+s+rF8pf8c6/qpO+2/UuSJGksexPoRV+QWNTJl23/mk56tP0dSZKkk48rHt2+8P/+JU1KnOmTL5J8R5Ik6YsFTXrx3ciC/U+cSZF+IEmS9GR6kyY8H5m+/4kzKdKPJEmS/u/j3F2b8sR28v7PmWnu86RbRfqRJEnSV1P3f9Jf2rif+X7CrF9HNPNzN5+1/UySJOmb+2m79njp7/74vXlfd5v394jmvZ/kfaT/kCRJ+s6kXfs080vtr+c85Ho3c6a3c2Z69M72f0mSJH3v44wXlN7MfTwy5SHX+7kzvZox063vtf2CJEnSD17+8GbiTdvXmV588/Y4/wbp5Zvj3P2SJDkaP3n7sgulyZcjT25eNtOSy5EXXrxNvbndiSRJ0s9eclHybtXTkbvrn968m37Z9n8frp9pwWXbLiRJkv7r1ZV3b48Lf5Svrvw48PFu3Ys/V8f7wctIvyVJkvQrN1e8D7hy+U+uiVLiTJ/feKz9B5IkSb92c+GyvVu8/CeXBmB1kL7M9HDZ7dvjgyD9kSRJ0u+8ujv/ofLtvPcQ/+j+w/kzfTpqptfnP+j+9Not2zMkSZL+4O2bcy4BPn048j/+j2fN9O7Qi5GPD+eU8t2DT9meJ0mS9Gc3D3+8Bnh8f2iPnnz880yfbytmuvvz47fbOz06iyRJ0rPu397d/uoq4NObD2Vrdn9z9/43M9V9S+OfmX7Vyk/v73xz5GySJElnurm5u7t7f3vycHf3+ibhKe3Hmw93d2/+nSnhQuS7md7c3X2ImOlvIkmSBEEkSZIgiCRJEgSRJEmCIJIkSRBEkiQJgkiSJEEQSZIkCCJJkgRBJEmSIIgkSRIEkSRJgiCSJEkQRJIkCYJIkiRBEEmSJAgiSZIEQSRJkiCIJEkSBJEkSYIgkiRJEESSJAmCSJIkQRBJkiQIIkmSBEEkSZIgiCRJEgSRJEmCIJIkSRBEkiQJgkiSJEEQSZIkCCJJkgRBJEmSIIgkSRIEkSRJgiCSJEkQRJIkCYJIkiRBEEmSJAgiSZIEQSRJkiCIJEkSBJEkSYIgkiRJEESSJAmCSJIkQRBJkiQIIkmSBEEkSZIgiCRJEgSRJEmCIJIkSRBEkiQJgkiSJEEQSZIkCCJJkgRBJEmSIIgkSRIEkSRJgiCSJEkQRJIkCYJIkiRBEEmSJAgiSZIEQSRJkiCIJEkSBJEkSYIgkiRJEESSJAmCSJIkQRBJkiQIIkmSBEEkSZIgiCRJEgSRJEmCIJIkSRBEkiQJgkiSJEEQSZIkCCJJkgRBJEmSIIgkSRIEkSRJgiCSJEkQRJIkCYJIkiRBEEmSJAgiSZIEQSRJkiCIJEkSBJEkSYIgkiRJEESSJAmCSJIkQRBJkiQIIkmSBEEkSZIgiCRJEgSRJEmCIJIkSRBEkiQJgkiSJEEQSZIkCCJJkgRBJEmSIIgkSRIEkSRJgiCSJEkQRJIkCYJIkiRBEEmSJAgiSZIEQSRJkiCIJEkSBJEkSYIgkiRJEESSJAmCSJIkQRBJkiQIIkmSBEEkSZIgiCRJEgSRJEmCIJIkSRBEkiQJgkiSJEEQSZIkCCJJkgRBJEmSIIgkSRIEkSRJgiCSJEkQRJIkCYJIkiRBEEmSJAgiSZIEQSRJkiCIJEkSBJEkSYIgkiRJEESSJAmCSJIkQRBJkiQIIkmSBEEkSZIgiCRJEgSRJEmCIJIkSRBEkiQJgkiSJEEQSZIkCCJJkgRBJEmSIIgkSRIEkSRJgiCSJEkQRJIkCYJIkiRBEEmSJAgiSZIEQSRJkiCIJEkSBJEkSYIgkiRJEESSJAmCSJIkQRBJkiQIIkmSBEEkSZIgiCRJEgSRJEmCIJIkSRBEkiQJgkiSJEEQSZIkCCJJkgRBJOnz59u7BqoPGjNUn6Ij3Fb3ICBJLVQvEzNUn6IeRvUAPVQvEzNUn6IeRvUAPVQvEzNUn6IeRvUAPVQvEzNUn6IeRvUAPVQvEzNUn6IeRvUAPVQvEzNUn6IeRvUAPVQvEzNUn6IeRvUAPVQvEzNUn6IeRvUAPVQvEzNUn6IeRvUAPVQvEzNUn6IeRvUAPVQvEzNUn6IeRvUAPVQvEzNUn6IeRvUAPVQvEzNUn6IeRvUAPVQvEzNUn6IeRvUAPVQvEzNUn6IeRvUAPVQvEzNUn6IeRvUAPVQvEzNUn6IeRvUAPVQvEzNUn6IeRvUAPVQvEzNUn6IeRvUAPVQvEzNUn6IeRvUAPVQvEzNUn6IeRvUAPVQvEzNUn6IeRvUAPVQvEzNUn6IeRvUAPVQvEzNUn6IeRvUAPVQvEzNUn6IeRvUAPVQvEzNUn6IeRvUAPVQvEzNUn6IeRvUAPVQvEzNUn6IeRvUAPVQvEzNUn6IeRvUAPVQvEzNUn6IeRvUAPVQvEzNUn6IeRvUAPVQvEzNUn6IeRvUAPVQvEzNUn6IeRvUAPVQvEzNUn6IeRvUAPVQvEzNUn6IeRvUAPVQvEzNUn6IeRvUAPVQvEzNUn6IeRvUAPVQvEzNUn6IeRvUAPVQvEzNUn6IeRvUAPVQvEzNUn6IeRvUAPVQvEzNUn6IeRvUAPVQvEzNUn6IeRvUAPVQvEzNUn6IeRvUAPVQvEzNUn6IeRvUAPVQvEzNUn6IeRvUAPVQvEzNUn6IeRvUAPVQvEzNUn6IeRvUAPVQvEzNUn6IeRvUAPVQvEzNUn6IeRvUAPVQvEzNUn6IeRvUAPVQvEzNUn6IeRvUAPVQvEzNUn6IeRvUAPVQvEzNUn6IeRvUAPVQvEzNUn6IeRvUAPVQvEzNUn6IeRvUAPVQvEzNUn6IeRvUAPVQvEzNUn6IeRvUAPVQvEzNUn6IeRvUAPVQvEzNUn6IeRvUAPVQvEzNUn6IeRvUAPVQvEzNUn6IeRvUAPVQvEzNUn6IeRvUAPVQvEzNUn6IeRvUAPVQvEzNUn6IeRvUAPVQvEzNUn6IeRvUAPVQvEzNUn6IeRvUAPVQvEzNUn6IeRvUAPVQvEzNUn6IeRvUAPVQvEzNUn6IeRvUAPVQvEzNUn6IeRvUAPVQvEzNUn6IeRvUAPVQvEzNUn6IeRvUAPVQvEzNUn6IeRvUAPVQvEzNUn6IeRvUAPVQvEzNUn6IeRvUAPVQvEzNUn6IeRvUAPVQvEzNUn6IeRvUAPVQvEzNUn6IeRvUAPVQvEzNUn6IeRvUAPVQvEzNUn6IeRvUAPVQvEzNUn6IeRvUAPVQvEzNUn6IeRvUAPVQvEzNUn6IeRvUAPVQvEzNUn6IeRvUAPVQvEzNUn6IeRvUAPVQvEzNUn6IeRvUAPVQvEzNUn6IeRvUAPVQvEzNUn6IeRvUAPVQvEzNUn6IeRvUAPVQvEzNUn6IeRvUAPVQvEzNUn6IeRvUAPVQvEzNUn6IeRvUAPVQvEzNUn6IeRvUAPVQvEzNUn6IeRvUAPVQvEzNUn6IeRvUAPVQvEzNUn6IeRvUAPVQvEzNUn6IeRvUAPVQvEzNUn6IeRvUAPVQvEzNUn6IeRvUAPVQvEzNUn6IeRvUAPVQvEzNUn6IeRvUAPVQvEzNUn6IeRvUAPVQvEzNUn6IeRvUAPVQvEzNUn6IeRvUAPVQvEzNUn6IeRvUAPVQvEzNUn6IeRvUAPVQvEzNUn6IeRvUAPVQvEzNUn6IeRvUAPVQvEzNUn6IeRvUAPVQvEzNUn6IeRvUAPVQvEzNUn6IeRvUAPVQvEzNUn6IeRvUAPVQvEzNUn6IeRvUAPVQvEzNUn6IeRvUAPVQvEzNUn6IeRvUAPVQvEzNUn6IeRvUAPVQvEzNUn6IeRvUAPVQvEzNUn6IeRvUAPVQvEzNUn6IeRvUAPVQvEzNUn6IeRvUAPVQvEzNUn6IeRvUAPVQvEzNUn6IeRvUAPVQvEzNUn6IeRvUAPVQvEzNUn6IeRvUAPVQvEzNUn6IeRvUAPVQvEzNUn6IeRvUAPVQvEzNUn6IeRvUAPVQvEzNUn6IeRvUAPVQvEzNUn6Ie/gcLRxxOKlYQdAAAAABJRU5ErkJggg=="/> | ||
| </svg> |
Sorry, the diff of this file is not supported yet
| <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="100" height="100" viewBox="0 0 1194 1063"> | ||
| <metadata><?xpacket begin="" id="W5M0MpCehiHzreSzNTczkc9d"?> | ||
| <x:xmpmeta xmlns:x="adobe:ns:meta/" x:xmptk="Adobe XMP Core 5.6-c138 79.159824, 2016/09/14-01:09:01 "> | ||
| <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"> | ||
| <rdf:Description rdf:about=""/> | ||
| </rdf:RDF> | ||
| </x:xmpmeta> | ||
| <?xpacket end="w"?></metadata> | ||
| <image width="1194" height="1063" xlink:href="data:image/png;base64,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"/> | ||
| </svg> |
| @import url('https://fonts.googleapis.com/css2?family=Lato:ital,wght@0,400;0,700;0,900;1,400;1,700;1,900&family=Open+Sans:ital,wght@0,400;0,600;1,400;1,600&display=swap'); | ||
| body { | ||
| font-family: 'Open Sans', sans-serif; | ||
| } | ||
| h1 { | ||
| font-family: "Lato", sans-serif; | ||
| } | ||
| pre, | ||
| code { | ||
| font-size: 100%; | ||
| line-height: 155%; | ||
| } | ||
| /* Main page overview cards */ | ||
| .sd-card { | ||
| border-radius: 0; | ||
| padding: 30px 10px 20px 10px; | ||
| margin: 10px 0px; | ||
| } | ||
| .sd-card .sd-card-header { | ||
| text-align: center; | ||
| } | ||
| .sd-card .sd-card-title { | ||
| text-align: center; | ||
| } | ||
| .sd-card .sd-card-header .sd-card-text { | ||
| margin: 0px; | ||
| } | ||
| .sd-card .sd-card-img-top { | ||
| height: 52px; | ||
| width: 52px; | ||
| margin-left: auto; | ||
| margin-right: auto; | ||
| } | ||
| .sd-card .sd-card-header { | ||
| border: none; | ||
| font-size: var(--pst-font-size-h5); | ||
| font-weight: bold; | ||
| padding: 2.5rem 0rem 0.5rem 0rem; | ||
| } |
| <svg xmlns="http://www.w3.org/2000/svg" enable-background="new 0 0 24 24" height="24px" viewBox="0 0 24 24" width="24px" fill="#013243"><g><rect fill="none" height="24" width="24"/></g><g><g/><g><path d="M21,5c-1.11-0.35-2.33-0.5-3.5-0.5c-1.95,0-4.05,0.4-5.5,1.5c-1.45-1.1-3.55-1.5-5.5-1.5S2.45,4.9,1,6v14.65 c0,0.25,0.25,0.5,0.5,0.5c0.1,0,0.15-0.05,0.25-0.05C3.1,20.45,5.05,20,6.5,20c1.95,0,4.05,0.4,5.5,1.5c1.35-0.85,3.8-1.5,5.5-1.5 c1.65,0,3.35,0.3,4.75,1.05c0.1,0.05,0.15,0.05,0.25,0.05c0.25,0,0.5-0.25,0.5-0.5V6C22.4,5.55,21.75,5.25,21,5z M21,18.5 c-1.1-0.35-2.3-0.5-3.5-0.5c-1.7,0-4.15,0.65-5.5,1.5V8c1.35-0.85,3.8-1.5,5.5-1.5c1.2,0,2.4,0.15,3.5,0.5V18.5z"/><g><path d="M17.5,10.5c0.88,0,1.73,0.09,2.5,0.26V9.24C19.21,9.09,18.36,9,17.5,9c-1.7,0-3.24,0.29-4.5,0.83v1.66 C14.13,10.85,15.7,10.5,17.5,10.5z"/><path d="M13,12.49v1.66c1.13-0.64,2.7-0.99,4.5-0.99c0.88,0,1.73,0.09,2.5,0.26V11.9c-0.79-0.15-1.64-0.24-2.5-0.24 C15.8,11.66,14.26,11.96,13,12.49z"/><path d="M17.5,14.33c-1.7,0-3.24,0.29-4.5,0.83v1.66c1.13-0.64,2.7-0.99,4.5-0.99c0.88,0,1.73,0.09,2.5,0.26v-1.52 C19.21,14.41,18.36,14.33,17.5,14.33z"/></g></g></g></svg> |
| Spherical Tokamak | ||
| ================= | ||
| - This is characterized by a blanket that only goes around the outboard sides of the plasma and a center column that has no inboard breeding. | ||
| Spherical tokamak | ||
| ----------------- | ||
| - The spherical_tokamak function provides a parametric tokamak shaped reactor. | ||
| - This is characterized by a blanket that only goes around the outboard sides of the plasma. | ||
| - This reactor allows for a separate vertical and radial build which allows different thickness layers in the blanket. | ||
| .. cadquery:: | ||
| :gridsize: 0 | ||
| :select: result | ||
| :color: #00cd00 | ||
| :width: 100% | ||
| :height: 600px | ||
| import paramak | ||
| result = paramak.spherical_tokamak( | ||
| radial_build=[ | ||
| (paramak.LayerType.GAP, 10), | ||
| (paramak.LayerType.SOLID, 50), | ||
| (paramak.LayerType.SOLID, 10), | ||
| (paramak.LayerType.GAP, 50), | ||
| (paramak.LayerType.PLASMA, 300), | ||
| (paramak.LayerType.GAP, 60), | ||
| (paramak.LayerType.SOLID, 10), | ||
| (paramak.LayerType.SOLID, 60), | ||
| (paramak.LayerType.SOLID, 10), | ||
| ], | ||
| vertical_build=[ | ||
| (paramak.LayerType.SOLID, 15), | ||
| (paramak.LayerType.SOLID, 120), | ||
| (paramak.LayerType.SOLID, 10), | ||
| (paramak.LayerType.GAP, 50), | ||
| (paramak.LayerType.PLASMA, 700), | ||
| (paramak.LayerType.GAP, 60), | ||
| (paramak.LayerType.SOLID, 10), | ||
| (paramak.LayerType.SOLID, 30), | ||
| (paramak.LayerType.SOLID, 15), | ||
| ], | ||
| rotation_angle=180, | ||
| triangularity=0.55, | ||
| ).toCompound() | ||
| .. code-block:: python | ||
| import paramak | ||
| result = paramak.spherical_tokamak( | ||
| radial_build=[ | ||
| (paramak.LayerType.GAP, 10), | ||
| (paramak.LayerType.SOLID, 50), | ||
| (paramak.LayerType.SOLID, 10), | ||
| (paramak.LayerType.GAP, 50), | ||
| (paramak.LayerType.PLASMA, 300), | ||
| (paramak.LayerType.GAP, 60), | ||
| (paramak.LayerType.SOLID, 10), | ||
| (paramak.LayerType.SOLID, 60), | ||
| (paramak.LayerType.SOLID, 10), | ||
| ], | ||
| vertical_build=[ | ||
| (paramak.LayerType.SOLID, 15), | ||
| (paramak.LayerType.SOLID, 120), | ||
| (paramak.LayerType.SOLID, 10), | ||
| (paramak.LayerType.GAP, 50), | ||
| (paramak.LayerType.PLASMA, 700), | ||
| (paramak.LayerType.GAP, 60), | ||
| (paramak.LayerType.SOLID, 10), | ||
| (paramak.LayerType.SOLID, 30), | ||
| (paramak.LayerType.SOLID, 15), | ||
| ], | ||
| rotation_angle=180, | ||
| triangularity=0.55, | ||
| ) | ||
| result.save(f"spherical_tokamak_minimal.step") | ||
| Spherical tokamak from plasma | ||
| ----------------------------- | ||
| - The spherical_tokamak_from_plasma function provides a parametric tokamak shaped reactor. | ||
| - This reactor requires minimal arguments to create as it keeps the vertical build of the blanket layers the same thickness as the radial build. | ||
| .. cadquery:: | ||
| :gridsize: 0 | ||
| :select: result | ||
| :color: #00cd00 | ||
| :width: 100% | ||
| :height: 600px | ||
| import paramak | ||
| result = paramak.spherical_tokamak_from_plasma( | ||
| radial_build=[ | ||
| (paramak.LayerType.GAP, 10), | ||
| (paramak.LayerType.SOLID, 60), | ||
| (paramak.LayerType.SOLID, 20), | ||
| (paramak.LayerType.GAP, 60), | ||
| (paramak.LayerType.PLASMA, 300), | ||
| (paramak.LayerType.GAP, 60), | ||
| (paramak.LayerType.SOLID, 20), | ||
| (paramak.LayerType.SOLID, 120), | ||
| (paramak.LayerType.SOLID, 10), | ||
| ], | ||
| elongation=2, | ||
| triangularity=0.55, | ||
| rotation_angle=90, | ||
| ).toCompound() | ||
| .. code-block:: python | ||
| import paramak | ||
| result = paramak.spherical_tokamak_from_plasma( | ||
| radial_build=[ | ||
| (paramak.LayerType.GAP, 10), | ||
| (paramak.LayerType.SOLID, 60), | ||
| (paramak.LayerType.SOLID, 20), | ||
| (paramak.LayerType.GAP, 60), | ||
| (paramak.LayerType.PLASMA, 300), | ||
| (paramak.LayerType.GAP, 60), | ||
| (paramak.LayerType.SOLID, 20), | ||
| (paramak.LayerType.SOLID, 120), | ||
| (paramak.LayerType.SOLID, 10), | ||
| ], | ||
| elongation=2, | ||
| triangularity=0.55, | ||
| rotation_angle=90, | ||
| ) | ||
| result.save('reactor.step') | ||
| Spherical tokamak with divertor | ||
| ------------------------------- | ||
| - Reactors support adding additional extra intersect shapes that can be_divertor. | ||
| - This example adds a divertor to a spherical_tokamak_from_plasma reactor. | ||
| .. cadquery:: | ||
| :gridsize: 0 | ||
| :select: result | ||
| :color: #00cd00 | ||
| :width: 100% | ||
| :height: 600px | ||
| from cadquery import Workplane | ||
| # makes a rectangle that overlaps the lower blanket under the plasma | ||
| # the intersection of this and the layers will form the lower divertor | ||
| points = [(200, -700), (200, 0), (300, 0), (300, -700)] | ||
| divertor_lower = Workplane('XZ', origin=(0,0,0)).polyline(points).close().revolve(180) | ||
| result = paramak.spherical_tokamak_from_plasma( | ||
| radial_build=[ | ||
| (paramak.LayerType.GAP, 10), | ||
| (paramak.LayerType.SOLID, 50), | ||
| (paramak.LayerType.SOLID, 15), | ||
| (paramak.LayerType.GAP, 50), | ||
| (paramak.LayerType.PLASMA, 300), | ||
| (paramak.LayerType.GAP, 60), | ||
| (paramak.LayerType.SOLID, 15), | ||
| (paramak.LayerType.SOLID, 60), | ||
| (paramak.LayerType.SOLID, 10), | ||
| ], | ||
| elongation=2, | ||
| triangularity=0.55, | ||
| rotation_angle=180, | ||
| extra_intersect_shapes=[divertor_lower] | ||
| ).toCompound() | ||
| .. code-block:: python | ||
| from cadquery import Workplane | ||
| # makes a rectangle that overlaps the lower blanket under the plasma | ||
| # the intersection of this and the layers will form the lower divertor | ||
| points = [(200, -700), (200, 0), (300, 0), (300, -700)] | ||
| divertor_lower = Workplane('XZ', origin=(0,0,0)).polyline(points).close().revolve(180) | ||
| result = paramak.spherical_tokamak_from_plasma( | ||
| radial_build=[ | ||
| (paramak.LayerType.GAP, 10), | ||
| (paramak.LayerType.SOLID, 50), | ||
| (paramak.LayerType.SOLID, 15), | ||
| (paramak.LayerType.GAP, 50), | ||
| (paramak.LayerType.PLASMA, 300), | ||
| (paramak.LayerType.GAP, 60), | ||
| (paramak.LayerType.SOLID, 15), | ||
| (paramak.LayerType.SOLID, 60), | ||
| (paramak.LayerType.SOLID, 10), | ||
| ], | ||
| elongation=2, | ||
| triangularity=0.55, | ||
| rotation_angle=180, | ||
| extra_intersect_shapes=[divertor_lower] | ||
| ) | ||
| result.save('reactor.step') | ||
| Spherical tokamak with poloidal field coils | ||
| ------------------------------------------- | ||
| - All reactors support adding a sequence of CadQuery shapes (e.g. workplanes) to the reactor using the extra_cut_shapes argument | ||
| - This example adds PF coils to a spherical_tokamak_from_plasma reactor but and other reactor would also work. | ||
| .. cadquery:: | ||
| :gridsize: 0 | ||
| :select: result | ||
| :color: #00cd00 | ||
| :width: 100% | ||
| :height: 600px | ||
| import paramak | ||
| extra_cut_shapes = [] | ||
| for case_thickness, height, width, center_point in zip( | ||
| [10, 15, 15, 10], [20, 50, 50, 20], [20, 50, 50, 20], | ||
| [(500, 300), (560, 100), (560, -100), (500, -300)] | ||
| ): | ||
| extra_cut_shapes.append( | ||
| paramak.poloidal_field_coil( | ||
| height=height, width=width, center_point=center_point, rotation_angle=270 | ||
| ) | ||
| ) | ||
| extra_cut_shapes.append( | ||
| paramak.poloidal_field_coil_case( | ||
| coil_height=height, | ||
| coil_width=width, | ||
| casing_thickness=case_thickness, | ||
| rotation_angle=270, | ||
| center_point=center_point, | ||
| ) | ||
| ) | ||
| result = paramak.spherical_tokamak_from_plasma( | ||
| radial_build=[ | ||
| (paramak.LayerType.GAP, 10), | ||
| (paramak.LayerType.SOLID, 50), | ||
| (paramak.LayerType.SOLID, 15), | ||
| (paramak.LayerType.GAP, 50), | ||
| (paramak.LayerType.PLASMA, 300), | ||
| (paramak.LayerType.GAP, 60), | ||
| (paramak.LayerType.SOLID, 15), | ||
| (paramak.LayerType.SOLID, 60), | ||
| (paramak.LayerType.SOLID, 10), | ||
| ], | ||
| elongation=2, | ||
| triangularity=0.55, | ||
| rotation_angle=270, | ||
| extra_cut_shapes=extra_cut_shapes, | ||
| ).toCompound() | ||
| .. code-block:: python | ||
| import paramak | ||
| extra_cut_shapes = [] | ||
| for case_thickness, height, width, center_point in zip( | ||
| [10, 15, 15, 10], [20, 50, 50, 20], [20, 50, 50, 20], | ||
| [(500, 300), (560, 100), (560, -100), (500, -300)] | ||
| ): | ||
| extra_cut_shapes.append( | ||
| paramak.poloidal_field_coil( | ||
| height=height, width=width, center_point=center_point, rotation_angle=270 | ||
| ) | ||
| ) | ||
| extra_cut_shapes.append( | ||
| paramak.poloidal_field_coil_case( | ||
| coil_height=height, | ||
| coil_width=width, | ||
| casing_thickness=case_thickness, | ||
| rotation_angle=270, | ||
| center_point=center_point, | ||
| ) | ||
| ) | ||
| result = paramak.spherical_tokamak_from_plasma( | ||
| radial_build=[ | ||
| (paramak.LayerType.GAP, 10), | ||
| (paramak.LayerType.SOLID, 50), | ||
| (paramak.LayerType.SOLID, 15), | ||
| (paramak.LayerType.GAP, 50), | ||
| (paramak.LayerType.PLASMA, 300), | ||
| (paramak.LayerType.GAP, 60), | ||
| (paramak.LayerType.SOLID, 15), | ||
| (paramak.LayerType.SOLID, 60), | ||
| (paramak.LayerType.SOLID, 10), | ||
| ], | ||
| elongation=2, | ||
| triangularity=0.55, | ||
| rotation_angle=270, | ||
| extra_cut_shapes=extra_cut_shapes, | ||
| ) | ||
| result.save(f"spherical_tokamak_from_plasma_with_pf_magnets.step") | ||
| Spherical tokamak with toroidal field coils | ||
| ------------------------------------------- | ||
| - In a similar way to adding poloidal field coils one can also add toroidal field coils by making use of the extra_cut_shapes argument. | ||
| - All reactors support adding a sequence of CadQuery shapes (e.g. workplanes) to the reactor using the extra_cut_shapes argument | ||
| - This example adds TF coils to a spherical_tokamak_from_plasma reactor but and other reactor would also work. | ||
| - Also these are rectangle shaped TF coils but other shapes are also available. | ||
| .. cadquery:: | ||
| :gridsize: 0 | ||
| :select: result | ||
| :color: #00cd00 | ||
| :width: 100% | ||
| :height: 600px | ||
| import paramak | ||
| tf_style_1 = paramak.toroidal_field_coil_rectangle( | ||
| horizontal_start_point = (10, 520), | ||
| vertical_mid_point = (600, 0), | ||
| thickness = 50, | ||
| distance = 40, | ||
| rotation_angle = 180, | ||
| with_inner_leg = True, | ||
| azimuthal_placement_angles = [0, 30, 60, 90, 120, 150, 180], | ||
| ) | ||
| result1 = paramak.spherical_tokamak_from_plasma( | ||
| radial_build=[ | ||
| (paramak.LayerType.GAP, 70), | ||
| (paramak.LayerType.SOLID, 10), | ||
| (paramak.LayerType.SOLID, 10), | ||
| (paramak.LayerType.GAP, 50), | ||
| (paramak.LayerType.PLASMA, 300), | ||
| (paramak.LayerType.GAP, 60), | ||
| (paramak.LayerType.SOLID, 10), | ||
| (paramak.LayerType.SOLID, 60), | ||
| (paramak.LayerType.SOLID, 10), | ||
| ], | ||
| elongation=2.5, | ||
| rotation_angle=180, | ||
| triangularity=0.55, | ||
| extra_cut_shapes=[tf_style_1] | ||
| ).toCompound().translate((700, 0, 0)) | ||
| tf_style_2 = paramak.toroidal_field_coil_princeton_d( | ||
| r1=5, | ||
| r2=610, | ||
| azimuthal_placement_angles = [0, 30, 60, 90, 120, 150, 180], | ||
| rotation_angle = 180, | ||
| thickness = 50, | ||
| distance = 40 | ||
| ) | ||
| result2 = paramak.spherical_tokamak_from_plasma( | ||
| radial_build=[ | ||
| (paramak.LayerType.GAP, 70), | ||
| (paramak.LayerType.SOLID, 10), | ||
| (paramak.LayerType.SOLID, 10), | ||
| (paramak.LayerType.GAP, 50), | ||
| (paramak.LayerType.PLASMA, 300), | ||
| (paramak.LayerType.GAP, 60), | ||
| (paramak.LayerType.SOLID, 10), | ||
| (paramak.LayerType.SOLID, 60), | ||
| (paramak.LayerType.SOLID, 10), | ||
| ], | ||
| elongation=2.5, | ||
| rotation_angle=180, | ||
| triangularity=0.55, | ||
| extra_cut_shapes=[tf_style_2] | ||
| ).toCompound().translate((-700, 0, 0)) | ||
| import cadquery as cq | ||
| result = cq.Assembly() | ||
| result.add(result1) | ||
| result.add(result2) | ||
| result = result.toCompound() | ||
| .. code-block:: python | ||
| import paramak | ||
| tf_style_1 = paramak.toroidal_field_coil_rectangle( | ||
| horizontal_start_point = (10, 520), | ||
| vertical_mid_point = (600, 0), | ||
| thickness = 50, | ||
| distance = 40, | ||
| with_inner_leg = True, | ||
| rotation_angle = 180, | ||
| azimuthal_placement_angles = [0, 30, 60, 90, 120, 150, 180], | ||
| ) | ||
| result = paramak.spherical_tokamak_from_plasma( | ||
| radial_build=[ | ||
| (paramak.LayerType.GAP, 70), | ||
| (paramak.LayerType.SOLID, 10), | ||
| (paramak.LayerType.SOLID, 10), | ||
| (paramak.LayerType.GAP, 50), | ||
| (paramak.LayerType.PLASMA, 300), | ||
| (paramak.LayerType.GAP, 60), | ||
| (paramak.LayerType.SOLID, 10), | ||
| (paramak.LayerType.SOLID, 60), | ||
| (paramak.LayerType.SOLID, 10), | ||
| ], | ||
| elongation=2.5, | ||
| rotation_angle=180, | ||
| triangularity=0.55, | ||
| extra_cut_shapes=[tf_style_1] | ||
| ) | ||
| result.save(f"spherical_tokamak_with_rectangular_tf.step") | ||
| tf_style_2 = paramak.toroidal_field_coil_princeton_d( | ||
| r1=5, | ||
| r2=610, | ||
| azimuthal_placement_angles = [120, 150, 180], | ||
| rotation_angle = 180, | ||
| thickness = 50, | ||
| distance = 40 | ||
| ) | ||
| result2 = paramak.spherical_tokamak_from_plasma( | ||
| radial_build=[ | ||
| (paramak.LayerType.GAP, 70), | ||
| (paramak.LayerType.SOLID, 10), | ||
| (paramak.LayerType.SOLID, 10), | ||
| (paramak.LayerType.GAP, 50), | ||
| (paramak.LayerType.PLASMA, 300), | ||
| (paramak.LayerType.GAP, 60), | ||
| (paramak.LayerType.SOLID, 10), | ||
| (paramak.LayerType.SOLID, 60), | ||
| (paramak.LayerType.SOLID, 10), | ||
| ], | ||
| elongation=2.5, | ||
| rotation_angle=180, | ||
| triangularity=0.55, | ||
| extra_cut_shapes=[tf] | ||
| ) | ||
| result2.save(f"spherical_tokamak_with_princeton_tf.step") | ||
| Spherical tokamak with negative triangularity | ||
| --------------------------------------------- | ||
| - The triangularity argument can be set to a negative value to make a plasma with a negative triangularity. | ||
| - This example makes a spherical tokamak with a negative but this would work on any reactor. | ||
| .. cadquery:: | ||
| :gridsize: 0 | ||
| :select: result | ||
| :color: #00cd00 | ||
| :width: 100% | ||
| :height: 600px | ||
| import paramak | ||
| result = paramak.spherical_tokamak( | ||
| radial_build=[ | ||
| (paramak.LayerType.GAP, 10), | ||
| (paramak.LayerType.SOLID, 50), | ||
| (paramak.LayerType.SOLID, 15), | ||
| (paramak.LayerType.GAP, 50), | ||
| (paramak.LayerType.PLASMA, 300), | ||
| (paramak.LayerType.GAP, 60), | ||
| (paramak.LayerType.SOLID, 40), | ||
| (paramak.LayerType.SOLID, 60), | ||
| (paramak.LayerType.SOLID, 10), | ||
| ], | ||
| vertical_build=[ | ||
| (paramak.LayerType.SOLID, 15), | ||
| (paramak.LayerType.SOLID, 80), | ||
| (paramak.LayerType.SOLID, 10), | ||
| (paramak.LayerType.GAP, 50), | ||
| (paramak.LayerType.PLASMA, 700), | ||
| (paramak.LayerType.GAP, 60), | ||
| (paramak.LayerType.SOLID, 10), | ||
| (paramak.LayerType.SOLID, 40), | ||
| (paramak.LayerType.SOLID, 15), | ||
| ], | ||
| rotation_angle=180, | ||
| triangularity=-0.55, | ||
| ).toCompound() | ||
| .. code-block:: python | ||
| import paramak | ||
| result = paramak.spherical_tokamak( | ||
| radial_build=[ | ||
| (paramak.LayerType.GAP, 10), | ||
| (paramak.LayerType.SOLID, 50), | ||
| (paramak.LayerType.SOLID, 15), | ||
| (paramak.LayerType.GAP, 50), | ||
| (paramak.LayerType.PLASMA, 300), | ||
| (paramak.LayerType.GAP, 60), | ||
| (paramak.LayerType.SOLID, 10), | ||
| (paramak.LayerType.SOLID, 60), | ||
| (paramak.LayerType.SOLID, 10), | ||
| ], | ||
| vertical_build=[ | ||
| (paramak.LayerType.SOLID, 15), | ||
| (paramak.LayerType.SOLID, 80), | ||
| (paramak.LayerType.SOLID, 10), | ||
| (paramak.LayerType.GAP, 50), | ||
| (paramak.LayerType.PLASMA, 700), | ||
| (paramak.LayerType.GAP, 60), | ||
| (paramak.LayerType.SOLID, 10), | ||
| (paramak.LayerType.SOLID, 40), | ||
| (paramak.LayerType.SOLID, 15), | ||
| ], | ||
| rotation_angle=180, | ||
| triangularity=-0.55, | ||
| ) | ||
| result.save(f"spherical_tokamak_minimal.step") |
| Tokamak | ||
| ======= | ||
| - This is characterized by a continuous blanket that goes around the inboard and outboard sides of the plasma. | ||
| Tokamak | ||
| ------- | ||
| - The spherical_tokamak function provides a parametric tokamak shaped reactor. | ||
| - This is characterized by a blanket that only goes around the outboard sides of the plasma. | ||
| - This reactor allows for a separate vertical and radial build which allows different thickness layers in the blanket. | ||
| .. cadquery:: | ||
| :gridsize: 0 | ||
| :select: result | ||
| :color: #00cd00 | ||
| :width: 100% | ||
| :height: 600px | ||
| import paramak | ||
| result = paramak.tokamak( | ||
| radial_build=[ | ||
| (paramak.LayerType.GAP, 10), | ||
| (paramak.LayerType.SOLID, 30), | ||
| (paramak.LayerType.SOLID, 50), | ||
| (paramak.LayerType.SOLID, 10), | ||
| (paramak.LayerType.SOLID, 120), | ||
| (paramak.LayerType.SOLID, 20), | ||
| (paramak.LayerType.GAP, 60), | ||
| (paramak.LayerType.PLASMA, 300), | ||
| (paramak.LayerType.GAP, 60), | ||
| (paramak.LayerType.SOLID, 20), | ||
| (paramak.LayerType.SOLID, 120), | ||
| (paramak.LayerType.SOLID, 10), | ||
| ], | ||
| vertical_build=[ | ||
| (paramak.LayerType.SOLID, 15), | ||
| (paramak.LayerType.SOLID, 80), | ||
| (paramak.LayerType.SOLID, 10), | ||
| (paramak.LayerType.GAP, 50), | ||
| (paramak.LayerType.PLASMA, 700), | ||
| (paramak.LayerType.GAP, 60), | ||
| (paramak.LayerType.SOLID, 10), | ||
| (paramak.LayerType.SOLID, 40), | ||
| (paramak.LayerType.SOLID, 15), | ||
| ], | ||
| triangularity=0.55, | ||
| rotation_angle=180, | ||
| ).toCompound() | ||
| .. code-block:: python | ||
| import paramak | ||
| result = paramak.tokamak( | ||
| radial_build=[ | ||
| (paramak.LayerType.GAP, 10), | ||
| (paramak.LayerType.SOLID, 30), | ||
| (paramak.LayerType.SOLID, 50), | ||
| (paramak.LayerType.SOLID, 10), | ||
| (paramak.LayerType.SOLID, 120), | ||
| (paramak.LayerType.SOLID, 20), | ||
| (paramak.LayerType.GAP, 60), | ||
| (paramak.LayerType.PLASMA, 300), | ||
| (paramak.LayerType.GAP, 60), | ||
| (paramak.LayerType.SOLID, 20), | ||
| (paramak.LayerType.SOLID, 120), | ||
| (paramak.LayerType.SOLID, 10), | ||
| ], | ||
| vertical_build=[ | ||
| (paramak.LayerType.SOLID, 15), | ||
| (paramak.LayerType.SOLID, 80), | ||
| (paramak.LayerType.SOLID, 10), | ||
| (paramak.LayerType.GAP, 50), | ||
| (paramak.LayerType.PLASMA, 700), | ||
| (paramak.LayerType.GAP, 60), | ||
| (paramak.LayerType.SOLID, 10), | ||
| (paramak.LayerType.SOLID, 40), | ||
| (paramak.LayerType.SOLID, 15), | ||
| ], | ||
| triangularity=0.55, | ||
| rotation_angle=180, | ||
| ) | ||
| result.save(f"tokamak_minimal.step") | ||
| Tokamak from plasma | ||
| ------------------- | ||
| - The tokamak_from_plasma function provides a parametric tokamak shaped reactor. | ||
| - This reactor requires few arguments to create as it keeps the vertical build of the blanket layers the same thickness as the radial build. | ||
| .. cadquery:: | ||
| :gridsize: 0 | ||
| :select: result | ||
| :color: #00cd00 | ||
| :width: 100% | ||
| :height: 600px | ||
| import paramak | ||
| result = paramak.tokamak_from_plasma( | ||
| radial_build=[ | ||
| (paramak.LayerType.GAP, 10), | ||
| (paramak.LayerType.SOLID, 30), | ||
| (paramak.LayerType.SOLID, 50), | ||
| (paramak.LayerType.SOLID, 10), | ||
| (paramak.LayerType.SOLID, 120), | ||
| (paramak.LayerType.SOLID, 20), | ||
| (paramak.LayerType.GAP, 60), | ||
| (paramak.LayerType.PLASMA, 300), | ||
| (paramak.LayerType.GAP, 60), | ||
| (paramak.LayerType.SOLID, 20), | ||
| (paramak.LayerType.SOLID, 120), | ||
| (paramak.LayerType.SOLID, 10), | ||
| ], | ||
| elongation=2, | ||
| triangularity=0.55, | ||
| rotation_angle=90, | ||
| ).toCompound() | ||
| .. code-block:: python | ||
| import paramak | ||
| result = paramak.tokamak_from_plasma( | ||
| radial_build=[ | ||
| (paramak.LayerType.GAP, 10), | ||
| (paramak.LayerType.SOLID, 30), | ||
| (paramak.LayerType.SOLID, 50), | ||
| (paramak.LayerType.SOLID, 10), | ||
| (paramak.LayerType.SOLID, 120), | ||
| (paramak.LayerType.SOLID, 20), | ||
| (paramak.LayerType.GAP, 60), | ||
| (paramak.LayerType.PLASMA, 300), | ||
| (paramak.LayerType.GAP, 60), | ||
| (paramak.LayerType.SOLID, 20), | ||
| (paramak.LayerType.SOLID, 120), | ||
| (paramak.LayerType.SOLID, 10), | ||
| ], | ||
| elongation=2, | ||
| triangularity=0.55, | ||
| rotation_angle=90, | ||
| ) | ||
| Tokamak with divertor | ||
| --------------------- | ||
| TODO | ||
| Tokamak with poloidal field coils | ||
| --------------------------------- | ||
| TODO | ||
| Tokamak with toroidal field coils | ||
| --------------------------------- | ||
| TODO | ||
| Tokamak with negative triangularity | ||
| ----------------------------------- | ||
| - The triangularity argument can be set to a negative value to make a plasma with a negative triangularity. | ||
| - This example makes a tokamak with a negative but this would work on any reactor. | ||
| .. cadquery:: | ||
| :gridsize: 0 | ||
| :select: result | ||
| :color: #00cd00 | ||
| :width: 100% | ||
| :height: 600px | ||
| import paramak | ||
| result = paramak.tokamak( | ||
| radial_build=[ | ||
| (paramak.LayerType.GAP, 10), | ||
| (paramak.LayerType.SOLID, 30), | ||
| (paramak.LayerType.SOLID, 50), | ||
| (paramak.LayerType.SOLID, 10), | ||
| (paramak.LayerType.SOLID, 120), | ||
| (paramak.LayerType.SOLID, 20), | ||
| (paramak.LayerType.GAP, 60), | ||
| (paramak.LayerType.PLASMA, 300), | ||
| (paramak.LayerType.GAP, 60), | ||
| (paramak.LayerType.SOLID, 20), | ||
| (paramak.LayerType.SOLID, 120), | ||
| (paramak.LayerType.SOLID, 10), | ||
| ], | ||
| vertical_build=[ | ||
| (paramak.LayerType.SOLID, 15), | ||
| (paramak.LayerType.SOLID, 80), | ||
| (paramak.LayerType.SOLID, 10), | ||
| (paramak.LayerType.GAP, 50), | ||
| (paramak.LayerType.PLASMA, 700), | ||
| (paramak.LayerType.GAP, 60), | ||
| (paramak.LayerType.SOLID, 10), | ||
| (paramak.LayerType.SOLID, 40), | ||
| (paramak.LayerType.SOLID, 15), | ||
| ], | ||
| triangularity=-0.55, | ||
| rotation_angle=180, | ||
| ).toCompound() | ||
| .. code-block:: python | ||
| import paramak | ||
| result = paramak.tokamak( | ||
| radial_build=[ | ||
| (paramak.LayerType.GAP, 10), | ||
| (paramak.LayerType.SOLID, 30), | ||
| (paramak.LayerType.SOLID, 50), | ||
| (paramak.LayerType.SOLID, 10), | ||
| (paramak.LayerType.SOLID, 120), | ||
| (paramak.LayerType.SOLID, 20), | ||
| (paramak.LayerType.GAP, 60), | ||
| (paramak.LayerType.PLASMA, 300), | ||
| (paramak.LayerType.GAP, 60), | ||
| (paramak.LayerType.SOLID, 20), | ||
| (paramak.LayerType.SOLID, 120), | ||
| (paramak.LayerType.SOLID, 10), | ||
| ], | ||
| vertical_build=[ | ||
| (paramak.LayerType.SOLID, 15), | ||
| (paramak.LayerType.SOLID, 80), | ||
| (paramak.LayerType.SOLID, 10), | ||
| (paramak.LayerType.GAP, 50), | ||
| (paramak.LayerType.PLASMA, 700), | ||
| (paramak.LayerType.GAP, 60), | ||
| (paramak.LayerType.SOLID, 10), | ||
| (paramak.LayerType.SOLID, 40), | ||
| (paramak.LayerType.SOLID, 15), | ||
| ], | ||
| triangularity=-0.55, | ||
| rotation_angle=180, | ||
| ) | ||
| result.save(f"tokamak_minimal.step") | ||
| Tokamak with several customizations | ||
| ----------------------------------- | ||
| - Combining many of the examples together to produce a Tokamak | ||
| with extra blanket layers, a lower divertor, PF and TF coils. | ||
| .. cadquery:: | ||
| :gridsize: 0 | ||
| :select: result | ||
| :color: #00cd00 | ||
| :width: 100% | ||
| :height: 600px | ||
| import paramak | ||
| from cadquery import vis, Workplane | ||
| # makes a rectangle that overlaps the lower blanket under the plasma | ||
| # the intersection of this and the layers will form the lower divertor | ||
| points = [(300, -700), (300, 0), (400, 0), (400, -700)] | ||
| divertor_lower = Workplane('XZ', origin=(0,0,0)).polyline(points).close().revolve(180) | ||
| # creates a toroidal | ||
| tf = paramak.toroidal_field_coil_rectangle( | ||
| horizontal_start_point = (10, 520), | ||
| vertical_mid_point = (860, 0), | ||
| thickness = 50, | ||
| distance = 40, | ||
| with_inner_leg = True, | ||
| rotation_angle = 180, | ||
| azimuthal_placement_angles = [0, 30, 60, 90, 120, 150, 180], | ||
| ) | ||
| extra_cut_shapes = [tf] | ||
| # creates pf coil | ||
| for case_thickness, height, width, center_point in zip( | ||
| [10, 15, 15, 10], [20, 50, 50, 20], [20, 50, 50, 20], | ||
| [(730, 370), (810, 235), (810, -235), (730, -370)] | ||
| ): | ||
| extra_cut_shapes.append( | ||
| paramak.poloidal_field_coil( | ||
| height=height, width=width, center_point=center_point, rotation_angle=180 | ||
| ) | ||
| ) | ||
| extra_cut_shapes.append( | ||
| paramak.poloidal_field_coil_case( | ||
| coil_height=height, | ||
| coil_width=width, | ||
| casing_thickness=case_thickness, | ||
| rotation_angle=180, | ||
| center_point=center_point, | ||
| ) | ||
| ) | ||
| result = paramak.tokamak( | ||
| radial_build=[ | ||
| (paramak.LayerType.GAP, 10), | ||
| (paramak.LayerType.SOLID, 30), | ||
| (paramak.LayerType.SOLID, 50), | ||
| (paramak.LayerType.SOLID, 10), | ||
| (paramak.LayerType.SOLID, 60), | ||
| (paramak.LayerType.SOLID, 60), | ||
| (paramak.LayerType.SOLID, 20), | ||
| (paramak.LayerType.GAP, 60), | ||
| (paramak.LayerType.PLASMA, 300), | ||
| (paramak.LayerType.GAP, 60), | ||
| (paramak.LayerType.SOLID, 20), | ||
| (paramak.LayerType.SOLID, 60), | ||
| (paramak.LayerType.SOLID, 60), | ||
| (paramak.LayerType.SOLID, 10), | ||
| ], | ||
| vertical_build=[ | ||
| (paramak.LayerType.SOLID, 10), | ||
| (paramak.LayerType.SOLID, 50), | ||
| (paramak.LayerType.SOLID, 50), | ||
| (paramak.LayerType.SOLID, 20), | ||
| (paramak.LayerType.GAP, 60), | ||
| (paramak.LayerType.PLASMA, 650), | ||
| (paramak.LayerType.GAP, 60), | ||
| (paramak.LayerType.SOLID, 20), | ||
| (paramak.LayerType.SOLID, 50), | ||
| (paramak.LayerType.SOLID, 50), | ||
| (paramak.LayerType.SOLID, 10), | ||
| ], | ||
| triangularity=0.55, | ||
| rotation_angle=180, | ||
| extra_cut_shapes=extra_cut_shapes, | ||
| extra_intersect_shapes=[divertor_lower] | ||
| ).toCompound() | ||
| .. code-block:: python | ||
| import paramak | ||
| from cadquery import Workplane | ||
| # makes a rectangle that overlaps the lower blanket under the plasma | ||
| # the intersection of this and the layers will form the lower divertor | ||
| points = [(300, -700), (300, 0), (400, 0), (400, -700)] | ||
| divertor_lower = Workplane('XZ', origin=(0,0,0)).polyline(points).close().revolve(180) | ||
| # creates a toroidal | ||
| tf = paramak.toroidal_field_coil_rectangle( | ||
| horizontal_start_point = (10, 520), | ||
| vertical_mid_point = (860, 0), | ||
| thickness = 50, | ||
| distance = 40, | ||
| with_inner_leg = True, | ||
| rotation_angle = 180, | ||
| azimuthal_placement_angles = [0, 30, 60, 90, 120, 150, 180], | ||
| ) | ||
| extra_cut_shapes = [tf] | ||
| # creates pf coil | ||
| for case_thickness, height, width, center_point in zip( | ||
| [10, 15, 15, 10], [20, 50, 50, 20], [20, 50, 50, 20], | ||
| [(730, 370), (810, 235), (810, -235), (730, -370)] | ||
| ): | ||
| extra_cut_shapes.append( | ||
| paramak.poloidal_field_coil( | ||
| height=height, width=width, center_point=center_point, rotation_angle=180 | ||
| ) | ||
| ) | ||
| extra_cut_shapes.append( | ||
| paramak.poloidal_field_coil_case( | ||
| coil_height=height, | ||
| coil_width=width, | ||
| casing_thickness=case_thickness, | ||
| rotation_angle=180, | ||
| center_point=center_point, | ||
| ) | ||
| ) | ||
| my_reactor = paramak.tokamak( | ||
| radial_build=[ | ||
| (paramak.LayerType.GAP, 10), | ||
| (paramak.LayerType.SOLID, 30), | ||
| (paramak.LayerType.SOLID, 50), | ||
| (paramak.LayerType.SOLID, 10), | ||
| (paramak.LayerType.SOLID, 60), | ||
| (paramak.LayerType.SOLID, 60), | ||
| (paramak.LayerType.SOLID, 20), | ||
| (paramak.LayerType.GAP, 60), | ||
| (paramak.LayerType.PLASMA, 300), | ||
| (paramak.LayerType.GAP, 60), | ||
| (paramak.LayerType.SOLID, 20), | ||
| (paramak.LayerType.SOLID, 60), | ||
| (paramak.LayerType.SOLID, 60), | ||
| (paramak.LayerType.SOLID, 10), | ||
| ], | ||
| vertical_build=[ | ||
| (paramak.LayerType.SOLID, 10), | ||
| (paramak.LayerType.SOLID, 50), | ||
| (paramak.LayerType.SOLID, 50), | ||
| (paramak.LayerType.SOLID, 20), | ||
| (paramak.LayerType.GAP, 60), | ||
| (paramak.LayerType.PLASMA, 650), | ||
| (paramak.LayerType.GAP, 60), | ||
| (paramak.LayerType.SOLID, 20), | ||
| (paramak.LayerType.SOLID, 50), | ||
| (paramak.LayerType.SOLID, 50), | ||
| (paramak.LayerType.SOLID, 10), | ||
| ], | ||
| triangularity=0.55, | ||
| rotation_angle=180, | ||
| extra_cut_shapes=extra_cut_shapes, | ||
| extra_intersect_shapes=[divertor_lower] | ||
| ) | ||
| my_reactor.save(f"tokamak_with_customizations.step") |
| Visualization options | ||
| ===================== | ||
| The reactors (cadquery.Assembly objects) and components (cadquery.Workplane objects) can be visualized in a number of ways. | ||
| First option is to export them to STEP, BREP or STL file then open the file with your favorite CAD software for example `FreeCAD <https://www.freecad.org/>`_. | ||
| See the `CadQuery documentation on saving <https://cadquery.readthedocs.io/en/latest/importexport.html#exporting-step>`_ for more information. | ||
| Other options include the built in visualization tools in CadQuery | ||
| .. code-block:: python | ||
| from cadquery.vis import show | ||
| show(result) # where result is the returned reactor or component object | ||
| Jupyter_cadquery package can be installed (pip install jupyter-cadquery) which allows for interactive 3D visualization in a web browser. | ||
| This package can also be used to export portable html files with the 3D visualization. | ||
| .. code-block:: python | ||
| # pip install jupyter_cadquery | ||
| # might needed to downgrade pip with ... python -m pip install pip==24.0 | ||
| from jupyter_cadquery import show | ||
| view = show(result) # where result is the returned reactor or component object | ||
| view.export_html("3d.html") |
| Examples | ||
| ======== | ||
| There are two main reactors to choose from: | ||
| * Tokamak | ||
| * Spherical Tokamak. | ||
| The reactors can be varied in terms of their radial build, vertical build, elongation and triangularity which gives a lot of variability. | ||
| All reactors can be built with either: | ||
| * A radial and vertical build which gives more control of the size of components allowing reactor blankets to vary both radially and vertically. | ||
| * A radial build and plasma elongation which assumes the vertical build matches the radial build and allows the reactors to be built with a minimal number of parameters. | ||
| It is also easy to add additional components such as: | ||
| * divertors | ||
| * poloidal magnets | ||
| * toroidal magnets | ||
| * your own CadQuery shapes / workplanes | ||
| These examples show how to make various reactors with different options. | ||
| .. toctree:: | ||
| :maxdepth: 3 | ||
| examples_vis | ||
| examples_tokamak | ||
| examples_spherical_tokamak | ||
@@ -14,3 +14,3 @@ name: CI testing | ||
| test: | ||
| runs-on: ubuntu-latest | ||
| runs-on: ubuntu-22.04 | ||
| strategy: | ||
@@ -17,0 +17,0 @@ matrix: |
@@ -20,3 +20,3 @@ name: documentation release | ||
| name: Documentation | ||
| runs-on: ubuntu-latest | ||
| runs-on: ubuntu-22.04 | ||
| steps: | ||
@@ -23,0 +23,0 @@ - name: checkout actions |
+13
-2
@@ -17,3 +17,3 @@ # Configuration file for the Sphinx documentation builder. | ||
| project = "Paramak" | ||
| copyright = "2024, J. Shimwell" | ||
| copyright = "2024, Fusion Energy" | ||
| author = "J. Shimwell" | ||
@@ -38,2 +38,3 @@ | ||
| "sphinxcadquery.sphinxcadquery", | ||
| "sphinx_design", | ||
| ] | ||
@@ -50,4 +51,4 @@ | ||
| html_static_path = ["_static"] | ||
| html_css_files = ["paramak.css"] | ||
| # TODO add logo | ||
@@ -67,2 +68,3 @@ # html_favicon = "favicon.ico" | ||
| html_theme_options = { | ||
| # "primary_sidebar_end": ["sidebar-nav-bs"], | ||
| "github_url": "https://github.com/fusion-energy/paramak", | ||
@@ -74,2 +76,11 @@ "switcher": { | ||
| "navbar_start": ["version-switcher", "navbar-icon-links"], | ||
| "show_nav_level": 3, | ||
| "collapse_navigation": True, | ||
| "show_version_warning_banner": True, | ||
| } | ||
| html_sidebars = { | ||
| "**": ["sidebar-nav-bs"] | ||
| } | ||
| html_favicon = '_static/favicon.ico' | ||
| master_doc = "index" |
+57
-5
@@ -5,4 +5,16 @@ | ||
| **Version**: |version| | ||
| .. toctree:: | ||
| :maxdepth: 3 | ||
| :caption: Contents: | ||
| :hidden: | ||
| install | ||
| examples | ||
| python_api | ||
| Parameter driven CAD creation for fusion reactors. | ||
@@ -15,7 +27,47 @@ | ||
| .. toctree:: | ||
| :maxdepth: 3 | ||
| install | ||
| usage | ||
| python_api | ||
| .. grid:: 1 1 3 3 | ||
| :gutter: 2 | ||
| .. grid-item-card:: | ||
| :img-top: _static/getting_started.svg | ||
| :text-align: center | ||
| Installation | ||
| ^^^ | ||
| .. button-ref:: install | ||
| :expand: | ||
| :color: secondary | ||
| :click-parent: | ||
| To the installation guide | ||
| .. grid-item-card:: | ||
| :img-top: _static/user_guide.svg | ||
| :text-align: center | ||
| Examples | ||
| ^^^ | ||
| .. button-ref:: examples | ||
| :expand: | ||
| :color: secondary | ||
| :click-parent: | ||
| To the examples | ||
| .. grid-item-card:: | ||
| :img-top: _static/api.svg | ||
| :text-align: center | ||
| API reference | ||
| ^^^ | ||
| .. button-ref:: python_api | ||
| :expand: | ||
| :color: secondary | ||
| :click-parent: | ||
| To the reference guide | ||
+40
-42
| Install | ||
| ======= | ||
| Prerequisites | ||
| ------------- | ||
| Paramak is distributed via `PyPI <https://pypi.org/project/paramak/>`_ and can be installed using pip. | ||
| To use of Paramak you will need Python 3 installed using Miniconda or Anaconda, or Miniforge | ||
| .. code-block:: bash | ||
| * `Miniforge <https://github.com/conda-forge/miniforge>`_ recommended as it includes Mamba | ||
| * `Miniconda <https://docs.conda.io/en/latest/miniconda.html>`_ | ||
| * `Anaconda <https://www.anaconda.com/>`_ | ||
| pip install paramak | ||
| .. Prerequisites | ||
| .. ------------- | ||
| Once you have a version of Mamba or Conda installed then proceed with the Paramak specific steps. | ||
| .. To use of Paramak you will need Python 3 installed using Miniconda or Anaconda, or Miniforge | ||
| .. * `Miniforge <https://github.com/conda-forge/miniforge>`_ recommended as it includes Mamba | ||
| .. * `Miniconda <https://docs.conda.io/en/latest/miniconda.html>`_ | ||
| .. * `Anaconda <https://www.anaconda.com/>`_ | ||
| Install (mamba) | ||
| --------------- | ||
| This is the recommended method as it installs all the dependencies and Mamba is faster and requires less RAM than the pure Conda method. | ||
| Create a new environment (with your preferred python version). | ||
| .. Once you have a version of Mamba or Conda installed then proceed with the Paramak specific steps. | ||
| .. code-block:: bash | ||
| mamba create --name paramak_env python=3.11 | ||
| .. Install (mamba) | ||
| .. --------------- | ||
| .. This is the recommended method as it installs all the dependencies and Mamba is faster and requires less RAM than the pure Conda method. | ||
| Then activate the new environment. | ||
| .. Create a new environment (with your preferred python version). | ||
| .. code-block:: bash | ||
| .. .. code-block:: bash | ||
| mamba activate paramak_env | ||
| .. mamba create --name paramak_env python=3.11 | ||
| Then install the Paramak. | ||
| .. Then activate the new environment. | ||
| .. code-block:: bash | ||
| .. .. code-block:: bash | ||
| mamba install -c conda-forge paramak | ||
| .. mamba activate paramak_env | ||
| Now you should be ready to import paramak from your new python environment. | ||
| Install (conda) | ||
| --------------- | ||
| .. Then install the Paramak. | ||
| Create a new environment (with your preferred python version). | ||
| .. .. code-block:: bash | ||
| .. code-block:: bash | ||
| .. mamba install -c conda-forge paramak | ||
| conda create --name paramak_env python=3.11 | ||
| .. Now you should be ready to import paramak from your new python environment. | ||
| .. Install (conda) | ||
| .. --------------- | ||
| Then activate the new environment. | ||
| .. Create a new environment (with your preferred python version). | ||
| .. code-block:: bash | ||
| .. .. code-block:: bash | ||
| conda activate paramak_env | ||
| .. conda create --name paramak_env python=3.11 | ||
| Then install the Paramak. | ||
| .. code-block:: bash | ||
| .. Then activate the new environment. | ||
| mamba install -c conda-forge paramak | ||
| .. .. code-block:: bash | ||
| Now you should be ready to import paramak from your new python environment. | ||
| .. conda activate paramak_env | ||
| .. Then install the Paramak. | ||
| .. .. code-block:: bash | ||
| .. mamba install -c conda-forge paramak | ||
| .. Now you should be ready to import paramak from your new python environment. | ||
| Developer Installation | ||
@@ -75,3 +82,3 @@ ---------------------- | ||
| If you want to contribute to the paramak or then you might want to install the | ||
| package in a more dynamic manner. | ||
| package in a more dynamic manner so that your changes to the code are readily available. | ||
@@ -81,11 +88,2 @@ Download and install MiniConda, create a new python environment and activate the | ||
| Then install CadQuery with Conda, Mamba or pip. | ||
| .. code-block:: bash | ||
| conda install -c conda-forge cadquery | ||
| mamba install -c conda-forge cadquery | ||
| pip install cadquery | ||
| Then clone the repository | ||
@@ -92,0 +90,0 @@ |
@@ -11,7 +11,4 @@ Python API reference | ||
| .. autofunction:: tokamak | ||
| .. autofunction:: tokamak_from_plasma | ||
| .. autofunction:: spherical_tokamak | ||
| .. autofunction:: spherical_tokamak_from_plasma | ||
@@ -18,0 +15,0 @@ |
@@ -13,6 +13,6 @@ [ | ||
| { | ||
| "name": "0.9.3", | ||
| "version": "0.9.3", | ||
| "url": "https://fusion-energy.github.io/paramak/0.9.3" | ||
| "name": "0.9.4", | ||
| "version": "0.9.4", | ||
| "url": "https://fusion-energy.github.io/paramak/0.9.4" | ||
| } | ||
| ] |
+2
-1
| Metadata-Version: 2.1 | ||
| Name: paramak | ||
| Version: 0.9.4 | ||
| Version: 0.9.5 | ||
| Summary: Create 3D fusion reactor CAD models based on input parameters | ||
@@ -34,2 +34,3 @@ Author: The Paramak Development Team | ||
| Requires-Dist: ipython; extra == "docs" | ||
| Requires-Dist: sphinx_design; extra == "docs" | ||
@@ -36,0 +37,0 @@ |
+2
-1
@@ -49,3 +49,4 @@ [build-system] | ||
| "cadquery", | ||
| "ipython" | ||
| "ipython", | ||
| "sphinx_design" | ||
| ] | ||
@@ -52,0 +53,0 @@ |
+2
-2
@@ -15,3 +15,3 @@ # file generated by setuptools_scm | ||
| __version__ = version = '0.9.4' | ||
| __version_tuple__ = version_tuple = (0, 9, 4) | ||
| __version__ = version = '0.9.5' | ||
| __version_tuple__ = version_tuple = (0, 9, 5) |
| Metadata-Version: 2.1 | ||
| Name: paramak | ||
| Version: 0.9.4 | ||
| Version: 0.9.5 | ||
| Summary: Create 3D fusion reactor CAD models based on input parameters | ||
@@ -34,2 +34,3 @@ Author: The Paramak Development Team | ||
| Requires-Dist: ipython; extra == "docs" | ||
| Requires-Dist: sphinx_design; extra == "docs" | ||
@@ -36,0 +37,0 @@ |
@@ -15,2 +15,3 @@ cadquery | ||
| ipython | ||
| sphinx_design | ||
@@ -17,0 +18,0 @@ [tests] |
@@ -12,2 +12,6 @@ .gitignore | ||
| docs/conf.py | ||
| docs/examples.rst | ||
| docs/examples_spherical_tokamak.rst | ||
| docs/examples_tokamak.rst | ||
| docs/examples_vis.rst | ||
| docs/index.rst | ||
@@ -17,7 +21,8 @@ docs/install.rst | ||
| docs/python_api.rst | ||
| docs/usage.rst | ||
| docs/usage_spherical_tokamak.rst | ||
| docs/usage_tokamak.rst | ||
| docs/usage_vis.rst | ||
| docs/version_switcher.json | ||
| docs/_static/api.svg | ||
| docs/_static/favicon.ico | ||
| docs/_static/getting_started.svg | ||
| docs/_static/paramak.css | ||
| docs/_static/user_guide.svg | ||
| examples/example_util_functions.py | ||
@@ -24,0 +29,0 @@ examples/plasma.py |
@@ -178,9 +178,10 @@ from typing import Optional, Sequence, Tuple, Union | ||
| # make vertical build from outer radial build | ||
| # make vertical build from inner radial build | ||
| pi = get_plasma_index(radial_build) | ||
| upper_vertical_build = radial_build[pi:] | ||
| rbi = len(radial_build)-1 - pi # number of unique entries in outer or inner radial build | ||
| upper_vertical_build = radial_build[pi-rbi:pi][::-1] #get the inner radial build | ||
| plasma_height = 2 * minor_radius * elongation | ||
| # slice opperation reverses the list and removes the last value to avoid two plasmas | ||
| vertical_build = upper_vertical_build[::-1][:-1] + [(LayerType.PLASMA, plasma_height)] + upper_vertical_build[1:] | ||
| vertical_build = upper_vertical_build[::-1] + [(LayerType.PLASMA, plasma_height)] + upper_vertical_build | ||
@@ -187,0 +188,0 @@ return tokamak( |
| Spherical Tokamak | ||
| ================= | ||
| - This is characterized by a blanket that only goes around the outboard sides of the plasma and a center column that has no inboard breeding. | ||
| Spherical tokamak | ||
| ----------------- | ||
| - The spherical_tokamak function provides a parametric tokamak shaped reactor. | ||
| - This is characterized by a blanket that only goes around the outboard sides of the plasma. | ||
| - This reactor allows for a separate vertical and radial build which allows different thickness layers in the blanket. | ||
| .. cadquery:: | ||
| :gridsize: 0 | ||
| :select: result | ||
| :color: #00cd00 | ||
| :width: 100% | ||
| :height: 600px | ||
| import paramak | ||
| result = paramak.spherical_tokamak( | ||
| radial_build=[ | ||
| (paramak.LayerType.GAP, 10), | ||
| (paramak.LayerType.SOLID, 50), | ||
| (paramak.LayerType.SOLID, 10), | ||
| (paramak.LayerType.GAP, 50), | ||
| (paramak.LayerType.PLASMA, 300), | ||
| (paramak.LayerType.GAP, 60), | ||
| (paramak.LayerType.SOLID, 10), | ||
| (paramak.LayerType.SOLID, 60), | ||
| (paramak.LayerType.SOLID, 10), | ||
| ], | ||
| vertical_build=[ | ||
| (paramak.LayerType.SOLID, 15), | ||
| (paramak.LayerType.SOLID, 120), | ||
| (paramak.LayerType.SOLID, 10), | ||
| (paramak.LayerType.GAP, 50), | ||
| (paramak.LayerType.PLASMA, 700), | ||
| (paramak.LayerType.GAP, 60), | ||
| (paramak.LayerType.SOLID, 10), | ||
| (paramak.LayerType.SOLID, 30), | ||
| (paramak.LayerType.SOLID, 15), | ||
| ], | ||
| rotation_angle=180, | ||
| triangularity=0.55, | ||
| ).toCompound() | ||
| .. code-block:: python | ||
| import paramak | ||
| result = paramak.spherical_tokamak( | ||
| radial_build=[ | ||
| (paramak.LayerType.GAP, 10), | ||
| (paramak.LayerType.SOLID, 50), | ||
| (paramak.LayerType.SOLID, 10), | ||
| (paramak.LayerType.GAP, 50), | ||
| (paramak.LayerType.PLASMA, 300), | ||
| (paramak.LayerType.GAP, 60), | ||
| (paramak.LayerType.SOLID, 10), | ||
| (paramak.LayerType.SOLID, 60), | ||
| (paramak.LayerType.SOLID, 10), | ||
| ], | ||
| vertical_build=[ | ||
| (paramak.LayerType.SOLID, 15), | ||
| (paramak.LayerType.SOLID, 120), | ||
| (paramak.LayerType.SOLID, 10), | ||
| (paramak.LayerType.GAP, 50), | ||
| (paramak.LayerType.PLASMA, 700), | ||
| (paramak.LayerType.GAP, 60), | ||
| (paramak.LayerType.SOLID, 10), | ||
| (paramak.LayerType.SOLID, 30), | ||
| (paramak.LayerType.SOLID, 15), | ||
| ], | ||
| rotation_angle=180, | ||
| triangularity=0.55, | ||
| ) | ||
| result.save(f"spherical_tokamak_minimal.step") | ||
| Spherical tokamak from plasma | ||
| ----------------------------- | ||
| - The spherical_tokamak_from_plasma function provides a parametric tokamak shaped reactor. | ||
| - This reactor requires minimal arguments to create as it keeps the vertical build of the blanket layers the same thickness as the radial build. | ||
| .. cadquery:: | ||
| :gridsize: 0 | ||
| :select: result | ||
| :color: #00cd00 | ||
| :width: 100% | ||
| :height: 600px | ||
| import paramak | ||
| result = paramak.spherical_tokamak_from_plasma( | ||
| radial_build=[ | ||
| (paramak.LayerType.GAP, 10), | ||
| (paramak.LayerType.SOLID, 60), | ||
| (paramak.LayerType.SOLID, 20), | ||
| (paramak.LayerType.GAP, 60), | ||
| (paramak.LayerType.PLASMA, 300), | ||
| (paramak.LayerType.GAP, 60), | ||
| (paramak.LayerType.SOLID, 20), | ||
| (paramak.LayerType.SOLID, 120), | ||
| (paramak.LayerType.SOLID, 10), | ||
| ], | ||
| elongation=2, | ||
| triangularity=0.55, | ||
| rotation_angle=90, | ||
| ).toCompound() | ||
| .. code-block:: python | ||
| import paramak | ||
| result = paramak.spherical_tokamak_from_plasma( | ||
| radial_build=[ | ||
| (paramak.LayerType.GAP, 10), | ||
| (paramak.LayerType.SOLID, 60), | ||
| (paramak.LayerType.SOLID, 20), | ||
| (paramak.LayerType.GAP, 60), | ||
| (paramak.LayerType.PLASMA, 300), | ||
| (paramak.LayerType.GAP, 60), | ||
| (paramak.LayerType.SOLID, 20), | ||
| (paramak.LayerType.SOLID, 120), | ||
| (paramak.LayerType.SOLID, 10), | ||
| ], | ||
| elongation=2, | ||
| triangularity=0.55, | ||
| rotation_angle=90, | ||
| ) | ||
| result.save('reactor.step') | ||
| Spherical tokamak with divertor | ||
| ------------------------------- | ||
| - Reactors support adding additional extra intersect shapes that can be_divertor. | ||
| - This example adds a divertor to a spherical_tokamak_from_plasma reactor. | ||
| .. cadquery:: | ||
| :gridsize: 0 | ||
| :select: result | ||
| :color: #00cd00 | ||
| :width: 100% | ||
| :height: 600px | ||
| from cadquery import Workplane | ||
| # makes a rectangle that overlaps the lower blanket under the plasma | ||
| # the intersection of this and the layers will form the lower divertor | ||
| points = [(200, -700), (200, 0), (300, 0), (300, -700)] | ||
| divertor_lower = Workplane('XZ', origin=(0,0,0)).polyline(points).close().revolve(180) | ||
| result = paramak.spherical_tokamak_from_plasma( | ||
| radial_build=[ | ||
| (paramak.LayerType.GAP, 10), | ||
| (paramak.LayerType.SOLID, 50), | ||
| (paramak.LayerType.SOLID, 15), | ||
| (paramak.LayerType.GAP, 50), | ||
| (paramak.LayerType.PLASMA, 300), | ||
| (paramak.LayerType.GAP, 60), | ||
| (paramak.LayerType.SOLID, 15), | ||
| (paramak.LayerType.SOLID, 60), | ||
| (paramak.LayerType.SOLID, 10), | ||
| ], | ||
| elongation=2, | ||
| triangularity=0.55, | ||
| rotation_angle=180, | ||
| extra_intersect_shapes=[divertor_lower] | ||
| ).toCompound() | ||
| .. code-block:: python | ||
| from cadquery import Workplane | ||
| # makes a rectangle that overlaps the lower blanket under the plasma | ||
| # the intersection of this and the layers will form the lower divertor | ||
| points = [(200, -700), (200, 0), (300, 0), (300, -700)] | ||
| divertor_lower = Workplane('XZ', origin=(0,0,0)).polyline(points).close().revolve(180) | ||
| result = paramak.spherical_tokamak_from_plasma( | ||
| radial_build=[ | ||
| (paramak.LayerType.GAP, 10), | ||
| (paramak.LayerType.SOLID, 50), | ||
| (paramak.LayerType.SOLID, 15), | ||
| (paramak.LayerType.GAP, 50), | ||
| (paramak.LayerType.PLASMA, 300), | ||
| (paramak.LayerType.GAP, 60), | ||
| (paramak.LayerType.SOLID, 15), | ||
| (paramak.LayerType.SOLID, 60), | ||
| (paramak.LayerType.SOLID, 10), | ||
| ], | ||
| elongation=2, | ||
| triangularity=0.55, | ||
| rotation_angle=180, | ||
| extra_intersect_shapes=[divertor_lower] | ||
| ) | ||
| result.save('reactor.step') | ||
| Spherical tokamak with poloidal field coils | ||
| ------------------------------------------- | ||
| - All reactors support adding a sequence of CadQuery shapes (e.g. workplanes) to the reactor using the extra_cut_shapes argument | ||
| - This example adds PF coils to a spherical_tokamak_from_plasma reactor but and other reactor would also work. | ||
| .. cadquery:: | ||
| :gridsize: 0 | ||
| :select: result | ||
| :color: #00cd00 | ||
| :width: 100% | ||
| :height: 600px | ||
| import paramak | ||
| extra_cut_shapes = [] | ||
| for case_thickness, height, width, center_point in zip( | ||
| [10, 15, 15, 10], [20, 50, 50, 20], [20, 50, 50, 20], | ||
| [(500, 300), (560, 100), (560, -100), (500, -300)] | ||
| ): | ||
| extra_cut_shapes.append( | ||
| paramak.poloidal_field_coil( | ||
| height=height, width=width, center_point=center_point, rotation_angle=270 | ||
| ) | ||
| ) | ||
| extra_cut_shapes.append( | ||
| paramak.poloidal_field_coil_case( | ||
| coil_height=height, | ||
| coil_width=width, | ||
| casing_thickness=case_thickness, | ||
| rotation_angle=270, | ||
| center_point=center_point, | ||
| ) | ||
| ) | ||
| result = paramak.spherical_tokamak_from_plasma( | ||
| radial_build=[ | ||
| (paramak.LayerType.GAP, 10), | ||
| (paramak.LayerType.SOLID, 50), | ||
| (paramak.LayerType.SOLID, 15), | ||
| (paramak.LayerType.GAP, 50), | ||
| (paramak.LayerType.PLASMA, 300), | ||
| (paramak.LayerType.GAP, 60), | ||
| (paramak.LayerType.SOLID, 15), | ||
| (paramak.LayerType.SOLID, 60), | ||
| (paramak.LayerType.SOLID, 10), | ||
| ], | ||
| elongation=2, | ||
| triangularity=0.55, | ||
| rotation_angle=270, | ||
| extra_cut_shapes=extra_cut_shapes, | ||
| ).toCompound() | ||
| .. code-block:: python | ||
| import paramak | ||
| extra_cut_shapes = [] | ||
| for case_thickness, height, width, center_point in zip( | ||
| [10, 15, 15, 10], [20, 50, 50, 20], [20, 50, 50, 20], | ||
| [(500, 300), (560, 100), (560, -100), (500, -300)] | ||
| ): | ||
| extra_cut_shapes.append( | ||
| paramak.poloidal_field_coil( | ||
| height=height, width=width, center_point=center_point, rotation_angle=270 | ||
| ) | ||
| ) | ||
| extra_cut_shapes.append( | ||
| paramak.poloidal_field_coil_case( | ||
| coil_height=height, | ||
| coil_width=width, | ||
| casing_thickness=case_thickness, | ||
| rotation_angle=270, | ||
| center_point=center_point, | ||
| ) | ||
| ) | ||
| result = paramak.spherical_tokamak_from_plasma( | ||
| radial_build=[ | ||
| (paramak.LayerType.GAP, 10), | ||
| (paramak.LayerType.SOLID, 50), | ||
| (paramak.LayerType.SOLID, 15), | ||
| (paramak.LayerType.GAP, 50), | ||
| (paramak.LayerType.PLASMA, 300), | ||
| (paramak.LayerType.GAP, 60), | ||
| (paramak.LayerType.SOLID, 15), | ||
| (paramak.LayerType.SOLID, 60), | ||
| (paramak.LayerType.SOLID, 10), | ||
| ], | ||
| elongation=2, | ||
| triangularity=0.55, | ||
| rotation_angle=270, | ||
| extra_cut_shapes=extra_cut_shapes, | ||
| ) | ||
| result.save(f"spherical_tokamak_from_plasma_with_pf_magnets.step") | ||
| Spherical tokamak with toroidal field coils | ||
| ------------------------------------------- | ||
| - In a similar way to adding poloidal field coils one can also add toroidal field coils by making use of the extra_cut_shapes argument. | ||
| - All reactors support adding a sequence of CadQuery shapes (e.g. workplanes) to the reactor using the extra_cut_shapes argument | ||
| - This example adds TF coils to a spherical_tokamak_from_plasma reactor but and other reactor would also work. | ||
| - Also these are rectangle shaped TF coils but other shapes are also available. | ||
| .. cadquery:: | ||
| :gridsize: 0 | ||
| :select: result | ||
| :color: #00cd00 | ||
| :width: 100% | ||
| :height: 600px | ||
| import paramak | ||
| tf_style_1 = paramak.toroidal_field_coil_rectangle( | ||
| horizontal_start_point = (10, 520), | ||
| vertical_mid_point = (600, 0), | ||
| thickness = 50, | ||
| distance = 40, | ||
| rotation_angle = 180, | ||
| with_inner_leg = True, | ||
| azimuthal_placement_angles = [0, 30, 60, 90, 120, 150, 180], | ||
| ) | ||
| result1 = paramak.spherical_tokamak_from_plasma( | ||
| radial_build=[ | ||
| (paramak.LayerType.GAP, 70), | ||
| (paramak.LayerType.SOLID, 10), | ||
| (paramak.LayerType.SOLID, 10), | ||
| (paramak.LayerType.GAP, 50), | ||
| (paramak.LayerType.PLASMA, 300), | ||
| (paramak.LayerType.GAP, 60), | ||
| (paramak.LayerType.SOLID, 10), | ||
| (paramak.LayerType.SOLID, 60), | ||
| (paramak.LayerType.SOLID, 10), | ||
| ], | ||
| elongation=2.5, | ||
| rotation_angle=180, | ||
| triangularity=0.55, | ||
| extra_cut_shapes=[tf_style_1] | ||
| ).toCompound().translate((700, 0, 0)) | ||
| tf_style_2 = paramak.toroidal_field_coil_princeton_d( | ||
| r1=5, | ||
| r2=610, | ||
| azimuthal_placement_angles = [0, 30, 60, 90, 120, 150, 180], | ||
| rotation_angle = 180, | ||
| thickness = 50, | ||
| distance = 40 | ||
| ) | ||
| result2 = paramak.spherical_tokamak_from_plasma( | ||
| radial_build=[ | ||
| (paramak.LayerType.GAP, 70), | ||
| (paramak.LayerType.SOLID, 10), | ||
| (paramak.LayerType.SOLID, 10), | ||
| (paramak.LayerType.GAP, 50), | ||
| (paramak.LayerType.PLASMA, 300), | ||
| (paramak.LayerType.GAP, 60), | ||
| (paramak.LayerType.SOLID, 10), | ||
| (paramak.LayerType.SOLID, 60), | ||
| (paramak.LayerType.SOLID, 10), | ||
| ], | ||
| elongation=2.5, | ||
| rotation_angle=180, | ||
| triangularity=0.55, | ||
| extra_cut_shapes=[tf_style_2] | ||
| ).toCompound().translate((-700, 0, 0)) | ||
| import cadquery as cq | ||
| result = cq.Assembly() | ||
| result.add(result1) | ||
| result.add(result2) | ||
| result = result.toCompound() | ||
| .. code-block:: python | ||
| import paramak | ||
| tf_style_1 = paramak.toroidal_field_coil_rectangle( | ||
| horizontal_start_point = (10, 520), | ||
| vertical_mid_point = (600, 0), | ||
| thickness = 50, | ||
| distance = 40, | ||
| with_inner_leg = True, | ||
| rotation_angle = 180, | ||
| azimuthal_placement_angles = [0, 30, 60, 90, 120, 150, 180], | ||
| ) | ||
| result = paramak.spherical_tokamak_from_plasma( | ||
| radial_build=[ | ||
| (paramak.LayerType.GAP, 70), | ||
| (paramak.LayerType.SOLID, 10), | ||
| (paramak.LayerType.SOLID, 10), | ||
| (paramak.LayerType.GAP, 50), | ||
| (paramak.LayerType.PLASMA, 300), | ||
| (paramak.LayerType.GAP, 60), | ||
| (paramak.LayerType.SOLID, 10), | ||
| (paramak.LayerType.SOLID, 60), | ||
| (paramak.LayerType.SOLID, 10), | ||
| ], | ||
| elongation=2.5, | ||
| rotation_angle=180, | ||
| triangularity=0.55, | ||
| extra_cut_shapes=[tf_style_1] | ||
| ) | ||
| result.save(f"spherical_tokamak_with_rectangular_tf.step") | ||
| tf_style_2 = paramak.toroidal_field_coil_princeton_d( | ||
| r1=5, | ||
| r2=610, | ||
| azimuthal_placement_angles = [120, 150, 180], | ||
| rotation_angle = 180, | ||
| thickness = 50, | ||
| distance = 40 | ||
| ) | ||
| result2 = paramak.spherical_tokamak_from_plasma( | ||
| radial_build=[ | ||
| (paramak.LayerType.GAP, 70), | ||
| (paramak.LayerType.SOLID, 10), | ||
| (paramak.LayerType.SOLID, 10), | ||
| (paramak.LayerType.GAP, 50), | ||
| (paramak.LayerType.PLASMA, 300), | ||
| (paramak.LayerType.GAP, 60), | ||
| (paramak.LayerType.SOLID, 10), | ||
| (paramak.LayerType.SOLID, 60), | ||
| (paramak.LayerType.SOLID, 10), | ||
| ], | ||
| elongation=2.5, | ||
| rotation_angle=180, | ||
| triangularity=0.55, | ||
| extra_cut_shapes=[tf] | ||
| ) | ||
| result2.save(f"spherical_tokamak_with_princeton_tf.step") | ||
| Spherical tokamak with negative triangularity | ||
| --------------------------------------------- | ||
| - The triangularity argument can be set to a negative value to make a plasma with a negative triangularity. | ||
| - This example makes a spherical tokamak with a negative but this would work on any reactor. | ||
| .. cadquery:: | ||
| :gridsize: 0 | ||
| :select: result | ||
| :color: #00cd00 | ||
| :width: 100% | ||
| :height: 600px | ||
| import paramak | ||
| result = paramak.spherical_tokamak( | ||
| radial_build=[ | ||
| (paramak.LayerType.GAP, 10), | ||
| (paramak.LayerType.SOLID, 50), | ||
| (paramak.LayerType.SOLID, 15), | ||
| (paramak.LayerType.GAP, 50), | ||
| (paramak.LayerType.PLASMA, 300), | ||
| (paramak.LayerType.GAP, 60), | ||
| (paramak.LayerType.SOLID, 40), | ||
| (paramak.LayerType.SOLID, 60), | ||
| (paramak.LayerType.SOLID, 10), | ||
| ], | ||
| vertical_build=[ | ||
| (paramak.LayerType.SOLID, 15), | ||
| (paramak.LayerType.SOLID, 80), | ||
| (paramak.LayerType.SOLID, 10), | ||
| (paramak.LayerType.GAP, 50), | ||
| (paramak.LayerType.PLASMA, 700), | ||
| (paramak.LayerType.GAP, 60), | ||
| (paramak.LayerType.SOLID, 10), | ||
| (paramak.LayerType.SOLID, 40), | ||
| (paramak.LayerType.SOLID, 15), | ||
| ], | ||
| rotation_angle=180, | ||
| triangularity=-0.55, | ||
| ).toCompound() | ||
| .. code-block:: python | ||
| import paramak | ||
| result = paramak.spherical_tokamak( | ||
| radial_build=[ | ||
| (paramak.LayerType.GAP, 10), | ||
| (paramak.LayerType.SOLID, 50), | ||
| (paramak.LayerType.SOLID, 15), | ||
| (paramak.LayerType.GAP, 50), | ||
| (paramak.LayerType.PLASMA, 300), | ||
| (paramak.LayerType.GAP, 60), | ||
| (paramak.LayerType.SOLID, 10), | ||
| (paramak.LayerType.SOLID, 60), | ||
| (paramak.LayerType.SOLID, 10), | ||
| ], | ||
| vertical_build=[ | ||
| (paramak.LayerType.SOLID, 15), | ||
| (paramak.LayerType.SOLID, 80), | ||
| (paramak.LayerType.SOLID, 10), | ||
| (paramak.LayerType.GAP, 50), | ||
| (paramak.LayerType.PLASMA, 700), | ||
| (paramak.LayerType.GAP, 60), | ||
| (paramak.LayerType.SOLID, 10), | ||
| (paramak.LayerType.SOLID, 40), | ||
| (paramak.LayerType.SOLID, 15), | ||
| ], | ||
| rotation_angle=180, | ||
| triangularity=-0.55, | ||
| ) | ||
| result.save(f"spherical_tokamak_minimal.step") |
| Tokamak | ||
| ======= | ||
| - This is characterized by a continuous blanket that goes around the inboard and outboard sides of the plasma. | ||
| Tokamak | ||
| ------- | ||
| - The spherical_tokamak function provides a parametric tokamak shaped reactor. | ||
| - This is characterized by a blanket that only goes around the outboard sides of the plasma. | ||
| - This reactor allows for a separate vertical and radial build which allows different thickness layers in the blanket. | ||
| .. cadquery:: | ||
| :gridsize: 0 | ||
| :select: result | ||
| :color: #00cd00 | ||
| :width: 100% | ||
| :height: 600px | ||
| import paramak | ||
| result = paramak.tokamak( | ||
| radial_build=[ | ||
| (paramak.LayerType.GAP, 10), | ||
| (paramak.LayerType.SOLID, 30), | ||
| (paramak.LayerType.SOLID, 50), | ||
| (paramak.LayerType.SOLID, 10), | ||
| (paramak.LayerType.SOLID, 120), | ||
| (paramak.LayerType.SOLID, 20), | ||
| (paramak.LayerType.GAP, 60), | ||
| (paramak.LayerType.PLASMA, 300), | ||
| (paramak.LayerType.GAP, 60), | ||
| (paramak.LayerType.SOLID, 20), | ||
| (paramak.LayerType.SOLID, 120), | ||
| (paramak.LayerType.SOLID, 10), | ||
| ], | ||
| vertical_build=[ | ||
| (paramak.LayerType.SOLID, 15), | ||
| (paramak.LayerType.SOLID, 80), | ||
| (paramak.LayerType.SOLID, 10), | ||
| (paramak.LayerType.GAP, 50), | ||
| (paramak.LayerType.PLASMA, 700), | ||
| (paramak.LayerType.GAP, 60), | ||
| (paramak.LayerType.SOLID, 10), | ||
| (paramak.LayerType.SOLID, 40), | ||
| (paramak.LayerType.SOLID, 15), | ||
| ], | ||
| triangularity=0.55, | ||
| rotation_angle=180, | ||
| ).toCompound() | ||
| .. code-block:: python | ||
| import paramak | ||
| result = paramak.tokamak( | ||
| radial_build=[ | ||
| (paramak.LayerType.GAP, 10), | ||
| (paramak.LayerType.SOLID, 30), | ||
| (paramak.LayerType.SOLID, 50), | ||
| (paramak.LayerType.SOLID, 10), | ||
| (paramak.LayerType.SOLID, 120), | ||
| (paramak.LayerType.SOLID, 20), | ||
| (paramak.LayerType.GAP, 60), | ||
| (paramak.LayerType.PLASMA, 300), | ||
| (paramak.LayerType.GAP, 60), | ||
| (paramak.LayerType.SOLID, 20), | ||
| (paramak.LayerType.SOLID, 120), | ||
| (paramak.LayerType.SOLID, 10), | ||
| ], | ||
| vertical_build=[ | ||
| (paramak.LayerType.SOLID, 15), | ||
| (paramak.LayerType.SOLID, 80), | ||
| (paramak.LayerType.SOLID, 10), | ||
| (paramak.LayerType.GAP, 50), | ||
| (paramak.LayerType.PLASMA, 700), | ||
| (paramak.LayerType.GAP, 60), | ||
| (paramak.LayerType.SOLID, 10), | ||
| (paramak.LayerType.SOLID, 40), | ||
| (paramak.LayerType.SOLID, 15), | ||
| ], | ||
| triangularity=0.55, | ||
| rotation_angle=180, | ||
| ) | ||
| result.save(f"tokamak_minimal.step") | ||
| Tokamak from plasma | ||
| ------------------- | ||
| - The tokamak_from_plasma function provides a parametric tokamak shaped reactor. | ||
| - This reactor requires few arguments to create as it keeps the vertical build of the blanket layers the same thickness as the radial build. | ||
| .. cadquery:: | ||
| :gridsize: 0 | ||
| :select: result | ||
| :color: #00cd00 | ||
| :width: 100% | ||
| :height: 600px | ||
| import paramak | ||
| result = paramak.tokamak_from_plasma( | ||
| radial_build=[ | ||
| (paramak.LayerType.GAP, 10), | ||
| (paramak.LayerType.SOLID, 30), | ||
| (paramak.LayerType.SOLID, 50), | ||
| (paramak.LayerType.SOLID, 10), | ||
| (paramak.LayerType.SOLID, 120), | ||
| (paramak.LayerType.SOLID, 20), | ||
| (paramak.LayerType.GAP, 60), | ||
| (paramak.LayerType.PLASMA, 300), | ||
| (paramak.LayerType.GAP, 60), | ||
| (paramak.LayerType.SOLID, 20), | ||
| (paramak.LayerType.SOLID, 120), | ||
| (paramak.LayerType.SOLID, 10), | ||
| ], | ||
| elongation=2, | ||
| triangularity=0.55, | ||
| rotation_angle=90, | ||
| ).toCompound() | ||
| .. code-block:: python | ||
| import paramak | ||
| result = paramak.tokamak_from_plasma( | ||
| radial_build=[ | ||
| (paramak.LayerType.GAP, 10), | ||
| (paramak.LayerType.SOLID, 30), | ||
| (paramak.LayerType.SOLID, 50), | ||
| (paramak.LayerType.SOLID, 10), | ||
| (paramak.LayerType.SOLID, 120), | ||
| (paramak.LayerType.SOLID, 20), | ||
| (paramak.LayerType.GAP, 60), | ||
| (paramak.LayerType.PLASMA, 300), | ||
| (paramak.LayerType.GAP, 60), | ||
| (paramak.LayerType.SOLID, 20), | ||
| (paramak.LayerType.SOLID, 120), | ||
| (paramak.LayerType.SOLID, 10), | ||
| ], | ||
| elongation=2, | ||
| triangularity=0.55, | ||
| rotation_angle=90, | ||
| ) | ||
| Tokamak with divertor | ||
| --------------------- | ||
| TODO | ||
| Tokamak with poloidal field coils | ||
| --------------------------------- | ||
| TODO | ||
| Tokamak with toroidal field coils | ||
| --------------------------------- | ||
| TODO | ||
| Tokamak with negative triangularity | ||
| ----------------------------------- | ||
| - The triangularity argument can be set to a negative value to make a plasma with a negative triangularity. | ||
| - This example makes a tokamak with a negative but this would work on any reactor. | ||
| .. cadquery:: | ||
| :gridsize: 0 | ||
| :select: result | ||
| :color: #00cd00 | ||
| :width: 100% | ||
| :height: 600px | ||
| import paramak | ||
| result = paramak.tokamak( | ||
| radial_build=[ | ||
| (paramak.LayerType.GAP, 10), | ||
| (paramak.LayerType.SOLID, 30), | ||
| (paramak.LayerType.SOLID, 50), | ||
| (paramak.LayerType.SOLID, 10), | ||
| (paramak.LayerType.SOLID, 120), | ||
| (paramak.LayerType.SOLID, 20), | ||
| (paramak.LayerType.GAP, 60), | ||
| (paramak.LayerType.PLASMA, 300), | ||
| (paramak.LayerType.GAP, 60), | ||
| (paramak.LayerType.SOLID, 20), | ||
| (paramak.LayerType.SOLID, 120), | ||
| (paramak.LayerType.SOLID, 10), | ||
| ], | ||
| vertical_build=[ | ||
| (paramak.LayerType.SOLID, 15), | ||
| (paramak.LayerType.SOLID, 80), | ||
| (paramak.LayerType.SOLID, 10), | ||
| (paramak.LayerType.GAP, 50), | ||
| (paramak.LayerType.PLASMA, 700), | ||
| (paramak.LayerType.GAP, 60), | ||
| (paramak.LayerType.SOLID, 10), | ||
| (paramak.LayerType.SOLID, 40), | ||
| (paramak.LayerType.SOLID, 15), | ||
| ], | ||
| triangularity=-0.55, | ||
| rotation_angle=180, | ||
| ).toCompound() | ||
| .. code-block:: python | ||
| import paramak | ||
| result = paramak.tokamak( | ||
| radial_build=[ | ||
| (paramak.LayerType.GAP, 10), | ||
| (paramak.LayerType.SOLID, 30), | ||
| (paramak.LayerType.SOLID, 50), | ||
| (paramak.LayerType.SOLID, 10), | ||
| (paramak.LayerType.SOLID, 120), | ||
| (paramak.LayerType.SOLID, 20), | ||
| (paramak.LayerType.GAP, 60), | ||
| (paramak.LayerType.PLASMA, 300), | ||
| (paramak.LayerType.GAP, 60), | ||
| (paramak.LayerType.SOLID, 20), | ||
| (paramak.LayerType.SOLID, 120), | ||
| (paramak.LayerType.SOLID, 10), | ||
| ], | ||
| vertical_build=[ | ||
| (paramak.LayerType.SOLID, 15), | ||
| (paramak.LayerType.SOLID, 80), | ||
| (paramak.LayerType.SOLID, 10), | ||
| (paramak.LayerType.GAP, 50), | ||
| (paramak.LayerType.PLASMA, 700), | ||
| (paramak.LayerType.GAP, 60), | ||
| (paramak.LayerType.SOLID, 10), | ||
| (paramak.LayerType.SOLID, 40), | ||
| (paramak.LayerType.SOLID, 15), | ||
| ], | ||
| triangularity=-0.55, | ||
| rotation_angle=180, | ||
| ) | ||
| result.save(f"tokamak_minimal.step") | ||
| Tokamak with several customizations | ||
| ----------------------------------- | ||
| - Combining many of the examples together to produce a Tokamak | ||
| with extra blanket layers, a lower divertor, PF and TF coils. | ||
| .. cadquery:: | ||
| :gridsize: 0 | ||
| :select: result | ||
| :color: #00cd00 | ||
| :width: 100% | ||
| :height: 600px | ||
| import paramak | ||
| from cadquery import vis, Workplane | ||
| # makes a rectangle that overlaps the lower blanket under the plasma | ||
| # the intersection of this and the layers will form the lower divertor | ||
| points = [(300, -700), (300, 0), (400, 0), (400, -700)] | ||
| divertor_lower = Workplane('XZ', origin=(0,0,0)).polyline(points).close().revolve(180) | ||
| # creates a toroidal | ||
| tf = paramak.toroidal_field_coil_rectangle( | ||
| horizontal_start_point = (10, 520), | ||
| vertical_mid_point = (860, 0), | ||
| thickness = 50, | ||
| distance = 40, | ||
| with_inner_leg = True, | ||
| rotation_angle = 180, | ||
| azimuthal_placement_angles = [0, 30, 60, 90, 120, 150, 180], | ||
| ) | ||
| extra_cut_shapes = [tf] | ||
| # creates pf coil | ||
| for case_thickness, height, width, center_point in zip( | ||
| [10, 15, 15, 10], [20, 50, 50, 20], [20, 50, 50, 20], | ||
| [(730, 370), (810, 235), (810, -235), (730, -370)] | ||
| ): | ||
| extra_cut_shapes.append( | ||
| paramak.poloidal_field_coil( | ||
| height=height, width=width, center_point=center_point, rotation_angle=180 | ||
| ) | ||
| ) | ||
| extra_cut_shapes.append( | ||
| paramak.poloidal_field_coil_case( | ||
| coil_height=height, | ||
| coil_width=width, | ||
| casing_thickness=case_thickness, | ||
| rotation_angle=180, | ||
| center_point=center_point, | ||
| ) | ||
| ) | ||
| result = paramak.tokamak( | ||
| radial_build=[ | ||
| (paramak.LayerType.GAP, 10), | ||
| (paramak.LayerType.SOLID, 30), | ||
| (paramak.LayerType.SOLID, 50), | ||
| (paramak.LayerType.SOLID, 10), | ||
| (paramak.LayerType.SOLID, 60), | ||
| (paramak.LayerType.SOLID, 60), | ||
| (paramak.LayerType.SOLID, 20), | ||
| (paramak.LayerType.GAP, 60), | ||
| (paramak.LayerType.PLASMA, 300), | ||
| (paramak.LayerType.GAP, 60), | ||
| (paramak.LayerType.SOLID, 20), | ||
| (paramak.LayerType.SOLID, 60), | ||
| (paramak.LayerType.SOLID, 60), | ||
| (paramak.LayerType.SOLID, 10), | ||
| ], | ||
| vertical_build=[ | ||
| (paramak.LayerType.SOLID, 10), | ||
| (paramak.LayerType.SOLID, 50), | ||
| (paramak.LayerType.SOLID, 50), | ||
| (paramak.LayerType.SOLID, 20), | ||
| (paramak.LayerType.GAP, 60), | ||
| (paramak.LayerType.PLASMA, 650), | ||
| (paramak.LayerType.GAP, 60), | ||
| (paramak.LayerType.SOLID, 20), | ||
| (paramak.LayerType.SOLID, 50), | ||
| (paramak.LayerType.SOLID, 50), | ||
| (paramak.LayerType.SOLID, 10), | ||
| ], | ||
| triangularity=0.55, | ||
| rotation_angle=180, | ||
| extra_cut_shapes=extra_cut_shapes, | ||
| extra_intersect_shapes=[divertor_lower] | ||
| ).toCompound() | ||
| .. code-block:: python | ||
| import paramak | ||
| from cadquery import Workplane | ||
| # makes a rectangle that overlaps the lower blanket under the plasma | ||
| # the intersection of this and the layers will form the lower divertor | ||
| points = [(300, -700), (300, 0), (400, 0), (400, -700)] | ||
| divertor_lower = Workplane('XZ', origin=(0,0,0)).polyline(points).close().revolve(180) | ||
| # creates a toroidal | ||
| tf = paramak.toroidal_field_coil_rectangle( | ||
| horizontal_start_point = (10, 520), | ||
| vertical_mid_point = (860, 0), | ||
| thickness = 50, | ||
| distance = 40, | ||
| with_inner_leg = True, | ||
| rotation_angle = 180, | ||
| azimuthal_placement_angles = [0, 30, 60, 90, 120, 150, 180], | ||
| ) | ||
| extra_cut_shapes = [tf] | ||
| # creates pf coil | ||
| for case_thickness, height, width, center_point in zip( | ||
| [10, 15, 15, 10], [20, 50, 50, 20], [20, 50, 50, 20], | ||
| [(730, 370), (810, 235), (810, -235), (730, -370)] | ||
| ): | ||
| extra_cut_shapes.append( | ||
| paramak.poloidal_field_coil( | ||
| height=height, width=width, center_point=center_point, rotation_angle=180 | ||
| ) | ||
| ) | ||
| extra_cut_shapes.append( | ||
| paramak.poloidal_field_coil_case( | ||
| coil_height=height, | ||
| coil_width=width, | ||
| casing_thickness=case_thickness, | ||
| rotation_angle=180, | ||
| center_point=center_point, | ||
| ) | ||
| ) | ||
| my_reactor = paramak.tokamak( | ||
| radial_build=[ | ||
| (paramak.LayerType.GAP, 10), | ||
| (paramak.LayerType.SOLID, 30), | ||
| (paramak.LayerType.SOLID, 50), | ||
| (paramak.LayerType.SOLID, 10), | ||
| (paramak.LayerType.SOLID, 60), | ||
| (paramak.LayerType.SOLID, 60), | ||
| (paramak.LayerType.SOLID, 20), | ||
| (paramak.LayerType.GAP, 60), | ||
| (paramak.LayerType.PLASMA, 300), | ||
| (paramak.LayerType.GAP, 60), | ||
| (paramak.LayerType.SOLID, 20), | ||
| (paramak.LayerType.SOLID, 60), | ||
| (paramak.LayerType.SOLID, 60), | ||
| (paramak.LayerType.SOLID, 10), | ||
| ], | ||
| vertical_build=[ | ||
| (paramak.LayerType.SOLID, 10), | ||
| (paramak.LayerType.SOLID, 50), | ||
| (paramak.LayerType.SOLID, 50), | ||
| (paramak.LayerType.SOLID, 20), | ||
| (paramak.LayerType.GAP, 60), | ||
| (paramak.LayerType.PLASMA, 650), | ||
| (paramak.LayerType.GAP, 60), | ||
| (paramak.LayerType.SOLID, 20), | ||
| (paramak.LayerType.SOLID, 50), | ||
| (paramak.LayerType.SOLID, 50), | ||
| (paramak.LayerType.SOLID, 10), | ||
| ], | ||
| triangularity=0.55, | ||
| rotation_angle=180, | ||
| extra_cut_shapes=extra_cut_shapes, | ||
| extra_intersect_shapes=[divertor_lower] | ||
| ) | ||
| my_reactor.save(f"tokamak_with_customizations.step") |
| Visualization options | ||
| ===================== | ||
| The reactors (cadquery.Assembly objects) and components (cadquery.Workplane objects) can be visualized in a number of ways. | ||
| First option is to export them to STEP, BREP or STL file then open the file with your favorite CAD software for example `FreeCAD <https://www.freecad.org/>`_. | ||
| See the `CadQuery documentation on saving <https://cadquery.readthedocs.io/en/latest/importexport.html#exporting-step>`_ for more information. | ||
| Other options include the built in visualization tools in CadQuery | ||
| .. code-block:: python | ||
| from cadquery.vis import show | ||
| show(result) # where result is the returned reactor or component object | ||
| Jupyter_cadquery package can be installed (pip install jupyter-cadquery) which allows for interactive 3D visualization in a web browser. | ||
| This package can also be used to export portable html files with the 3D visualization. | ||
| .. code-block:: python | ||
| # pip install jupyter_cadquery | ||
| # might needed to downgrade pip with ... python -m pip install pip==24.0 | ||
| from jupyter_cadquery import show | ||
| view = show(result) # where result is the returned reactor or component object | ||
| view.export_html("3d.html") |
| Usage | ||
| ===== | ||
| There are two main reactors to choose from: | ||
| * Tokamak | ||
| * Spherical Tokamak. | ||
| The reactors can be varied in terms of their radial build, vertical build, elongation and triangularity which gives a lot of variability. | ||
| All reactors can be built with either: | ||
| * A radial and vertical build which gives more control of the size of components allowing reactor blankets to vary both radially and vertically. | ||
| * A radial build and plasma elongation which assumes the vertical build matches the radial build and allows the reactors to be built with a minimal number of parameters. | ||
| It is also easy to add additional components such as: | ||
| * divertors | ||
| * poloidal magnets | ||
| * toroidal magnets | ||
| * your own CadQuery shapes / workplanes | ||
| These examples show how to make various reactors with different options. | ||
| .. toctree:: | ||
| :maxdepth: 3 | ||
| usage_vis | ||
| usage_tokamak | ||
| usage_spherical_tokamak | ||
Alert delta unavailable
Currently unable to show alert delta for PyPI packages.
343338
20.14%84
6.33%4248
1.22%