{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# ✅Visualization based on pyvista" ] }, { "cell_type": "raw", "metadata": { "raw_mimetype": "text/restructuredtext", "tags": [] }, "source": [ "First load the necessary classes and functions, where :py:class:`~opstool.vis.GetFEMdata` is used to get the model data from the current domain of OpenSeesPy, \n", "and :py:class:`~opstool.vis.OpsVisPyvista` is used to visualize the model.\n", "Function :py:func:`~opstool.load_ops_examples` is used to load predefined examples from **opstool**." ] }, { "cell_type": "code", "execution_count": 1, "metadata": { "execution": { "iopub.execute_input": "2023-06-17T09:09:20.055398Z", "iopub.status.busy": "2023-06-17T09:09:20.055398Z", "iopub.status.idle": "2023-06-17T09:09:20.929951Z", "shell.execute_reply": "2023-06-17T09:09:20.929951Z", "shell.execute_reply.started": "2023-06-17T09:09:20.055398Z" }, "tags": [] }, "outputs": [], "source": [ "import openseespy.opensees as ops\n", "import opstool as opst" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Load the 3D Arch Bridge finite element model." ] }, { "cell_type": "code", "execution_count": 2, "metadata": { "execution": { "iopub.execute_input": "2023-06-17T09:09:49.436932Z", "iopub.status.busy": "2023-06-17T09:09:49.436932Z", "iopub.status.idle": "2023-06-17T09:09:49.469427Z", "shell.execute_reply": "2023-06-17T09:09:49.469427Z", "shell.execute_reply.started": "2023-06-17T09:09:49.436932Z" }, "tags": [] }, "outputs": [], "source": [ "opst.load_ops_examples(\"SuspensionBridge\")\n", "# or your openseespy code\n", "# your openseespy code here" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Display OpenSeesPy Geometry Model" ] }, { "cell_type": "raw", "metadata": { "raw_mimetype": "text/restructuredtext", "tags": [] }, "source": [ "Get the model data from the current domain. Of course, you can also run your own model code before instantiating :py:class:`~opstool.vis.GetFEMdata`.\n", "Parameter *results_dir* is used to specify the directory where the output file is saved." ] }, { "cell_type": "code", "execution_count": 3, "metadata": { "execution": { "iopub.execute_input": "2023-06-17T09:09:51.973210Z", "iopub.status.busy": "2023-06-17T09:09:51.973210Z", "iopub.status.idle": "2023-06-17T09:09:52.018561Z", "shell.execute_reply": "2023-06-17T09:09:52.018561Z", "shell.execute_reply.started": "2023-06-17T09:09:51.973210Z" }, "tags": [] }, "outputs": [ { "data": { "text/html": [ "
\n",
       "***** Model Information *****\n",
       "
\n" ], "text/plain": [ "\n", "***** Model Information *****\n" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/html": [ "
Number of nodes: 200\n",
       "
\n" ], "text/plain": [ "Number of nodes: \u001b[1;36m200\u001b[0m\n" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/html": [ "
Number of elements: 343\n",
       "
\n" ], "text/plain": [ "Number of elements: \u001b[1;36m343\u001b[0m\n" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/html": [ "
The boundary size: X --> [-70.  70.]; Y --> [-1.75  1.75]; Z --> [-6.25 11.25]\n",
       "
\n" ], "text/plain": [ "The boundary size: X --> \u001b[1m[\u001b[0m\u001b[1;36m-70\u001b[0m. \u001b[1;36m70\u001b[0m.\u001b[1m]\u001b[0m; Y --> \u001b[1m[\u001b[0m\u001b[1;36m-1.75\u001b[0m \u001b[1;36m1.75\u001b[0m\u001b[1m]\u001b[0m; Z --> \u001b[1m[\u001b[0m\u001b[1;36m-6.25\u001b[0m \u001b[1;36m11.25\u001b[0m\u001b[1m]\u001b[0m\n" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/html": [ "
Element types: {'ShellMITC4', 'ElasticBeam3d'}\n",
       "
\n" ], "text/plain": [ "Element types: \u001b[1m{\u001b[0m\u001b[32m'ShellMITC4'\u001b[0m, \u001b[32m'ElasticBeam3d'\u001b[0m\u001b[1m}\u001b[0m\n" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/html": [ "
***** END *****\n",
       "\n",
       "
\n" ], "text/plain": [ "***** END *****\n", "\n" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/html": [ "
Model data saved in opstool_output/ModelData.hdf5!\n",
       "
\n" ], "text/plain": [ "Model data saved in \u001b[1;38;2;0;174;255mopstool_output/ModelData.hdf5\u001b[0m!\n" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "ModelData = opst.GetFEMdata(results_dir=\"opstool_output\")\n", "ModelData.get_model_data(save_file=\"ModelData.hdf5\")" ] }, { "cell_type": "raw", "metadata": { "raw_mimetype": "text/restructuredtext", "tags": [] }, "source": [ "Instantiating visualization class :py:class:`~opstool.vis.OpsVisPyvista`." ] }, { "cell_type": "code", "execution_count": 4, "metadata": { "execution": { "iopub.execute_input": "2023-06-17T09:10:08.397190Z", "iopub.status.busy": "2023-06-17T09:10:08.397190Z", "iopub.status.idle": "2023-06-17T09:10:08.405554Z", "shell.execute_reply": "2023-06-17T09:10:08.405404Z", "shell.execute_reply.started": "2023-06-17T09:10:08.397190Z" }, "tags": [] }, "outputs": [], "source": [ "opsvis = opst.OpsVisPyvista(point_size=0, line_width=2,\n", " colors_dict=None, theme=\"paraview\",\n", " color_map=\"coolwarm\", on_notebook=False,\n", " results_dir=\"opstool_output\")" ] }, { "cell_type": "raw", "metadata": { "raw_mimetype": "text/restructuredtext", "tags": [] }, "source": [ "Display the geometric information of the model, Input parameter explanation see class method :py:meth:`~opstool.vis.OpsVisPyvista.model_vis`." ] }, { "cell_type": "code", "execution_count": 5, "metadata": { "execution": { "iopub.execute_input": "2023-06-17T09:10:12.269587Z", "iopub.status.busy": "2023-06-17T09:10:12.269587Z", "iopub.status.idle": "2023-06-17T09:10:36.306483Z", "shell.execute_reply": "2023-06-17T09:10:36.305493Z", "shell.execute_reply.started": "2023-06-17T09:10:12.269587Z" }, "tags": [] }, "outputs": [], "source": [ "opsvis.model_vis(input_file=\"ModelData.hdf5\",\n", " show_node_label=False, show_ele_label=False,\n", " show_local_crd=True,\n", " local_crd_alpha=1.5,\n", " show_fix_node=True,\n", " fix_node_alpha=2.0,\n", " show_constrain_dof=False,\n", " label_size=15,\n", " show_outline=True,\n", " opacity=1.0,\n", " save_fig='images/ModelVis.svg')" ] }, { "cell_type": "raw", "metadata": { "raw_mimetype": "text/restructuredtext", "tags": [] }, "source": [ ".. image:: images/ModelVis.svg\n", " :align: center" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Display Eigen Analysis" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "
\n", "\n", "Note\n", "\n", "Before performing the eigenvalue analysis, you need to ensure that the OpenSeesPy model is correct and that the mass is set.\n", "\n", "
" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Obtain the first 20 orders of modal data." ] }, { "cell_type": "code", "execution_count": 6, "metadata": { "execution": { "iopub.execute_input": "2023-06-17T09:10:50.061155Z", "iopub.status.busy": "2023-06-17T09:10:50.060164Z", "iopub.status.idle": "2023-06-17T09:10:50.110425Z", "shell.execute_reply": "2023-06-17T09:10:50.110425Z", "shell.execute_reply.started": "2023-06-17T09:10:50.061155Z" }, "tags": [] }, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "Using DomainModalProperties - Developed by: Massimo Petracca, Guido Camata, ASDEA Software Technology\n" ] }, { "data": { "text/html": [ "
Eigen data saved in opstool_output/EigenData.hdf5!\n",
       "
\n" ], "text/plain": [ "Eigen data saved in \u001b[1;38;2;51;105;231mopstool_output/EigenData.hdf5\u001b[0m!\n" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "ModelData.get_eigen_data(mode_tag=20, solver=\"-genBandArpack\",\n", " save_file='EigenData.hdf5')" ] }, { "cell_type": "raw", "metadata": { "raw_mimetype": "text/restructuredtext", "tags": [] }, "source": [ "Visualize eigenvalue modes. When you set a two-element list for the argument *mode_tags* and *subplots* is False, the method :py:meth:`~opstool.vis.OpsVisPyvista.eigen_vis` returns a slider-style plot." ] }, { "cell_type": "code", "execution_count": 7, "metadata": { "execution": { "iopub.execute_input": "2023-06-17T09:11:04.159787Z", "iopub.status.busy": "2023-06-17T09:11:04.159787Z", "iopub.status.idle": "2023-06-17T09:11:19.527255Z", "shell.execute_reply": "2023-06-17T09:11:19.526254Z", "shell.execute_reply.started": "2023-06-17T09:11:04.159787Z" }, "tags": [] }, "outputs": [], "source": [ "opsvis.eigen_vis(input_file='EigenData.hdf5',\n", " mode_tags=[1, 20], subplots=False,\n", " alpha=1.0, show_outline=False,\n", " show_origin=False, opacity=1.0,\n", " show_face_line=False, save_fig='images/EigenVis.svg')" ] }, { "cell_type": "raw", "metadata": { "raw_mimetype": "text/restructuredtext", "tags": [] }, "source": [ ".. image:: images/EigenVis.svg\n", " :align: center" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Of course, *subplots* set to True will return a multi-sub plot." ] }, { "cell_type": "code", "execution_count": 8, "metadata": { "execution": { "iopub.execute_input": "2023-06-17T09:11:26.709042Z", "iopub.status.busy": "2023-06-17T09:11:26.708042Z", "iopub.status.idle": "2023-06-17T09:11:30.805046Z", "shell.execute_reply": "2023-06-17T09:11:30.805046Z", "shell.execute_reply.started": "2023-06-17T09:11:26.709042Z" }, "tags": [] }, "outputs": [], "source": [ "opsvis.eigen_vis(input_file='EigenData.hdf5',\n", " mode_tags=[1, 16], subplots=True,\n", " alpha=1.0, show_outline=False,\n", " show_origin=False, opacity=1.0,\n", " show_face_line=False, save_fig='images/EigenVis2.svg')" ] }, { "cell_type": "raw", "metadata": { "raw_mimetype": "text/restructuredtext", "tags": [] }, "source": [ ".. image:: images/EigenVis2.svg\n", " :align: center" ] }, { "cell_type": "raw", "metadata": { "raw_mimetype": "text/restructuredtext", "tags": [] }, "source": [ "You can also create an gif or mp4 animation by :py:meth:`~opstool.vis.OpsVisPyvista.eigen_anim`." ] }, { "cell_type": "code", "execution_count": 9, "metadata": { "execution": { "iopub.execute_input": "2023-06-17T09:11:43.687982Z", "iopub.status.busy": "2023-06-17T09:11:43.687982Z", "iopub.status.idle": "2023-06-17T09:11:47.856327Z", "shell.execute_reply": "2023-06-17T09:11:47.856327Z", "shell.execute_reply.started": "2023-06-17T09:11:43.687982Z" }, "tags": [] }, "outputs": [], "source": [ "opsvis.eigen_anim(input_file='EigenData.hdf5',\n", " mode_tag=6, alpha=1.0,\n", " show_outline=False,\n", " opacity=1, framerate=3,\n", " n_cycle=5, # change steps here\n", " show_face_line=True,\n", " save_fig=\"images/EigenAnimation.gif\")" ] }, { "cell_type": "raw", "metadata": { "raw_mimetype": "text/restructuredtext", "tags": [] }, "source": [ ".. image:: images/EigenAnimation.gif\n", " :alt: StreamPlayer\n", " :align: center" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Display Response Data" ] }, { "cell_type": "raw", "metadata": { "raw_mimetype": "text/restructuredtext", "tags": [] }, "source": [ "First we use the function :py:func:`~opstool.preprocessing.gen_grav_load` to generate the gravity load.\n", "Ignore this command if you have already defined gravity or loads you want." ] }, { "cell_type": "code", "execution_count": 10, "metadata": { "execution": { "iopub.execute_input": "2023-06-17T09:11:54.754710Z", "iopub.status.busy": "2023-06-17T09:11:54.753710Z", "iopub.status.idle": "2023-06-17T09:11:54.760712Z", "shell.execute_reply": "2023-06-17T09:11:54.760712Z", "shell.execute_reply.started": "2023-06-17T09:11:54.753710Z" }, "tags": [] }, "outputs": [], "source": [ "opst.gen_grav_load(ts_tag=1, pattern_tag=1,\n", " factor=-9.81, direction=\"Z\")" ] }, { "cell_type": "raw", "metadata": { "raw_mimetype": "text/restructuredtext", "tags": [] }, "source": [ "Next, we save the response data in each analysis step.\n", "I chose to do this to strip the visualization from the analysis,\n", "and you are free to tweak the analysis parameters, which is very helpful for debugging the convergence of the model!\n", "\n", ".. note::\n", " Since version 0.7.0, ``opstool`` has added methods :meth:`opstool.vis.GetFEMdata.get_resp_step` \n", " and :meth:`opstool.vis.GetFEMdata.save_resp_all` \n", " to get and save all supported responses at once,\n", " you don't have to use commands like ``get_node_resp_step()``,``get_frame_resp_step()``, ..., anymore." ] }, { "cell_type": "code", "execution_count": 11, "metadata": { "execution": { "iopub.execute_input": "2023-06-17T09:12:02.710798Z", "iopub.status.busy": "2023-06-17T09:12:02.709798Z", "iopub.status.idle": "2023-06-17T09:12:02.920641Z", "shell.execute_reply": "2023-06-17T09:12:02.920641Z", "shell.execute_reply.started": "2023-06-17T09:12:02.710798Z" }, "tags": [] }, "outputs": [ { "data": { "text/html": [ "
All responses data saved in opstool_output/RespStepData-1.hdf5!\n",
       "
\n" ], "text/plain": [ "All responses data saved in \u001b[1;38;2;142;67;231mopstool_output/RespStepData-\u001b[0m\u001b[1;38;2;142;67;231m1.\u001b[0m\u001b[1;38;2;142;67;231mhdf5\u001b[0m!\n" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "Nsteps = 10\n", "ops.wipeAnalysis()\n", "ops.system('BandGeneral')\n", "ops.constraints('Transformation')\n", "ops.numberer('RCM')\n", "ops.test('NormDispIncr', 1.0e-12, 10, 3)\n", "ops.algorithm('Newton')\n", "ops.integrator('LoadControl', 1 / Nsteps)\n", "ops.analysis('Static')\n", "\n", "# start analysis loop\n", "for i in range(Nsteps):\n", " ok = ops.analyze(1)\n", " ModelData.get_resp_step()\n", "# save all responses data after loop\n", "ModelData.save_resp_all(save_file=\"RespStepData-1.hdf5\")" ] }, { "cell_type": "raw", "metadata": { "raw_mimetype": "text/restructuredtext", "tags": [] }, "source": [ "Visualize node displacement by method :py:meth:`~opstool.vis.OpsVisPyvista.deform_vis`.\n", "Of course, velocity and acceleration are also optional, just change *response* to \"vel\" or \"accel\"." ] }, { "cell_type": "code", "execution_count": 12, "metadata": { "execution": { "iopub.execute_input": "2023-06-17T09:12:12.497955Z", "iopub.status.busy": "2023-06-17T09:12:12.496965Z", "iopub.status.idle": "2023-06-17T09:12:17.158611Z", "shell.execute_reply": "2023-06-17T09:12:17.158611Z", "shell.execute_reply.started": "2023-06-17T09:12:12.497955Z" }, "tags": [] }, "outputs": [], "source": [ "opsvis.deform_vis(input_file=\"RespStepData-1.hdf5\",\n", " slider=True,\n", " response=\"disp\", alpha=1.0,\n", " show_outline=False, show_origin=True,\n", " show_face_line=False, opacity=1,\n", " save_fig=\"images/DefoVis.svg\",\n", " model_update=False)" ] }, { "cell_type": "raw", "metadata": { "raw_mimetype": "text/restructuredtext", "tags": [] }, "source": [ ".. image:: images/DefoVis.svg\n", " :align: center" ] }, { "cell_type": "raw", "metadata": { "raw_mimetype": "text/restructuredtext", "tags": [] }, "source": [ "Create an html animation by :py:meth:`~opstool.vis.OpsVisPyvista.deform_anim`." ] }, { "cell_type": "code", "execution_count": 13, "metadata": { "execution": { "iopub.execute_input": "2023-06-17T09:12:22.698050Z", "iopub.status.busy": "2023-06-17T09:12:22.698050Z", "iopub.status.idle": "2023-06-17T09:12:25.884558Z", "shell.execute_reply": "2023-06-17T09:12:25.884558Z", "shell.execute_reply.started": "2023-06-17T09:12:22.698050Z" }, "tags": [] }, "outputs": [], "source": [ "opsvis.deform_anim(input_file=\"RespStepData-1.hdf5\",\n", " response=\"disp\", alpha=1.0,\n", " show_outline=False,\n", " framerate=2,\n", " show_face_line=False, opacity=1,\n", " save_fig=\"images/DefoAnimation.gif\",\n", " model_update=False)" ] }, { "cell_type": "raw", "metadata": { "raw_mimetype": "text/restructuredtext", "tags": [] }, "source": [ ".. image:: images/DefoAnimation.gif\n", " :alt: StreamPlayer\n", " :align: center" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Display Frame Element Response" ] }, { "cell_type": "raw", "metadata": { "raw_mimetype": "text/restructuredtext", "tags": [] }, "source": [ "When saving the node response data, we also save the response of the frame elemengts by method :py:meth:`~opstool.vis.GetFEMdata.get_frame_resp_step`, which you can visualize in the following way." ] }, { "cell_type": "code", "execution_count": 14, "metadata": { "execution": { "iopub.execute_input": "2023-06-17T09:12:29.617123Z", "iopub.status.busy": "2023-06-17T09:12:29.617123Z", "iopub.status.idle": "2023-06-17T09:12:40.988946Z", "shell.execute_reply": "2023-06-17T09:12:40.987948Z", "shell.execute_reply.started": "2023-06-17T09:12:29.617123Z" }, "tags": [] }, "outputs": [], "source": [ "opsvis.frame_resp_vis(input_file=\"RespStepData-1.hdf5\",\n", " ele_tags=None,\n", " slider=True,\n", " response=\"My\",\n", " show_values=False,\n", " alpha=1.0,\n", " opacity=1,\n", " save_fig=\"images/FrameRespVis.svg\")" ] }, { "cell_type": "raw", "metadata": { "raw_mimetype": "text/restructuredtext", "tags": [] }, "source": [ ".. image:: images/FrameRespVis.svg\n", " :align: center" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3 (ipykernel)", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.10.9" }, "toc-autonumbering": true, "vscode": { "interpreter": { "hash": "f7a9b8f8690f520d36b7cd58879dbcd97545c5eb0452dadad5bd7e9f8ca42860" } } }, "nbformat": 4, "nbformat_minor": 4 }