├── feastruct ├── __init__.py ├── fea │ ├── __init__.py │ ├── elements │ │ ├── __init__.py │ │ └── frame.py │ ├── utils.py │ ├── frame_analysis.py │ └── cases.py ├── post │ ├── __init__.py │ └── post.py ├── tests │ ├── __init__.py │ ├── implementation │ │ ├── __init__.py │ │ ├── AWC-DA6-BeamFormulas-0710.pdf │ │ ├── test_frame_element.py │ │ ├── test_finite_element.py │ │ └── test_node.py │ └── mastan2_textbook │ │ ├── __init__.py │ │ ├── test_chapter3.py │ │ ├── test_chapter2.py │ │ └── test_chapter5.py ├── solvers │ ├── __init__.py │ ├── linbuckling.py │ ├── naturalfrequency.py │ └── linstatic.py ├── pre │ ├── section.py │ └── material.py └── examples │ ├── frequency.py │ ├── beam_udl.py │ ├── beam.py │ ├── buckle.py │ ├── frame.py │ ├── arch.py │ └── bowstring.py ├── MANIFEST.in ├── docs ├── build │ ├── html │ │ ├── _static │ │ │ ├── custom.css │ │ │ ├── up.png │ │ │ ├── down.png │ │ │ ├── file.png │ │ │ ├── minus.png │ │ │ ├── plus.png │ │ │ ├── comment.png │ │ │ ├── up-pressed.png │ │ │ ├── ajax-loader.gif │ │ │ ├── down-pressed.png │ │ │ ├── comment-bright.png │ │ │ ├── comment-close.png │ │ │ ├── fonts │ │ │ │ ├── Lato-Bold.ttf │ │ │ │ ├── Lato-Italic.ttf │ │ │ │ ├── Lato-Regular.ttf │ │ │ │ ├── Inconsolata-Bold.ttf │ │ │ │ ├── Lato-BoldItalic.ttf │ │ │ │ ├── RobotoSlab-Bold.ttf │ │ │ │ ├── Inconsolata-Regular.ttf │ │ │ │ ├── RobotoSlab-Regular.ttf │ │ │ │ ├── fontawesome-webfont.eot │ │ │ │ ├── fontawesome-webfont.ttf │ │ │ │ ├── fontawesome-webfont.woff │ │ │ │ └── fontawesome-webfont.woff2 │ │ │ ├── documentation_options.js │ │ │ ├── css │ │ │ │ └── badge_only.css │ │ │ ├── js │ │ │ │ └── theme.js │ │ │ ├── pygments.css │ │ │ ├── classic.css │ │ │ ├── sidebar.js │ │ │ ├── doctools.js │ │ │ └── underscore.js │ │ ├── _sources │ │ │ ├── rst │ │ │ │ ├── installation.rst.txt │ │ │ │ ├── results.rst.txt │ │ │ │ ├── utils.rst.txt │ │ │ │ ├── frame2D.rst.txt │ │ │ │ ├── frame.rst.txt │ │ │ │ ├── post.rst.txt │ │ │ │ ├── pre.rst.txt │ │ │ │ ├── frame │ │ │ │ │ ├── frame_2d.rst.txt │ │ │ │ │ ├── frame_3d.rst.txt │ │ │ │ │ ├── frame_elements.rst.txt │ │ │ │ │ └── frame_analysis.rst.txt │ │ │ │ ├── fea.rst.txt │ │ │ │ ├── bcs.rst.txt │ │ │ │ ├── cases.rst.txt │ │ │ │ ├── node.rst.txt │ │ │ │ └── solvers.rst.txt │ │ │ └── index.rst.txt │ │ ├── objects.inv │ │ ├── .buildinfo │ │ ├── search.html │ │ └── rst │ │ │ └── installation.html │ └── doctrees │ │ ├── index.doctree │ │ ├── rst │ │ ├── bcs.doctree │ │ ├── fea.doctree │ │ ├── pre.doctree │ │ ├── cases.doctree │ │ ├── frame.doctree │ │ ├── node.doctree │ │ ├── post.doctree │ │ ├── utils.doctree │ │ ├── frame2D.doctree │ │ ├── results.doctree │ │ ├── solvers.doctree │ │ ├── installation.doctree │ │ └── frame │ │ │ ├── frame_2d.doctree │ │ │ ├── frame_3d.doctree │ │ │ ├── frame_analysis.doctree │ │ │ └── frame_elements.doctree │ │ └── environment.pickle ├── source │ ├── rst │ │ ├── installation.rst │ │ ├── utils.rst │ │ ├── frame.rst │ │ ├── post.rst │ │ ├── pre.rst │ │ ├── frame │ │ │ ├── frame_2d.rst │ │ │ ├── frame_3d.rst │ │ │ ├── frame_elements.rst │ │ │ └── frame_analysis.rst │ │ ├── fea.rst │ │ ├── bcs.rst │ │ ├── cases.rst │ │ ├── node.rst │ │ └── solvers.rst │ ├── index.rst │ └── conf.py └── Makefile ├── .gitignore ├── todo.md ├── setup.py ├── LICENSE └── README.md /feastruct/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /feastruct/fea/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /feastruct/post/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /feastruct/tests/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /MANIFEST.in: -------------------------------------------------------------------------------- 1 | include README.md 2 | -------------------------------------------------------------------------------- /feastruct/solvers/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /feastruct/fea/elements/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /feastruct/tests/implementation/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /feastruct/tests/mastan2_textbook/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /docs/build/html/_static/custom.css: -------------------------------------------------------------------------------- 1 | /* This file intentionally left blank. */ 2 | -------------------------------------------------------------------------------- /docs/source/rst/installation.rst: -------------------------------------------------------------------------------- 1 | Installation 2 | ============ 3 | 4 | tbc. 5 | -------------------------------------------------------------------------------- /docs/build/html/_sources/rst/installation.rst.txt: -------------------------------------------------------------------------------- 1 | Installation 2 | ============ 3 | 4 | tbc. 5 | -------------------------------------------------------------------------------- /docs/build/html/objects.inv: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/robbievanleeuwen/feastruct/HEAD/docs/build/html/objects.inv -------------------------------------------------------------------------------- /docs/build/html/_static/up.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/robbievanleeuwen/feastruct/HEAD/docs/build/html/_static/up.png -------------------------------------------------------------------------------- /docs/build/doctrees/index.doctree: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/robbievanleeuwen/feastruct/HEAD/docs/build/doctrees/index.doctree -------------------------------------------------------------------------------- /docs/build/html/_static/down.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/robbievanleeuwen/feastruct/HEAD/docs/build/html/_static/down.png -------------------------------------------------------------------------------- /docs/build/html/_static/file.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/robbievanleeuwen/feastruct/HEAD/docs/build/html/_static/file.png -------------------------------------------------------------------------------- /docs/build/html/_static/minus.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/robbievanleeuwen/feastruct/HEAD/docs/build/html/_static/minus.png -------------------------------------------------------------------------------- /docs/build/html/_static/plus.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/robbievanleeuwen/feastruct/HEAD/docs/build/html/_static/plus.png -------------------------------------------------------------------------------- /docs/build/doctrees/rst/bcs.doctree: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/robbievanleeuwen/feastruct/HEAD/docs/build/doctrees/rst/bcs.doctree -------------------------------------------------------------------------------- /docs/build/doctrees/rst/fea.doctree: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/robbievanleeuwen/feastruct/HEAD/docs/build/doctrees/rst/fea.doctree -------------------------------------------------------------------------------- /docs/build/doctrees/rst/pre.doctree: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/robbievanleeuwen/feastruct/HEAD/docs/build/doctrees/rst/pre.doctree -------------------------------------------------------------------------------- /docs/build/html/_static/comment.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/robbievanleeuwen/feastruct/HEAD/docs/build/html/_static/comment.png -------------------------------------------------------------------------------- /docs/build/doctrees/environment.pickle: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/robbievanleeuwen/feastruct/HEAD/docs/build/doctrees/environment.pickle -------------------------------------------------------------------------------- /docs/build/doctrees/rst/cases.doctree: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/robbievanleeuwen/feastruct/HEAD/docs/build/doctrees/rst/cases.doctree -------------------------------------------------------------------------------- /docs/build/doctrees/rst/frame.doctree: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/robbievanleeuwen/feastruct/HEAD/docs/build/doctrees/rst/frame.doctree -------------------------------------------------------------------------------- /docs/build/doctrees/rst/node.doctree: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/robbievanleeuwen/feastruct/HEAD/docs/build/doctrees/rst/node.doctree -------------------------------------------------------------------------------- /docs/build/doctrees/rst/post.doctree: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/robbievanleeuwen/feastruct/HEAD/docs/build/doctrees/rst/post.doctree -------------------------------------------------------------------------------- /docs/build/doctrees/rst/utils.doctree: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/robbievanleeuwen/feastruct/HEAD/docs/build/doctrees/rst/utils.doctree -------------------------------------------------------------------------------- /docs/build/html/_static/up-pressed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/robbievanleeuwen/feastruct/HEAD/docs/build/html/_static/up-pressed.png -------------------------------------------------------------------------------- /docs/build/doctrees/rst/frame2D.doctree: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/robbievanleeuwen/feastruct/HEAD/docs/build/doctrees/rst/frame2D.doctree -------------------------------------------------------------------------------- /docs/build/doctrees/rst/results.doctree: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/robbievanleeuwen/feastruct/HEAD/docs/build/doctrees/rst/results.doctree -------------------------------------------------------------------------------- /docs/build/doctrees/rst/solvers.doctree: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/robbievanleeuwen/feastruct/HEAD/docs/build/doctrees/rst/solvers.doctree -------------------------------------------------------------------------------- /docs/build/html/_static/ajax-loader.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/robbievanleeuwen/feastruct/HEAD/docs/build/html/_static/ajax-loader.gif -------------------------------------------------------------------------------- /docs/build/html/_static/down-pressed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/robbievanleeuwen/feastruct/HEAD/docs/build/html/_static/down-pressed.png -------------------------------------------------------------------------------- /docs/build/html/_static/comment-bright.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/robbievanleeuwen/feastruct/HEAD/docs/build/html/_static/comment-bright.png -------------------------------------------------------------------------------- /docs/build/html/_static/comment-close.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/robbievanleeuwen/feastruct/HEAD/docs/build/html/_static/comment-close.png -------------------------------------------------------------------------------- /docs/build/html/_static/fonts/Lato-Bold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/robbievanleeuwen/feastruct/HEAD/docs/build/html/_static/fonts/Lato-Bold.ttf -------------------------------------------------------------------------------- /docs/build/doctrees/rst/installation.doctree: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/robbievanleeuwen/feastruct/HEAD/docs/build/doctrees/rst/installation.doctree -------------------------------------------------------------------------------- /docs/build/html/_static/fonts/Lato-Italic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/robbievanleeuwen/feastruct/HEAD/docs/build/html/_static/fonts/Lato-Italic.ttf -------------------------------------------------------------------------------- /docs/build/doctrees/rst/frame/frame_2d.doctree: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/robbievanleeuwen/feastruct/HEAD/docs/build/doctrees/rst/frame/frame_2d.doctree -------------------------------------------------------------------------------- /docs/build/doctrees/rst/frame/frame_3d.doctree: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/robbievanleeuwen/feastruct/HEAD/docs/build/doctrees/rst/frame/frame_3d.doctree -------------------------------------------------------------------------------- /docs/build/html/_static/fonts/Lato-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/robbievanleeuwen/feastruct/HEAD/docs/build/html/_static/fonts/Lato-Regular.ttf -------------------------------------------------------------------------------- /docs/build/html/_static/fonts/Inconsolata-Bold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/robbievanleeuwen/feastruct/HEAD/docs/build/html/_static/fonts/Inconsolata-Bold.ttf -------------------------------------------------------------------------------- /docs/build/html/_static/fonts/Lato-BoldItalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/robbievanleeuwen/feastruct/HEAD/docs/build/html/_static/fonts/Lato-BoldItalic.ttf -------------------------------------------------------------------------------- /docs/build/html/_static/fonts/RobotoSlab-Bold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/robbievanleeuwen/feastruct/HEAD/docs/build/html/_static/fonts/RobotoSlab-Bold.ttf -------------------------------------------------------------------------------- /docs/build/doctrees/rst/frame/frame_analysis.doctree: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/robbievanleeuwen/feastruct/HEAD/docs/build/doctrees/rst/frame/frame_analysis.doctree -------------------------------------------------------------------------------- /docs/build/doctrees/rst/frame/frame_elements.doctree: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/robbievanleeuwen/feastruct/HEAD/docs/build/doctrees/rst/frame/frame_elements.doctree -------------------------------------------------------------------------------- /docs/build/html/_static/fonts/Inconsolata-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/robbievanleeuwen/feastruct/HEAD/docs/build/html/_static/fonts/Inconsolata-Regular.ttf -------------------------------------------------------------------------------- /docs/build/html/_static/fonts/RobotoSlab-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/robbievanleeuwen/feastruct/HEAD/docs/build/html/_static/fonts/RobotoSlab-Regular.ttf -------------------------------------------------------------------------------- /docs/build/html/_static/fonts/fontawesome-webfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/robbievanleeuwen/feastruct/HEAD/docs/build/html/_static/fonts/fontawesome-webfont.eot -------------------------------------------------------------------------------- /docs/build/html/_static/fonts/fontawesome-webfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/robbievanleeuwen/feastruct/HEAD/docs/build/html/_static/fonts/fontawesome-webfont.ttf -------------------------------------------------------------------------------- /docs/build/html/_static/fonts/fontawesome-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/robbievanleeuwen/feastruct/HEAD/docs/build/html/_static/fonts/fontawesome-webfont.woff -------------------------------------------------------------------------------- /docs/build/html/_static/fonts/fontawesome-webfont.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/robbievanleeuwen/feastruct/HEAD/docs/build/html/_static/fonts/fontawesome-webfont.woff2 -------------------------------------------------------------------------------- /feastruct/tests/implementation/AWC-DA6-BeamFormulas-0710.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/robbievanleeuwen/feastruct/HEAD/feastruct/tests/implementation/AWC-DA6-BeamFormulas-0710.pdf -------------------------------------------------------------------------------- /docs/build/html/_sources/rst/results.rst.txt: -------------------------------------------------------------------------------- 1 | Results 2 | ======= 3 | 4 | .. automodule:: feastruct.post.results 5 | :members: 6 | :special-members: __init__ 7 | :show-inheritance: 8 | -------------------------------------------------------------------------------- /docs/source/rst/utils.rst: -------------------------------------------------------------------------------- 1 | Finite Element Utilities 2 | ======================== 3 | 4 | .. automodule:: feastruct.fea.utils 5 | :members: 6 | :special-members: __init__ 7 | :show-inheritance: 8 | -------------------------------------------------------------------------------- /docs/build/html/_sources/rst/utils.rst.txt: -------------------------------------------------------------------------------- 1 | Finite Element Utilities 2 | ======================== 3 | 4 | .. automodule:: feastruct.fea.utils 5 | :members: 6 | :special-members: __init__ 7 | :show-inheritance: 8 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Compiled python modules. 2 | *.pyc 3 | 4 | # Setuptools distribution folder. 5 | /dist/ 6 | /build/ 7 | 8 | # Python egg metadata, regenerated from source files by setuptools. 9 | /*.egg-info 10 | 11 | # UML 12 | *.mdj 13 | -------------------------------------------------------------------------------- /docs/build/html/_sources/rst/frame2D.rst.txt: -------------------------------------------------------------------------------- 1 | Frame Analysis 2 | ============== 3 | 4 | .. automodule:: feastruct.fea.frame2d 5 | :members: 6 | :special-members: __init__ 7 | :show-inheritance: 8 | :inherited-members: 9 | -------------------------------------------------------------------------------- /docs/source/rst/frame.rst: -------------------------------------------------------------------------------- 1 | #################### 2 | Frame 3 | #################### 4 | 5 | .. toctree:: 6 | :maxdepth: 2 7 | 8 | frame/frame_analysis 9 | frame/frame_elements 10 | frame/frame_2d 11 | frame/frame_3d 12 | -------------------------------------------------------------------------------- /docs/build/html/_sources/rst/frame.rst.txt: -------------------------------------------------------------------------------- 1 | #################### 2 | Frame 3 | #################### 4 | 5 | .. toctree:: 6 | :maxdepth: 2 7 | 8 | frame/frame_analysis 9 | frame/frame_elements 10 | frame/frame_2d 11 | frame/frame_3d 12 | -------------------------------------------------------------------------------- /docs/build/html/.buildinfo: -------------------------------------------------------------------------------- 1 | # Sphinx build info version 1 2 | # This file hashes the configuration used when building these files. When it is not found, a full rebuild will be done. 3 | config: f72d0870d02e2c094a752c266a56fc10 4 | tags: 645f666f9bcd5a90fca523b33c5a78b7 5 | -------------------------------------------------------------------------------- /docs/build/html/_static/documentation_options.js: -------------------------------------------------------------------------------- 1 | var DOCUMENTATION_OPTIONS = { 2 | URL_ROOT: document.getElementById("documentation_options").getAttribute('data-url_root'), 3 | VERSION: '0.1', 4 | LANGUAGE: 'None', 5 | COLLAPSE_INDEX: false, 6 | FILE_SUFFIX: '.html', 7 | HAS_SOURCE: true, 8 | SOURCELINK_SUFFIX: '.txt' 9 | }; -------------------------------------------------------------------------------- /docs/source/rst/post.rst: -------------------------------------------------------------------------------- 1 | Post-Processing 2 | =============== 3 | 4 | Post-Processor 2D 5 | ----------------- 6 | 7 | .. autoclass:: feastruct.post.post2d.PostProcessor2D 8 | :members: 9 | :special-members: __init__ 10 | 11 | Scalar Result 12 | ------------- 13 | 14 | .. autoclass:: feastruct.post.post.ScalarResult 15 | :members: 16 | :special-members: __init__ 17 | -------------------------------------------------------------------------------- /docs/build/html/_sources/rst/post.rst.txt: -------------------------------------------------------------------------------- 1 | Post-Processing 2 | =============== 3 | 4 | Post-Processor 2D 5 | ----------------- 6 | 7 | .. autoclass:: feastruct.post.post2d.PostProcessor2D 8 | :members: 9 | :special-members: __init__ 10 | 11 | Scalar Result 12 | ------------- 13 | 14 | .. autoclass:: feastruct.post.post.ScalarResult 15 | :members: 16 | :special-members: __init__ 17 | -------------------------------------------------------------------------------- /docs/source/index.rst: -------------------------------------------------------------------------------- 1 | Welcome to feastruct's documentation! 2 | ===================================== 3 | 4 | .. toctree:: 5 | :maxdepth: 2 6 | :caption: Contents: 7 | 8 | rst/installation 9 | rst/pre 10 | rst/node 11 | rst/fea 12 | rst/utils 13 | rst/frame 14 | rst/cases 15 | rst/bcs 16 | rst/solvers 17 | rst/post 18 | 19 | 20 | Indices and tables 21 | ================== 22 | 23 | * :ref:`genindex` 24 | * :ref:`modindex` 25 | * :ref:`search` 26 | -------------------------------------------------------------------------------- /docs/source/rst/pre.rst: -------------------------------------------------------------------------------- 1 | Pre 2 | === 3 | 4 | Materials 5 | --------- 6 | 7 | .. autoclass:: feastruct.pre.material.Material 8 | :members: 9 | :special-members: __init__ 10 | 11 | .. autoclass:: feastruct.pre.material.Steel 12 | :members: 13 | :special-members: __init__ 14 | :show-inheritance: 15 | :inherited-members: 16 | 17 | Sections 18 | -------- 19 | 20 | .. autoclass:: feastruct.pre.section.Section 21 | :members: 22 | :special-members: __init__ 23 | -------------------------------------------------------------------------------- /docs/build/html/_sources/index.rst.txt: -------------------------------------------------------------------------------- 1 | Welcome to feastruct's documentation! 2 | ===================================== 3 | 4 | .. toctree:: 5 | :maxdepth: 2 6 | :caption: Contents: 7 | 8 | rst/installation 9 | rst/pre 10 | rst/node 11 | rst/fea 12 | rst/utils 13 | rst/frame 14 | rst/cases 15 | rst/bcs 16 | rst/solvers 17 | rst/post 18 | 19 | 20 | Indices and tables 21 | ================== 22 | 23 | * :ref:`genindex` 24 | * :ref:`modindex` 25 | * :ref:`search` 26 | -------------------------------------------------------------------------------- /docs/build/html/_sources/rst/pre.rst.txt: -------------------------------------------------------------------------------- 1 | Pre 2 | === 3 | 4 | Materials 5 | --------- 6 | 7 | .. autoclass:: feastruct.pre.material.Material 8 | :members: 9 | :special-members: __init__ 10 | 11 | .. autoclass:: feastruct.pre.material.Steel 12 | :members: 13 | :special-members: __init__ 14 | :show-inheritance: 15 | :inherited-members: 16 | 17 | Sections 18 | -------- 19 | 20 | .. autoclass:: feastruct.pre.section.Section 21 | :members: 22 | :special-members: __init__ 23 | -------------------------------------------------------------------------------- /docs/source/rst/frame/frame_2d.rst: -------------------------------------------------------------------------------- 1 | 2D Frame Elements 2 | ================= 3 | 4 | Bar2D_2N 5 | -------- 6 | 7 | .. autoclass:: feastruct.fea.elements.frame2d.Bar2D_2N 8 | :members: 9 | :special-members: __init__ 10 | :show-inheritance: 11 | :inherited-members: 12 | 13 | EulerBernoulli2D_2N 14 | ------------------- 15 | 16 | .. autoclass:: feastruct.fea.elements.frame2d.EulerBernoulli2D_2N 17 | :members: 18 | :special-members: __init__ 19 | :show-inheritance: 20 | :inherited-members: 21 | -------------------------------------------------------------------------------- /docs/source/rst/frame/frame_3d.rst: -------------------------------------------------------------------------------- 1 | 3D Frame Elements 2 | ================= 3 | 4 | Bar3D_2N 5 | -------- 6 | 7 | .. autoclass:: feastruct.fea.elements.frame3d.Bar3D_2N 8 | :members: 9 | :special-members: __init__ 10 | :show-inheritance: 11 | :inherited-members: 12 | 13 | EulerBernoulli3D_2N 14 | ------------------- 15 | 16 | .. autoclass:: feastruct.fea.elements.frame3d.EulerBernoulli3D_2N 17 | :members: 18 | :special-members: __init__ 19 | :show-inheritance: 20 | :inherited-members: 21 | -------------------------------------------------------------------------------- /docs/build/html/_sources/rst/frame/frame_2d.rst.txt: -------------------------------------------------------------------------------- 1 | 2D Frame Elements 2 | ================= 3 | 4 | Bar2D_2N 5 | -------- 6 | 7 | .. autoclass:: feastruct.fea.elements.frame2d.Bar2D_2N 8 | :members: 9 | :special-members: __init__ 10 | :show-inheritance: 11 | :inherited-members: 12 | 13 | EulerBernoulli2D_2N 14 | ------------------- 15 | 16 | .. autoclass:: feastruct.fea.elements.frame2d.EulerBernoulli2D_2N 17 | :members: 18 | :special-members: __init__ 19 | :show-inheritance: 20 | :inherited-members: 21 | -------------------------------------------------------------------------------- /docs/build/html/_sources/rst/frame/frame_3d.rst.txt: -------------------------------------------------------------------------------- 1 | 3D Frame Elements 2 | ================= 3 | 4 | Bar3D_2N 5 | -------- 6 | 7 | .. autoclass:: feastruct.fea.elements.frame3d.Bar3D_2N 8 | :members: 9 | :special-members: __init__ 10 | :show-inheritance: 11 | :inherited-members: 12 | 13 | EulerBernoulli3D_2N 14 | ------------------- 15 | 16 | .. autoclass:: feastruct.fea.elements.frame3d.EulerBernoulli3D_2N 17 | :members: 18 | :special-members: __init__ 19 | :show-inheritance: 20 | :inherited-members: 21 | -------------------------------------------------------------------------------- /docs/source/rst/fea.rst: -------------------------------------------------------------------------------- 1 | Finite Element Analysis 2 | ======================= 3 | 4 | FiniteElementAnalysis 5 | --------------------- 6 | 7 | .. autoclass:: feastruct.fea.fea.FiniteElementAnalysis 8 | :members: 9 | :special-members: __init__ 10 | 11 | FiniteElement 12 | ------------- 13 | 14 | .. autoclass:: feastruct.fea.fea.FiniteElement 15 | :members: 16 | :special-members: __init__ 17 | 18 | ForceVector 19 | ----------- 20 | 21 | .. autoclass:: feastruct.fea.fea.ForceVector 22 | :members: 23 | :special-members: __init__ 24 | -------------------------------------------------------------------------------- /docs/build/html/_sources/rst/fea.rst.txt: -------------------------------------------------------------------------------- 1 | Finite Element Analysis 2 | ======================= 3 | 4 | FiniteElementAnalysis 5 | --------------------- 6 | 7 | .. autoclass:: feastruct.fea.fea.FiniteElementAnalysis 8 | :members: 9 | :special-members: __init__ 10 | 11 | FiniteElement 12 | ------------- 13 | 14 | .. autoclass:: feastruct.fea.fea.FiniteElement 15 | :members: 16 | :special-members: __init__ 17 | 18 | ForceVector 19 | ----------- 20 | 21 | .. autoclass:: feastruct.fea.fea.ForceVector 22 | :members: 23 | :special-members: __init__ 24 | -------------------------------------------------------------------------------- /docs/source/rst/bcs.rst: -------------------------------------------------------------------------------- 1 | Boundary Conditions 2 | =================== 3 | 4 | Boundary Condition 5 | ------------------ 6 | 7 | .. autoclass:: feastruct.fea.bcs.BoundaryCondition 8 | :members: 9 | :special-members: __init__ 10 | 11 | Nodal Support 12 | ^^^^^^^^^^^^^ 13 | 14 | .. autoclass:: feastruct.fea.bcs.NodalSupport 15 | :members: 16 | :special-members: __init__ 17 | :show-inheritance: 18 | :inherited-members: 19 | 20 | Nodal Load 21 | ^^^^^^^^^^ 22 | 23 | .. autoclass:: feastruct.fea.bcs.NodalLoad 24 | :members: 25 | :special-members: __init__ 26 | :show-inheritance: 27 | :inherited-members: 28 | -------------------------------------------------------------------------------- /docs/build/html/_sources/rst/bcs.rst.txt: -------------------------------------------------------------------------------- 1 | Boundary Conditions 2 | =================== 3 | 4 | Boundary Condition 5 | ------------------ 6 | 7 | .. autoclass:: feastruct.fea.bcs.BoundaryCondition 8 | :members: 9 | :special-members: __init__ 10 | 11 | Nodal Support 12 | ^^^^^^^^^^^^^ 13 | 14 | .. autoclass:: feastruct.fea.bcs.NodalSupport 15 | :members: 16 | :special-members: __init__ 17 | :show-inheritance: 18 | :inherited-members: 19 | 20 | Nodal Load 21 | ^^^^^^^^^^ 22 | 23 | .. autoclass:: feastruct.fea.bcs.NodalLoad 24 | :members: 25 | :special-members: __init__ 26 | :show-inheritance: 27 | :inherited-members: 28 | -------------------------------------------------------------------------------- /docs/Makefile: -------------------------------------------------------------------------------- 1 | # Minimal makefile for Sphinx documentation 2 | # 3 | 4 | # You can set these variables from the command line. 5 | SPHINXOPTS = 6 | SPHINXBUILD = sphinx-build 7 | SPHINXPROJ = feastruct 8 | SOURCEDIR = source 9 | BUILDDIR = build 10 | 11 | # Put it first so that "make" without argument is like "make help". 12 | help: 13 | @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) 14 | 15 | .PHONY: help Makefile 16 | 17 | # Catch-all target: route all unknown targets to Sphinx using the new 18 | # "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). 19 | %: Makefile 20 | @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) -------------------------------------------------------------------------------- /feastruct/post/post.py: -------------------------------------------------------------------------------- 1 | class ScalarResult: 2 | """Class for storing a scalar result for a specific analysis case. 3 | 4 | :cvar float result: Scalar result 5 | :cvar analysis_case: Analysis case relating to the result 6 | :vartype analysis_case: :class:`~feastruct.fea.cases.AnalysisCase` 7 | """ 8 | 9 | def __init__(self, result, analysis_case): 10 | """Inits the ScalarResult class. 11 | 12 | :cvar float result: Scalar result 13 | :param analysis_case: Analysis case relating to the result 14 | :type analysis_case: :class:`~feastruct.fea.cases.AnalysisCase` 15 | """ 16 | 17 | self.result = result 18 | self.analysis_case = analysis_case 19 | -------------------------------------------------------------------------------- /docs/source/rst/cases.rst: -------------------------------------------------------------------------------- 1 | Cases 2 | ===== 3 | 4 | Analysis Case 5 | ------------- 6 | 7 | .. autoclass:: feastruct.fea.cases.AnalysisCase 8 | :members: 9 | :special-members: __init__ 10 | 11 | Case 12 | ---- 13 | 14 | .. autoclass:: feastruct.fea.cases.Case 15 | :members: 16 | :special-members: __init__ 17 | 18 | Freedom Case 19 | ^^^^^^^^^^^^ 20 | 21 | .. autoclass:: feastruct.fea.cases.FreedomCase 22 | :members: 23 | :special-members: __init__ 24 | :show-inheritance: 25 | :inherited-members: 26 | 27 | Load Case 28 | ^^^^^^^^^ 29 | 30 | .. autoclass:: feastruct.fea.cases.LoadCase 31 | :members: 32 | :special-members: __init__ 33 | :show-inheritance: 34 | :inherited-members: 35 | -------------------------------------------------------------------------------- /docs/source/rst/frame/frame_elements.rst: -------------------------------------------------------------------------------- 1 | Frame Elements 2 | ============== 3 | 4 | Frame Element 5 | ------------- 6 | 7 | .. autoclass:: feastruct.fea.elements.frame.FrameElement 8 | :members: 9 | :special-members: __init__ 10 | :show-inheritance: 11 | :inherited-members: 12 | 13 | Frame Element2D 14 | --------------- 15 | 16 | .. autoclass:: feastruct.fea.elements.frame2d.FrameElement2D 17 | :members: 18 | :special-members: __init__ 19 | :show-inheritance: 20 | :inherited-members: 21 | 22 | Frame Element3D 23 | --------------- 24 | 25 | .. autoclass:: feastruct.fea.elements.frame3d.FrameElement3D 26 | :members: 27 | :special-members: __init__ 28 | :show-inheritance: 29 | :inherited-members: 30 | -------------------------------------------------------------------------------- /docs/build/html/_sources/rst/cases.rst.txt: -------------------------------------------------------------------------------- 1 | Cases 2 | ===== 3 | 4 | Analysis Case 5 | ------------- 6 | 7 | .. autoclass:: feastruct.fea.cases.AnalysisCase 8 | :members: 9 | :special-members: __init__ 10 | 11 | Case 12 | ---- 13 | 14 | .. autoclass:: feastruct.fea.cases.Case 15 | :members: 16 | :special-members: __init__ 17 | 18 | Freedom Case 19 | ^^^^^^^^^^^^ 20 | 21 | .. autoclass:: feastruct.fea.cases.FreedomCase 22 | :members: 23 | :special-members: __init__ 24 | :show-inheritance: 25 | :inherited-members: 26 | 27 | Load Case 28 | ^^^^^^^^^ 29 | 30 | .. autoclass:: feastruct.fea.cases.LoadCase 31 | :members: 32 | :special-members: __init__ 33 | :show-inheritance: 34 | :inherited-members: 35 | -------------------------------------------------------------------------------- /docs/source/rst/frame/frame_analysis.rst: -------------------------------------------------------------------------------- 1 | Frame Analysis 2 | ============== 3 | 4 | Frame Analysis 5 | -------------- 6 | 7 | .. autoclass:: feastruct.fea.frame_analysis.FrameAnalysis 8 | :members: 9 | :special-members: __init__ 10 | :show-inheritance: 11 | :inherited-members: 12 | 13 | Frame Analysis2D 14 | ---------------- 15 | 16 | .. autoclass:: feastruct.fea.frame_analysis.FrameAnalysis2D 17 | :members: 18 | :special-members: __init__ 19 | :show-inheritance: 20 | :inherited-members: 21 | 22 | Frame Analysis3D 23 | ---------------- 24 | 25 | .. autoclass:: feastruct.fea.frame_analysis.FrameAnalysis3D 26 | :members: 27 | :special-members: __init__ 28 | :show-inheritance: 29 | :inherited-members: 30 | -------------------------------------------------------------------------------- /docs/build/html/_sources/rst/frame/frame_elements.rst.txt: -------------------------------------------------------------------------------- 1 | Frame Elements 2 | ============== 3 | 4 | Frame Element 5 | ------------- 6 | 7 | .. autoclass:: feastruct.fea.elements.frame.FrameElement 8 | :members: 9 | :special-members: __init__ 10 | :show-inheritance: 11 | :inherited-members: 12 | 13 | Frame Element2D 14 | --------------- 15 | 16 | .. autoclass:: feastruct.fea.elements.frame2d.FrameElement2D 17 | :members: 18 | :special-members: __init__ 19 | :show-inheritance: 20 | :inherited-members: 21 | 22 | Frame Element3D 23 | --------------- 24 | 25 | .. autoclass:: feastruct.fea.elements.frame3d.FrameElement3D 26 | :members: 27 | :special-members: __init__ 28 | :show-inheritance: 29 | :inherited-members: 30 | -------------------------------------------------------------------------------- /docs/build/html/_sources/rst/frame/frame_analysis.rst.txt: -------------------------------------------------------------------------------- 1 | Frame Analysis 2 | ============== 3 | 4 | Frame Analysis 5 | -------------- 6 | 7 | .. autoclass:: feastruct.fea.frame_analysis.FrameAnalysis 8 | :members: 9 | :special-members: __init__ 10 | :show-inheritance: 11 | :inherited-members: 12 | 13 | Frame Analysis2D 14 | ---------------- 15 | 16 | .. autoclass:: feastruct.fea.frame_analysis.FrameAnalysis2D 17 | :members: 18 | :special-members: __init__ 19 | :show-inheritance: 20 | :inherited-members: 21 | 22 | Frame Analysis3D 23 | ---------------- 24 | 25 | .. autoclass:: feastruct.fea.frame_analysis.FrameAnalysis3D 26 | :members: 27 | :special-members: __init__ 28 | :show-inheritance: 29 | :inherited-members: 30 | -------------------------------------------------------------------------------- /docs/source/rst/node.rst: -------------------------------------------------------------------------------- 1 | Node 2 | ==== 3 | 4 | Node 5 | ---- 6 | 7 | .. autoclass:: feastruct.fea.node.Node 8 | :members: 9 | :special-members: __init__ 10 | 11 | DoF 12 | --- 13 | 14 | .. autoclass:: feastruct.fea.node.DoF 15 | :members: 16 | :special-members: __init__ 17 | 18 | Displacement 19 | ------------ 20 | .. autoclass:: feastruct.fea.node.Displacement 21 | :members: 22 | :special-members: __init__ 23 | 24 | Buckling Modes 25 | -------------- 26 | .. autoclass:: feastruct.fea.node.BucklingModes 27 | :members: 28 | :special-members: __init__ 29 | 30 | Frequency Modes 31 | --------------- 32 | .. autoclass:: feastruct.fea.node.FrequencyModes 33 | :members: 34 | :special-members: __init__ 35 | -------------------------------------------------------------------------------- /todo.md: -------------------------------------------------------------------------------- 1 | # To-Do List: 2 | 3 | ## Class Implementation: 4 | 5 | - [x] Easier retrieval of displacements (also at positions along elements) 6 | - [x] Add get_sampling_points method for frame elements - use for everything! 7 | - [x] Method for moving & copying nodes 8 | - [ ] Load combinations 9 | 10 | ## Pre-Processor: 11 | 12 | - [ ] Triangular meshing 13 | 14 | ## FE Engine: 15 | 16 | - [x] 3d truss elements 17 | - [ ] 3d frame elements 18 | - [ ] Spring supports 19 | - [x] Distributed loads 20 | - [ ] Body loads 21 | - [ ] Thermal loads 22 | - [ ] MP Constraints 23 | - [ ] Frame releases 24 | - [ ] Rotational stiffness 25 | - [ ] GNL 26 | - [ ] MNL 27 | - [ ] Plane stress 28 | 29 | ## Post-Processor: 30 | 31 | - [ ] pyVista module 32 | - [ ] Line contour plots (e.g. displacement) 33 | -------------------------------------------------------------------------------- /docs/build/html/_sources/rst/node.rst.txt: -------------------------------------------------------------------------------- 1 | Node 2 | ==== 3 | 4 | Node 5 | ---- 6 | 7 | .. autoclass:: feastruct.fea.node.Node 8 | :members: 9 | :special-members: __init__ 10 | 11 | DoF 12 | --- 13 | 14 | .. autoclass:: feastruct.fea.node.DoF 15 | :members: 16 | :special-members: __init__ 17 | 18 | Displacement 19 | ------------ 20 | .. autoclass:: feastruct.fea.node.Displacement 21 | :members: 22 | :special-members: __init__ 23 | 24 | Buckling Modes 25 | -------------- 26 | .. autoclass:: feastruct.fea.node.BucklingModes 27 | :members: 28 | :special-members: __init__ 29 | 30 | Frequency Modes 31 | --------------- 32 | .. autoclass:: feastruct.fea.node.FrequencyModes 33 | :members: 34 | :special-members: __init__ 35 | -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | from setuptools import setup 2 | 3 | 4 | def readme(): 5 | with open('README.md') as f: 6 | return f.read() 7 | 8 | 9 | setup(name='feastruct', 10 | version='0.1', 11 | description='A python package for structural finite element analysis.', 12 | long_description=readme(), 13 | long_description_content_type='text/markdown', 14 | url='https://github.com/robbievanleeuwen/feastruct', 15 | author='Robbie van Leeuwen', 16 | author_email='robbie.vanleeuwen@gmail.com', 17 | license='MIT', 18 | packages=[ 19 | 'feastruct', 'feastruct.fea', 'feastruct.fea.elements', 'feastruct.post', 20 | 'feastruct.pre', 'feastruct.solvers', 21 | 'feastruct.examples', 'feastruct.tests.implementation', 22 | 'feastruct.tests.mastan2_textbook' 23 | ], 24 | install_requires=[ 25 | 'numpy', 'scipy', 'matplotlib' 26 | ], 27 | include_package_data=True, 28 | zip_safe=False) 29 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 Robbie van Leeuwen 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /feastruct/pre/section.py: -------------------------------------------------------------------------------- 1 | class Section: 2 | """Class for storing cross-section properties. 3 | 4 | :cvar string name: Section name 5 | :cvar float area: Cross-sectional area 6 | :cvar float ixx: Second moment of area about the centroidal x-axis 7 | :cvar float iyy: Second moment of area about the centroidal y-axis 8 | :cvar float j: Torsion constant 9 | :cvar float A_sx: Shear area about the x-axis 10 | :cvar float A_sy: Shear area about the y-axis 11 | :cvar colour: Section colour for rendering 12 | :vartype colour: :class:`matplotlib.colors` 13 | """ 14 | 15 | def __init__(self, name='', area=1, ixx=1, iyy=1, j=1, A_sx=1, A_sy=1, colour='k'): 16 | """Inits the Section class. 17 | 18 | :param string name: Section name 19 | :param float area: Cross-sectional area 20 | :param float ixx: Second moment of area about the centroidal x-axis 21 | :param float iyy: Second moment of area about the centroidal y-axis 22 | :param float j: Torsion constant 23 | :param float A_sx: Shear area about the x-axis 24 | :param float A_sy: Shear area about the y-axis 25 | :param colour: Section colour for rendering 26 | :type colour: :class:`matplotlib.colors` 27 | """ 28 | 29 | self.name = name 30 | self.area = area 31 | self.ixx = ixx 32 | self.iyy = iyy 33 | self.j = j 34 | self.A_sx = A_sx 35 | self.A_sy = A_sy 36 | self.colour = colour 37 | -------------------------------------------------------------------------------- /docs/source/rst/solvers.rst: -------------------------------------------------------------------------------- 1 | Solvers 2 | ======= 3 | 4 | FEA Solve 5 | --------- 6 | 7 | .. autoclass:: feastruct.solvers.feasolve.Solver 8 | :members: 9 | :special-members: __init__ 10 | 11 | Linear Static Solver 12 | ^^^^^^^^^^^^^^^^^^^^ 13 | 14 | .. autoclass:: feastruct.solvers.linstatic.LinearStatic 15 | :members: 16 | :special-members: __init__ 17 | :show-inheritance: 18 | :inherited-members: 19 | 20 | Linear Buckling Solver 21 | ^^^^^^^^^^^^^^^^^^^^^^ 22 | 23 | .. autoclass:: feastruct.solvers.linbuckling.LinearBuckling 24 | :members: 25 | :special-members: __init__ 26 | :show-inheritance: 27 | :inherited-members: 28 | 29 | Natural Frequency Solver 30 | ^^^^^^^^^^^^^^^^^^^^^^^^ 31 | 32 | .. autoclass:: feastruct.solvers.naturalfrequency.NaturalFrequency 33 | :members: 34 | :special-members: __init__ 35 | :show-inheritance: 36 | :inherited-members: 37 | 38 | 39 | Solver Settings 40 | --------------- 41 | 42 | .. autoclass:: feastruct.solvers.feasolve.SolverSettings 43 | :members: 44 | :special-members: __init__ 45 | 46 | Linear Static Settings 47 | ^^^^^^^^^^^^^^^^^^^^^^ 48 | 49 | .. autoclass:: feastruct.solvers.feasolve.LinearStaticSettings 50 | :members: 51 | :special-members: __init__ 52 | :show-inheritance: 53 | :inherited-members: 54 | 55 | Linear Buckling Settings 56 | ^^^^^^^^^^^^^^^^^^^^^^^^ 57 | 58 | .. autoclass:: feastruct.solvers.feasolve.LinearBucklingSettings 59 | :members: 60 | :special-members: __init__ 61 | :show-inheritance: 62 | :inherited-members: 63 | 64 | Natural Frequency Settings 65 | ^^^^^^^^^^^^^^^^^^^^^^^^^^ 66 | 67 | .. autoclass:: feastruct.solvers.feasolve.NaturalFrequencySettings 68 | :members: 69 | :special-members: __init__ 70 | :show-inheritance: 71 | :inherited-members: 72 | -------------------------------------------------------------------------------- /docs/build/html/_sources/rst/solvers.rst.txt: -------------------------------------------------------------------------------- 1 | Solvers 2 | ======= 3 | 4 | FEA Solve 5 | --------- 6 | 7 | .. autoclass:: feastruct.solvers.feasolve.Solver 8 | :members: 9 | :special-members: __init__ 10 | 11 | Linear Static Solver 12 | ^^^^^^^^^^^^^^^^^^^^ 13 | 14 | .. autoclass:: feastruct.solvers.linstatic.LinearStatic 15 | :members: 16 | :special-members: __init__ 17 | :show-inheritance: 18 | :inherited-members: 19 | 20 | Linear Buckling Solver 21 | ^^^^^^^^^^^^^^^^^^^^^^ 22 | 23 | .. autoclass:: feastruct.solvers.linbuckling.LinearBuckling 24 | :members: 25 | :special-members: __init__ 26 | :show-inheritance: 27 | :inherited-members: 28 | 29 | Natural Frequency Solver 30 | ^^^^^^^^^^^^^^^^^^^^^^^^ 31 | 32 | .. autoclass:: feastruct.solvers.naturalfrequency.NaturalFrequency 33 | :members: 34 | :special-members: __init__ 35 | :show-inheritance: 36 | :inherited-members: 37 | 38 | 39 | Solver Settings 40 | --------------- 41 | 42 | .. autoclass:: feastruct.solvers.feasolve.SolverSettings 43 | :members: 44 | :special-members: __init__ 45 | 46 | Linear Static Settings 47 | ^^^^^^^^^^^^^^^^^^^^^^ 48 | 49 | .. autoclass:: feastruct.solvers.feasolve.LinearStaticSettings 50 | :members: 51 | :special-members: __init__ 52 | :show-inheritance: 53 | :inherited-members: 54 | 55 | Linear Buckling Settings 56 | ^^^^^^^^^^^^^^^^^^^^^^^^ 57 | 58 | .. autoclass:: feastruct.solvers.feasolve.LinearBucklingSettings 59 | :members: 60 | :special-members: __init__ 61 | :show-inheritance: 62 | :inherited-members: 63 | 64 | Natural Frequency Settings 65 | ^^^^^^^^^^^^^^^^^^^^^^^^^^ 66 | 67 | .. autoclass:: feastruct.solvers.feasolve.NaturalFrequencySettings 68 | :members: 69 | :special-members: __init__ 70 | :show-inheritance: 71 | :inherited-members: 72 | -------------------------------------------------------------------------------- /feastruct/pre/material.py: -------------------------------------------------------------------------------- 1 | class Material: 2 | """Class for structural materials (assumed isotropic). 3 | 4 | Provides a way of storing material properties related to a specific material. The colour can be 5 | a multitude of different formats, refer to https://matplotlib.org/api/colors_api.html and 6 | https://matplotlib.org/examples/color/named_colors.html for more information. 7 | 8 | :cvar string name: Material name 9 | :cvar float elastic_modulus: Material modulus of elasticity 10 | :cvar float poissons_ratio: Material Poisson's ratio 11 | :cvar float shear_modulus: Material shear modulus, derived from the elastic modulus and 12 | Poisson's ratio assuming an isotropic material 13 | :cvar float rho: Material density 14 | :cvar colour: Material colour for rendering 15 | :vartype colour: :class:`matplotlib.colors` 16 | """ 17 | 18 | def __init__(self, name, elastic_modulus, poissons_ratio, rho, colour='w'): 19 | """Inits the Material class. 20 | 21 | :param string name: Material name 22 | :param float elastic_modulus: Material modulus of elasticity 23 | :param float poissons_ratio: Material Poisson's ratio 24 | :param float rho: Material density 25 | :param colour: Material color for rendering 26 | :type colour: :class:`matplotlib.colors` 27 | """ 28 | 29 | self.name = name 30 | self.elastic_modulus = elastic_modulus 31 | self.poissons_ratio = poissons_ratio 32 | self.shear_modulus = elastic_modulus / (2 * (1 + poissons_ratio)) 33 | self.rho = rho 34 | self.colour = colour 35 | 36 | 37 | class Steel(Material): 38 | """Class for structural steel to AS4100-1998. 39 | 40 | Material properties: 41 | 42 | * name: steel 43 | * elastic_modulus: 200000 N/mm2 44 | * poissons_ratio: 0.3 45 | * rho: 7.85e-9 T/mm^3 46 | * colour: lightgrey 47 | """ 48 | 49 | def __init__(self): 50 | """Inits the Steel class.""" 51 | 52 | super().__init__(name='steel', elastic_modulus=2e5, poissons_ratio=0.3, rho=7.85e-9, 53 | colour='lightgrey') 54 | -------------------------------------------------------------------------------- /feastruct/examples/frequency.py: -------------------------------------------------------------------------------- 1 | from feastruct.pre.material import Steel 2 | from feastruct.pre.section import Section 3 | import feastruct.fea.cases as cases 4 | from feastruct.fea.frame_analysis import FrameAnalysis2D 5 | from feastruct.solvers.naturalfrequency import NaturalFrequency 6 | from feastruct.solvers.feasolve import SolverSettings 7 | 8 | # ------------ 9 | # preprocessor 10 | # ------------ 11 | 12 | # constants & lists 13 | height = 20000 # length of the beam 14 | num_nodes = 21 # number of nodes to use 15 | num_modes = 6 # number of modes to calculate 16 | nodes = [] # list holding the node objects 17 | elements = [] # list holding the element objects 18 | 19 | # create 2d frame analysis object 20 | analysis = FrameAnalysis2D() 21 | 22 | # create materials and sections 23 | steel = Steel() 24 | section = Section(area=10400, ixx=88.3e6) 25 | 26 | # create nodes 27 | for i in range(num_nodes): 28 | nodes.append(analysis.create_node(coords=[0, height / (num_nodes - 1) * i])) 29 | 30 | # create beam elements 31 | for i in range(num_nodes - 1): 32 | elements.append(analysis.create_element( 33 | el_type='EB2-2D', 34 | nodes=[nodes[i], nodes[i+1]], 35 | material=steel, 36 | section=section 37 | )) 38 | 39 | # add supports - fixed base 40 | freedom_case = cases.FreedomCase() 41 | freedom_case.add_nodal_support(node=nodes[0], val=0, dof=0) 42 | freedom_case.add_nodal_support(node=nodes[0], val=0, dof=1) 43 | freedom_case.add_nodal_support(node=nodes[0], val=0, dof=5) 44 | 45 | # add analysis case 46 | analysis_case = cases.AnalysisCase(freedom_case=freedom_case, load_case=cases.LoadCase()) 47 | 48 | # ---------------- 49 | # frequency solver 50 | # ---------------- 51 | 52 | settings = SolverSettings() 53 | settings.natural_frequency.time_info = True 54 | settings.natural_frequency.num_modes = num_modes 55 | 56 | solver = NaturalFrequency( 57 | analysis=analysis, analysis_cases=[analysis_case], solver_settings=settings) 58 | solver.solve() 59 | 60 | # -------------- 61 | # frequency post 62 | # -------------- 63 | 64 | for i in range(num_modes): 65 | analysis.post.plot_frequency_results(analysis_case=analysis_case, frequency_mode=i) 66 | -------------------------------------------------------------------------------- /feastruct/examples/beam_udl.py: -------------------------------------------------------------------------------- 1 | from feastruct.pre.material import Steel 2 | from feastruct.pre.section import Section 3 | import feastruct.fea.cases as cases 4 | from feastruct.fea.frame_analysis import FrameAnalysis2D 5 | from feastruct.solvers.linstatic import LinearStatic 6 | from feastruct.solvers.feasolve import SolverSettings 7 | 8 | # ------------ 9 | # preprocessor 10 | # ------------ 11 | 12 | # constants & lists 13 | length = 5000 # length of the beam 14 | udl = -10 # value of the udl 15 | 16 | # create 2d frame analysis object 17 | analysis = FrameAnalysis2D() 18 | 19 | # create materials and sections 20 | steel = Steel() 21 | section = Section(area=3230, ixx=23.6e6) 22 | 23 | # create nodes 24 | node1 = analysis.create_node(coords=[0]) 25 | node2 = analysis.create_node(coords=[length]) 26 | node3 = analysis.create_node(coords=[2*length]) 27 | 28 | # create beam element 29 | beam1 = analysis.create_element( 30 | el_type='EB2-2D', nodes=[node1, node2], material=steel, section=section 31 | ) 32 | beam2 = analysis.create_element( 33 | el_type='EB2-2D', nodes=[node2, node3], material=steel, section=section 34 | ) 35 | 36 | # add supports 37 | freedom_case = cases.FreedomCase() 38 | freedom_case.add_nodal_support(node=node1, val=0, dof=0) 39 | freedom_case.add_nodal_support(node=node1, val=0, dof=1) 40 | freedom_case.add_nodal_support(node=node2, val=0, dof=1) 41 | freedom_case.add_nodal_support(node=node3, val=0, dof=1) 42 | 43 | # add loads 44 | load_case = cases.LoadCase() 45 | load_case.add_element_load(beam1.generate_udl(q=udl)) 46 | load_case.add_element_load(beam2.generate_udl(q=udl)) 47 | 48 | # add analysis case 49 | analysis_case = cases.AnalysisCase(freedom_case=freedom_case, load_case=load_case) 50 | 51 | # ------ 52 | # solver 53 | # ------ 54 | 55 | settings = SolverSettings() 56 | settings.linear_static.time_info = True 57 | 58 | LinearStatic(analysis=analysis, analysis_cases=[analysis_case], solver_settings=settings).solve() 59 | 60 | # ---- 61 | # post 62 | # ---- 63 | 64 | analysis.post.plot_geom(analysis_case=analysis_case) 65 | analysis.post.plot_geom(analysis_case=analysis_case, deformed=True, def_scale=100) 66 | analysis.post.plot_frame_forces(analysis_case=analysis_case, shear=True) 67 | analysis.post.plot_frame_forces(analysis_case=analysis_case, moment=True) 68 | analysis.post.plot_reactions(analysis_case=analysis_case) 69 | -------------------------------------------------------------------------------- /feastruct/examples/beam.py: -------------------------------------------------------------------------------- 1 | from feastruct.pre.material import Steel 2 | from feastruct.pre.section import Section 3 | import feastruct.fea.cases as cases 4 | from feastruct.fea.frame_analysis import FrameAnalysis2D 5 | from feastruct.solvers.linstatic import LinearStatic 6 | from feastruct.solvers.feasolve import SolverSettings 7 | 8 | # ------------ 9 | # preprocessor 10 | # ------------ 11 | 12 | # constants & lists 13 | length = 5000 # length of the beam 14 | num_nodes = 3 # number of nodes to use 15 | nodes = [] # list holding the node objects 16 | elements = [] # list holding the element objects 17 | 18 | # create 2d frame analysis object 19 | analysis = FrameAnalysis2D() 20 | 21 | # create materials and sections 22 | steel = Steel() 23 | section = Section(area=3230, ixx=23.6e6) 24 | 25 | # create nodes 26 | for i in range(num_nodes): 27 | nodes.append(analysis.create_node(coords=[length / (num_nodes - 1) * i])) 28 | 29 | # create beam elements 30 | for i in range(num_nodes - 1): 31 | elements.append(analysis.create_element( 32 | el_type='EB2-2D', 33 | nodes=[nodes[i], nodes[i+1]], 34 | material=steel, 35 | section=section 36 | )) 37 | 38 | # add supports 39 | freedom_case = cases.FreedomCase() 40 | freedom_case.add_nodal_support(node=nodes[0], val=0, dof=0) 41 | freedom_case.add_nodal_support(node=nodes[0], val=0, dof=1) 42 | freedom_case.add_nodal_support(node=nodes[-1], val=0, dof=1) 43 | 44 | # add loads 45 | load_case = cases.LoadCase() 46 | 47 | for i in range(num_nodes - 2): 48 | load_case.add_nodal_load(node=nodes[i+1], val=-1e4, dof=1) 49 | 50 | # add analysis case 51 | analysis_case = cases.AnalysisCase(freedom_case=freedom_case, load_case=load_case) 52 | 53 | # ------ 54 | # solver 55 | # ------ 56 | 57 | settings = SolverSettings() 58 | settings.linear_static.time_info = True 59 | 60 | LinearStatic(analysis=analysis, analysis_cases=[analysis_case], solver_settings=settings).solve() 61 | 62 | # ---- 63 | # post 64 | # ---- 65 | 66 | analysis.post.plot_geom(analysis_case=analysis_case) 67 | analysis.post.plot_geom(analysis_case=analysis_case, deformed=True, def_scale=25) 68 | analysis.post.plot_frame_forces(analysis_case=analysis_case, axial=True) 69 | analysis.post.plot_frame_forces(analysis_case=analysis_case, shear=True) 70 | analysis.post.plot_frame_forces(analysis_case=analysis_case, moment=True) 71 | analysis.post.plot_reactions(analysis_case=analysis_case) 72 | -------------------------------------------------------------------------------- /feastruct/tests/implementation/test_frame_element.py: -------------------------------------------------------------------------------- 1 | import unittest 2 | import numpy as np 3 | from feastruct.fea.node import Node 4 | from feastruct.pre.material import Steel 5 | from feastruct.pre.section import Section 6 | from feastruct.fea.elements.frame import FrameElement 7 | from feastruct.fea.elements.frame2d import FrameElement2D 8 | from feastruct.fea.cases import AnalysisCase 9 | 10 | 11 | class TestFrameElement(unittest.TestCase): 12 | """Tests the functionality of the FrameElement class""" 13 | 14 | def setUp(self): 15 | steel = Steel() 16 | section = Section() 17 | 18 | # create an FrameElement2D elemnetn 19 | self.x = 4 20 | self.y = 3 21 | self.node1 = Node([0, 0]) 22 | self.node2 = Node([self.x, self.y]) 23 | 24 | self.element_frame = FrameElement( 25 | nodes=[self.node1, self.node2], material=steel, section=section, 26 | efs=[True, True, False, False, False, True] 27 | ) 28 | self.element_frame2D = FrameElement2D( 29 | nodes=[self.node1, self.node2], material=steel, section=section, 30 | efs=[True, True, False, False, False, False] 31 | ) 32 | 33 | def test_get_geometric_properties(self): 34 | (node_coords, dx, l0, c) = self.element_frame.get_geometric_properties() 35 | 36 | coord_list = np.array([ 37 | [0, 0, 0], 38 | [self.x, self.y, 0], 39 | ]) 40 | 41 | c_check = np.array([self.x, self.y, 0]) / np.sqrt(self.x ** 2 + self.y ** 2) 42 | 43 | self.assertEqual(node_coords.tolist(), coord_list.tolist()) 44 | self.assertEqual(np.array([self.x, self.y, 0]).tolist(), dx.tolist()) 45 | self.assertEqual(l0, np.sqrt(self.x ** 2 + self.y ** 2)) 46 | self.assertEqual(c.tolist(), c_check.tolist()) 47 | 48 | def test_get_nodal_displacements(self): 49 | # add dummy analysis case 50 | case1 = AnalysisCase('fc', 'lc') 51 | case2 = AnalysisCase('fc', 'lc') 52 | 53 | # create dummy displacements 54 | dof_count = 0 55 | 56 | for node in self.element_frame2D.nodes: 57 | for dof in node.dofs: 58 | dof.save_displacement(dof_count, case1) 59 | dof_count += 1 60 | 61 | dof_nums = [0, 1, 5] 62 | nodal_disps = self.element_frame2D.get_nodal_displacements(case1) 63 | 64 | for (i, node) in enumerate(nodal_disps): 65 | for (j, disp) in enumerate(node): 66 | self.assertEqual(disp, 6 * i + dof_nums[j]) 67 | 68 | # check exception 69 | with self.assertRaises(Exception): 70 | self.element_frame2D.get_nodal_displacements(case2) 71 | 72 | 73 | if __name__ == "__main__": 74 | unittest.main() 75 | -------------------------------------------------------------------------------- /feastruct/examples/buckle.py: -------------------------------------------------------------------------------- 1 | from feastruct.pre.material import Steel 2 | from feastruct.pre.section import Section 3 | import feastruct.fea.cases as cases 4 | from feastruct.fea.frame_analysis import FrameAnalysis2D 5 | from feastruct.solvers.linstatic import LinearStatic 6 | from feastruct.solvers.linbuckling import LinearBuckling 7 | from feastruct.solvers.feasolve import SolverSettings 8 | 9 | 10 | # ------------ 11 | # preprocessor 12 | # ------------ 13 | 14 | # constants & lists 15 | L = 5000 # length of the beams 16 | n_el = 12 # number of subdivisions for each beam 17 | nodes = [] # list holding the node objects 18 | elements = [] # list holding the element objects 19 | 20 | # create 2d frame analysis object 21 | analysis = FrameAnalysis2D() 22 | analysis.post.n_subdiv = 5 23 | 24 | # create materials and sections 25 | steel = Steel() 26 | section = Section(area=1000, ixx=8.333e5) 27 | 28 | # create nodes (portal frame) 29 | for i in range(n_el + 1): 30 | nodes.append(analysis.create_node(coords=[0, i * L / n_el])) 31 | 32 | for i in range(n_el + 1, 2 * n_el + 1): 33 | nodes.append(analysis.create_node(coords=[(i - n_el) * L / n_el, L])) 34 | 35 | for i in range(2 * n_el + 1, 3 * n_el + 1): 36 | nodes.append(analysis.create_node(coords=[L, L - (i - 2 * n_el) * L / n_el])) 37 | 38 | # create elements 39 | for i in range(3 * n_el): 40 | elements.append(analysis.create_element( 41 | el_type='EB2-2D', 42 | nodes=[nodes[i], nodes[i+1]], 43 | material=steel, 44 | section=section 45 | )) 46 | 47 | # add supports 48 | freedom_case = cases.FreedomCase() 49 | freedom_case.add_nodal_support(node=nodes[0], val=0, dof=0) 50 | freedom_case.add_nodal_support(node=nodes[0], val=0, dof=1) 51 | freedom_case.add_nodal_support(node=nodes[-1], val=0, dof=0) 52 | freedom_case.add_nodal_support(node=nodes[-1], val=0, dof=1) 53 | 54 | # add loads 55 | load_case = cases.LoadCase() 56 | load_case.add_nodal_load(node=nodes[int(n_el*1.5)], val=-1e3, dof=1) 57 | 58 | # add analysis case 59 | analysis_case = cases.AnalysisCase(freedom_case=freedom_case, load_case=load_case) 60 | 61 | # ------------- 62 | # static solver 63 | # ------------- 64 | 65 | settings = SolverSettings() 66 | settings.linear_static.time_info = True 67 | 68 | LinearStatic(analysis=analysis, analysis_cases=[analysis_case], solver_settings=settings).solve() 69 | 70 | # ----------- 71 | # static post 72 | # ----------- 73 | 74 | analysis.post.plot_geom(analysis_case=analysis_case, deformed=True, def_scale=25) 75 | analysis.post.plot_frame_forces(analysis_case=analysis_case, axial=True) 76 | analysis.post.plot_frame_forces(analysis_case=analysis_case, shear=True) 77 | analysis.post.plot_frame_forces(analysis_case=analysis_case, moment=True) 78 | 79 | # --------------- 80 | # buckling solver 81 | # --------------- 82 | 83 | settings.linear_buckling.time_info = True 84 | 85 | LinearBuckling(analysis=analysis, analysis_cases=[analysis_case], solver_settings=settings).solve() 86 | 87 | # ------------- 88 | # buckling post 89 | # ------------- 90 | 91 | for i in range(settings.linear_buckling.num_modes): 92 | analysis.post.plot_buckling_results(analysis_case=analysis_case, buckling_mode=i) 93 | -------------------------------------------------------------------------------- /docs/build/html/_static/css/badge_only.css: -------------------------------------------------------------------------------- 1 | .fa:before{-webkit-font-smoothing:antialiased}.clearfix{*zoom:1}.clearfix:before,.clearfix:after{display:table;content:""}.clearfix:after{clear:both}@font-face{font-family:FontAwesome;font-weight:normal;font-style:normal;src:url("../fonts/fontawesome-webfont.eot");src:url("../fonts/fontawesome-webfont.eot?#iefix") format("embedded-opentype"),url("../fonts/fontawesome-webfont.woff") format("woff"),url("../fonts/fontawesome-webfont.ttf") format("truetype"),url("../fonts/fontawesome-webfont.svg#FontAwesome") format("svg")}.fa:before{display:inline-block;font-family:FontAwesome;font-style:normal;font-weight:normal;line-height:1;text-decoration:inherit}a .fa{display:inline-block;text-decoration:inherit}li .fa{display:inline-block}li .fa-large:before,li .fa-large:before{width:1.875em}ul.fas{list-style-type:none;margin-left:2em;text-indent:-0.8em}ul.fas li .fa{width:.8em}ul.fas li .fa-large:before,ul.fas li .fa-large:before{vertical-align:baseline}.fa-book:before{content:""}.icon-book:before{content:""}.fa-caret-down:before{content:""}.icon-caret-down:before{content:""}.fa-caret-up:before{content:""}.icon-caret-up:before{content:""}.fa-caret-left:before{content:""}.icon-caret-left:before{content:""}.fa-caret-right:before{content:""}.icon-caret-right:before{content:""}.rst-versions{position:fixed;bottom:0;left:0;width:300px;color:#fcfcfc;background:#1f1d1d;font-family:"Lato","proxima-nova","Helvetica Neue",Arial,sans-serif;z-index:400}.rst-versions a{color:#2980B9;text-decoration:none}.rst-versions .rst-badge-small{display:none}.rst-versions .rst-current-version{padding:12px;background-color:#272525;display:block;text-align:right;font-size:90%;cursor:pointer;color:#27AE60;*zoom:1}.rst-versions .rst-current-version:before,.rst-versions .rst-current-version:after{display:table;content:""}.rst-versions .rst-current-version:after{clear:both}.rst-versions .rst-current-version .fa{color:#fcfcfc}.rst-versions .rst-current-version .fa-book{float:left}.rst-versions .rst-current-version .icon-book{float:left}.rst-versions .rst-current-version.rst-out-of-date{background-color:#E74C3C;color:#fff}.rst-versions .rst-current-version.rst-active-old-version{background-color:#F1C40F;color:#000}.rst-versions.shift-up{height:auto;max-height:100%}.rst-versions.shift-up .rst-other-versions{display:block}.rst-versions .rst-other-versions{font-size:90%;padding:12px;color:gray;display:none}.rst-versions .rst-other-versions hr{display:block;height:1px;border:0;margin:20px 0;padding:0;border-top:solid 1px #413d3d}.rst-versions .rst-other-versions dd{display:inline-block;margin:0}.rst-versions .rst-other-versions dd a{display:inline-block;padding:6px;color:#fcfcfc}.rst-versions.rst-badge{width:auto;bottom:20px;right:20px;left:auto;border:none;max-width:300px}.rst-versions.rst-badge .icon-book{float:none}.rst-versions.rst-badge .fa-book{float:none}.rst-versions.rst-badge.shift-up .rst-current-version{text-align:right}.rst-versions.rst-badge.shift-up .rst-current-version .fa-book{float:left}.rst-versions.rst-badge.shift-up .rst-current-version .icon-book{float:left}.rst-versions.rst-badge .rst-current-version{width:auto;height:30px;line-height:30px;padding:0 6px;display:block;text-align:center}@media screen and (max-width: 768px){.rst-versions{width:85%;display:none}.rst-versions.shift{display:block}} 2 | -------------------------------------------------------------------------------- /feastruct/tests/implementation/test_finite_element.py: -------------------------------------------------------------------------------- 1 | import unittest 2 | import numpy as np 3 | from feastruct.fea.node import Node 4 | from feastruct.pre.material import Steel 5 | from feastruct.fea.fea import FiniteElement 6 | from feastruct.fea.cases import AnalysisCase 7 | 8 | 9 | class TestFiniteElement(unittest.TestCase): 10 | """Tests the functionality of the FiniteElement class""" 11 | 12 | def setUp(self): 13 | steel = Steel() 14 | 15 | # create a rectangular element 16 | self.width = 5 17 | self.height = 3 18 | 19 | self.node1 = Node([0, 0]) 20 | self.node2 = Node([self.width, 0]) 21 | self.node3 = Node([self.width, self.height]) 22 | self.node4 = Node([0, self.height]) 23 | 24 | self.element = FiniteElement( 25 | nodes=[self.node1, self.node2, self.node3, self.node4], 26 | material=steel, efs=[True, True, False, False, False, False] 27 | ) 28 | 29 | def test_get_node_coords(self): 30 | coord_list = np.array([ 31 | [0, 0, 0], 32 | [self.width, 0, 0], 33 | [self.width, self.height, 0], 34 | [0, self.height, 0] 35 | ]) 36 | 37 | self.assertEqual(coord_list.tolist(), self.element.get_node_coords().tolist()) 38 | 39 | def test_get_dofs(self): 40 | indices = [i for i, x in enumerate(self.element.efs) if x] 41 | 42 | dof_list = self.element.get_dofs() 43 | 44 | for (i, node) in enumerate(dof_list): 45 | for (j, dof) in enumerate(node): 46 | self.assertTrue(dof is self.element.nodes[i].dofs[indices[j]]) 47 | 48 | def test_get_nodal_displacements(self): 49 | # add dummy analysis case 50 | case1 = AnalysisCase('fc', 'lc') 51 | case2 = AnalysisCase('fc', 'lc') 52 | 53 | # create dummy displacements 54 | dof_count = 0 55 | 56 | for node in self.element.nodes: 57 | for dof in node.dofs: 58 | dof.save_displacement(dof_count, case1) 59 | dof_count += 1 60 | 61 | indices = [i for i, x in enumerate(self.element.efs) if x] 62 | nodal_disps = self.element.get_nodal_displacements(case1) 63 | 64 | for (i, node) in enumerate(nodal_disps): 65 | for (j, disp) in enumerate(node): 66 | self.assertEqual(disp, 6 * i + indices[j]) 67 | 68 | # check exception 69 | with self.assertRaises(Exception): 70 | self.element.get_nodal_displacements(case2) 71 | 72 | def test_fint(self): 73 | # add dummy analysis case 74 | case1 = AnalysisCase('fc', 'lc') 75 | case2 = AnalysisCase('fc', 'lc') 76 | case3 = AnalysisCase('fc', 'lc') 77 | 78 | # create dummy force vector 79 | f1 = np.array(range(8)) 80 | f2 = 3 * np.array(range(8)) 81 | 82 | # save fint 83 | self.element.save_fint(f1, case1) 84 | self.element.save_fint(f2, case2) 85 | 86 | # get fint 87 | f_res1 = self.element.get_fint(case1) 88 | f_res2 = self.element.get_fint(case2) 89 | 90 | self.assertEqual(f1.tolist(), f_res1.tolist()) 91 | self.assertEqual(f2.tolist(), f_res2.tolist()) 92 | 93 | # check exception 94 | with self.assertRaises(Exception): 95 | self.element.get_fint(case3) 96 | 97 | 98 | if __name__ == "__main__": 99 | unittest.main() 100 | -------------------------------------------------------------------------------- /feastruct/tests/implementation/test_node.py: -------------------------------------------------------------------------------- 1 | import unittest 2 | import numpy as np 3 | from feastruct.fea.node import Node 4 | from feastruct.fea.cases import AnalysisCase 5 | 6 | 7 | class TestNode(unittest.TestCase): 8 | """Tests the functionality of the Node class""" 9 | 10 | def setUp(self): 11 | self.x = 5 12 | self.y = 10 13 | self.z = 0 14 | self.node = Node([self.x, self.y, self.z]) 15 | 16 | def test_coordinates(self): 17 | self.assertTrue(np.isclose(self.node.x, self.x)) 18 | self.assertTrue(np.isclose(self.node.y, self.y)) 19 | self.assertTrue(np.isclose(self.node.z, self.z)) 20 | 21 | def test_dof_size(self): 22 | self.assertTrue(len(self.node.dofs) == 6) 23 | 24 | def test_dof_parent(self): 25 | for dof in self.node.dofs: 26 | self.assertTrue(dof.node is self.node) 27 | 28 | def test_node_dof_nums(self): 29 | for (i, dof) in enumerate(self.node.dofs): 30 | self.assertTrue(dof.node_dof_num is i) 31 | 32 | def test_node_get_dofs(self): 33 | # case 1 - 3D dofs 34 | freedom_signature = [True, True, True, True, True, True] 35 | indices = [i for i, x in enumerate(freedom_signature) if x] 36 | 37 | dof_list = self.node.get_dofs(freedom_signature) 38 | 39 | for (i, dof) in enumerate(dof_list): 40 | self.assertTrue(dof.node_dof_num == indices[i]) 41 | 42 | # case 2 - 2D dofs 43 | freedom_signature = [True, True, False, False, False, True] 44 | indices = [i for i, x in enumerate(freedom_signature) if x] 45 | 46 | dof_list = self.node.get_dofs(freedom_signature) 47 | 48 | for (i, dof) in enumerate(dof_list): 49 | self.assertTrue(dof.node_dof_num == indices[i]) 50 | 51 | # case 3 - single DoF 52 | freedom_signature = [True, False, False, False, False, False] 53 | indices = [i for i, x in enumerate(freedom_signature) if x] 54 | 55 | dof_list = self.node.get_dofs(freedom_signature) 56 | 57 | for (i, dof) in enumerate(dof_list): 58 | self.assertTrue(dof.node_dof_num == indices[i]) 59 | 60 | def test_dof_displacements(self): 61 | # add dummy analysis case 62 | case1 = AnalysisCase('fc', 'lc') 63 | case2 = AnalysisCase('fc', 'lc') 64 | 65 | # create dummy displacements 66 | for (i, dof) in enumerate(self.node.dofs): 67 | dof.save_displacement(i, case1) 68 | 69 | # get displacements 70 | for (i, dof) in enumerate(self.node.dofs): 71 | self.assertEqual(dof.get_displacement(case1), i) 72 | 73 | # check exception 74 | with self.assertRaises(Exception): 75 | dof.get_displacement(case2) 76 | 77 | def test_node_displacements(self): 78 | # add dummy analysis case 79 | case1 = AnalysisCase('fc', 'lc') 80 | 81 | # create dummy displacements 82 | for (i, dof) in enumerate(self.node.dofs): 83 | # don't save dof index 4 84 | if i == 4: 85 | pass 86 | else: 87 | dof.save_displacement(i, case1) 88 | 89 | # get displacements 90 | disp_vector = self.node.get_displacements(case1) 91 | 92 | for (i, disp) in enumerate(disp_vector): 93 | if i == 4: 94 | self.assertEqual(disp, None) 95 | else: 96 | self.assertEqual(disp, i) 97 | 98 | 99 | if __name__ == "__main__": 100 | unittest.main() 101 | -------------------------------------------------------------------------------- /feastruct/examples/frame.py: -------------------------------------------------------------------------------- 1 | from feastruct.pre.material import Steel 2 | from feastruct.pre.section import Section 3 | import feastruct.fea.cases as cases 4 | from feastruct.fea.frame_analysis import FrameAnalysis2D 5 | from feastruct.solvers.linstatic import LinearStatic 6 | from feastruct.solvers.feasolve import SolverSettings 7 | 8 | # ------------ 9 | # preprocessor 10 | # ------------ 11 | 12 | # lists 13 | nodes = [] # list holding the node objects 14 | elements = [] # list holding the element objects 15 | freedom_cases = [] # list holding the freedom cases 16 | load_cases = [] # list holding the load cases 17 | analysis_cases = [] # list holding the analysis cases 18 | 19 | # create 2d frame analysis object 20 | analysis = FrameAnalysis2D() 21 | 22 | # create materials and sections 23 | steel = Steel() 24 | section = Section(area=3230, ixx=23.6e6) 25 | 26 | # create nodes 27 | nodes.append(analysis.create_node(coords=[0, 0])) 28 | nodes.append(analysis.create_node(coords=[1500, 0])) 29 | nodes.append(analysis.create_node(coords=[3000, 1500])) 30 | 31 | # create beam elements 32 | for i in range(2): 33 | elements.append(analysis.create_element( 34 | el_type='EB2-2D', 35 | nodes=[nodes[i], nodes[i+1]], 36 | material=steel, 37 | section=section 38 | )) 39 | 40 | # create 3 freedom cases 41 | for i in range(3): 42 | freedom_cases.append(cases.FreedomCase()) 43 | 44 | # freedom case 1: pin middle node, roller right node 45 | freedom_cases[0].add_nodal_support(node=nodes[1], val=0, dof=0) 46 | freedom_cases[0].add_nodal_support(node=nodes[1], val=0, dof=1) 47 | freedom_cases[0].add_nodal_support(node=nodes[2], val=0, dof=1) 48 | 49 | # freedom case 2: imposed displacement left node, pin middle node, roller right node 50 | freedom_cases[1].add_nodal_support(node=nodes[0], val=-10, dof=1) 51 | freedom_cases[1].add_nodal_support(node=nodes[1], val=0, dof=0) 52 | freedom_cases[1].add_nodal_support(node=nodes[1], val=0, dof=1) 53 | freedom_cases[1].add_nodal_support(node=nodes[2], val=0, dof=1) 54 | 55 | # freedom case 3: imposed displacement and rotation left node, pin middle node, roller right node 56 | freedom_cases[2].add_nodal_support(node=nodes[0], val=0.01, dof=5) 57 | freedom_cases[2].add_nodal_support(node=nodes[1], val=0, dof=0) 58 | freedom_cases[2].add_nodal_support(node=nodes[1], val=0, dof=1) 59 | freedom_cases[2].add_nodal_support(node=nodes[2], val=0, dof=1) 60 | 61 | # create 2 load cases 62 | for i in range(2): 63 | load_cases.append(cases.LoadCase()) 64 | 65 | # load case 1: point load at left node 66 | load_cases[0].add_nodal_load(node=nodes[0], val=-1e4, dof=1) 67 | 68 | # load case 2: no loads 69 | 70 | # add analysis cases 71 | analysis_cases.append(cases.AnalysisCase(freedom_case=freedom_cases[0], load_case=load_cases[0])) 72 | analysis_cases.append(cases.AnalysisCase(freedom_case=freedom_cases[1], load_case=load_cases[1])) 73 | analysis_cases.append(cases.AnalysisCase(freedom_case=freedom_cases[2], load_case=load_cases[1])) 74 | 75 | # ------ 76 | # solver 77 | # ------ 78 | 79 | settings = SolverSettings() 80 | settings.linear_static.time_info = True 81 | 82 | LinearStatic(analysis=analysis, analysis_cases=analysis_cases, solver_settings=settings).solve() 83 | 84 | # ---- 85 | # post 86 | # ---- 87 | 88 | # plot the results for each analysis case 89 | for analysis_case in analysis_cases: 90 | analysis.post.plot_geom(analysis_case=analysis_case) 91 | analysis.post.plot_geom(analysis_case=analysis_case, deformed=True, def_scale=10) 92 | analysis.post.plot_frame_forces( 93 | analysis_case=analysis_case, axial=True, shear=True, moment=True) 94 | analysis.post.plot_reactions(analysis_case=analysis_case) 95 | -------------------------------------------------------------------------------- /feastruct/solvers/linbuckling.py: -------------------------------------------------------------------------------- 1 | from feastruct.solvers.feasolve import Solver 2 | 3 | 4 | class LinearBuckling(Solver): 5 | """Class for a linear buckling solver. 6 | 7 | :cvar analysis: Analysis object to solve 8 | :vartype analysis: :class:`~feastruct.fea.fea.FiniteElementAnalysis` 9 | :cvar analysis_cases: List of analysis cases to solve 10 | :vartype analysis_cases: list[:class:`~feastruct.fea.cases.AnalysisCase`] 11 | :cvar solver_settings: Settings to use in the solver 12 | :vartype solver_settings: :class:`~feastruct.solvers.feasolve.SolverSettings` 13 | :cvar int ndof: Number of degrees of freedom in the analysis 14 | """ 15 | 16 | def __init__(self, analysis, analysis_cases, solver_settings=None): 17 | """Inits the LinearBuckling class. 18 | 19 | :param analysis: Analysis object to solve 20 | :type analysis: :class:`~feastruct.fea.fea.FiniteElementAnalysis` 21 | :param analysis_cases: List of analysis cases to solve 22 | :type analysis_cases: list[:class:`~feastruct.fea.cases.AnalysisCase`] 23 | :param solver_settings: Settings to use in the solver - if not supplied, the default 24 | settings are adopted 25 | :type solver_settings: :class:`~feastruct.solvers.feasolve.SolverSettings` 26 | """ 27 | 28 | super().__init__(analysis, analysis_cases, solver_settings) 29 | 30 | # TODO: check that analysis_case results available 31 | 32 | def solve(self): 33 | """Executes the linear buckling finite element solver and saves the relevant results.""" 34 | 35 | if self.solver_settings.linear_buckling.time_info: 36 | print('\n-Starting the linear buckling solver...') 37 | 38 | # assign the global degree of freedom numbers 39 | if self.solver_settings.linear_static.time_info: 40 | str = '--Assigning the global degree of freedom numbers...' 41 | self.function_timer(str, self.assign_dofs) 42 | else: 43 | self.assign_dofs() 44 | 45 | # loop through each analysis case 46 | for (i, analysis_case) in enumerate(self.analysis_cases): 47 | if self.solver_settings.linear_buckling.time_info: 48 | print('\n--Analysis case {0}:'.format(i)) 49 | 50 | # assemble the global stiffness and geometric stiffness matrices 51 | if self.solver_settings.linear_buckling.time_info: 52 | str = '---Assembling the global stiffness and geometric stiffness matrices...' 53 | (K, K_g) = self.function_timer( 54 | str, self.assemble_stiff_matrix, True, analysis_case) 55 | else: 56 | (K, K_g) = self.assemble_stiff_matrix(geometric=True, analysis_case=analysis_case) 57 | 58 | # apply the boundary conditions 59 | K_mod = self.remove_constrained_dofs(K=K, analysis_case=analysis_case) 60 | K_mod_g = self.remove_constrained_dofs(K=K_g, analysis_case=analysis_case) 61 | 62 | # solve for the eigenvalues 63 | if self.solver_settings.linear_buckling.time_info: 64 | str = '---Solving for eigenvalues and eigenvectors ({0} modes)...'.format( 65 | self.solver_settings.linear_buckling.num_modes) 66 | (w, v) = self.function_timer( 67 | str, self.solve_eigenvalue, K_mod, -K_mod_g, 68 | self.solver_settings.linear_buckling) 69 | else: 70 | (w, v) = self.solve_eigenvalue( 71 | A=K_mod, M=-K_mod_g, eigen_settings=self.solver_settings.linear_buckling) 72 | 73 | self.save_buckling_results(w=w, v=v, analysis_case=analysis_case) 74 | -------------------------------------------------------------------------------- /feastruct/examples/arch.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | from feastruct.pre.material import Steel 3 | from feastruct.pre.section import Section 4 | import feastruct.fea.cases as cases 5 | from feastruct.fea.frame_analysis import FrameAnalysis2D 6 | from feastruct.solvers.linstatic import LinearStatic 7 | from feastruct.solvers.linbuckling import LinearBuckling 8 | from feastruct.solvers.naturalfrequency import NaturalFrequency 9 | from feastruct.solvers.feasolve import SolverSettings 10 | 11 | # ------------ 12 | # preprocessor 13 | # ------------ 14 | 15 | # constants & lists 16 | n = 20 # number of elements (make even to ensure point load in centre) 17 | L = 10000 # length of arch 18 | h = 3000 # height of arch 19 | nodes = [] # list holding the node objects 20 | elements = [] # list holding the element objects 21 | 22 | # create 2d frame analysis object 23 | analysis = FrameAnalysis2D() 24 | 25 | # create materials and sections 26 | steel = Steel() 27 | section = Section(area=3230, ixx=23.6e6) 28 | 29 | # create nodes 30 | for i in range(n + 1): 31 | x = i * L / n 32 | y = h * np.sin(np.pi * x / L) 33 | nodes.append(analysis.create_node(coords=[x, y])) 34 | 35 | # create beam elements 36 | for i in range(n): 37 | elements.append(analysis.create_element( 38 | el_type='EB2-2D', 39 | nodes=[nodes[i], nodes[i+1]], 40 | material=steel, 41 | section=section 42 | )) 43 | 44 | # add supports 45 | freedom_case = cases.FreedomCase() 46 | freedom_case.add_nodal_support(node=nodes[0], val=0, dof=0) 47 | freedom_case.add_nodal_support(node=nodes[0], val=0, dof=1) 48 | freedom_case.add_nodal_support(node=nodes[-1], val=0, dof=0) 49 | freedom_case.add_nodal_support(node=nodes[-1], val=0, dof=1) 50 | 51 | # add loads 52 | load_case = cases.LoadCase() 53 | load_case.add_nodal_load(node=nodes[int(n/2)], val=-1e3, dof=1) 54 | 55 | # add analysis case 56 | analysis_case = cases.AnalysisCase(freedom_case=freedom_case, load_case=load_case) 57 | 58 | # plot problem data 59 | analysis.post.n_subdiv = 5 # reduce number of subdivisions for elements in post 60 | analysis.post.plot_geom(analysis_case=analysis_case) 61 | 62 | # ------------- 63 | # static solver 64 | # ------------- 65 | 66 | settings = SolverSettings() 67 | settings.linear_static.time_info = True 68 | 69 | LinearStatic(analysis=analysis, analysis_cases=[analysis_case], solver_settings=settings).solve() 70 | 71 | # ----------- 72 | # static post 73 | # ----------- 74 | 75 | analysis.post.plot_geom(analysis_case=analysis_case, deformed=True, def_scale=2500) 76 | analysis.post.plot_frame_forces(analysis_case=analysis_case, axial=True) 77 | analysis.post.plot_frame_forces(analysis_case=analysis_case, shear=True) 78 | analysis.post.plot_frame_forces(analysis_case=analysis_case, moment=True) 79 | analysis.post.plot_reactions(analysis_case=analysis_case) 80 | 81 | # --------------- 82 | # buckling solver 83 | # --------------- 84 | 85 | settings.linear_buckling.time_info = True 86 | 87 | LinearBuckling(analysis=analysis, analysis_cases=[analysis_case], solver_settings=settings).solve() 88 | 89 | # ------------- 90 | # buckling post 91 | # ------------- 92 | 93 | for i in range(settings.linear_buckling.num_modes): 94 | analysis.post.plot_buckling_results(analysis_case=analysis_case, buckling_mode=i) 95 | 96 | # ---------------- 97 | # frequency solver 98 | # ---------------- 99 | 100 | settings.natural_frequency.time_info = True 101 | 102 | NaturalFrequency( 103 | analysis=analysis, analysis_cases=[analysis_case], solver_settings=settings).solve() 104 | 105 | # -------------- 106 | # frequency post 107 | # -------------- 108 | 109 | for i in range(settings.natural_frequency.num_modes): 110 | analysis.post.plot_frequency_results(analysis_case=analysis_case, frequency_mode=i) 111 | -------------------------------------------------------------------------------- /feastruct/solvers/naturalfrequency.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | from feastruct.solvers.feasolve import Solver 3 | 4 | 5 | class NaturalFrequency(Solver): 6 | """Class for a natural frequency solver. 7 | 8 | :cvar analysis: Analysis object to solve 9 | :vartype analysis: :class:`~feastruct.fea.fea.FiniteElementAnalysis` 10 | :cvar analysis_cases: List of analysis cases to solve 11 | :vartype analysis_cases: list[:class:`~feastruct.fea.cases.AnalysisCase`] 12 | :cvar solver_settings: Settings to use in the solver 13 | :vartype solver_settings: :class:`~feastruct.solvers.feasolve.SolverSettings` 14 | :cvar int ndof: Number of degrees of freedom in the analysis 15 | """ 16 | 17 | def __init__(self, analysis, analysis_cases, solver_settings=None): 18 | """Inits the NaturalFrequency class. 19 | 20 | :param analysis: Analysis object to solve 21 | :type analysis: :class:`~feastruct.fea.fea.FiniteElementAnalysis` 22 | :param analysis_cases: List of analysis cases to solve 23 | :type analysis_cases: list[:class:`~feastruct.fea.cases.AnalysisCase`] 24 | :param solver_settings: Settings to use in the solver - if not supplied, the default 25 | settings are adopted 26 | :type solver_settings: :class:`~feastruct.solvers.feasolve.SolverSettings` 27 | """ 28 | 29 | super().__init__(analysis, analysis_cases, solver_settings) 30 | 31 | # TODO: check that analysis_case results available 32 | 33 | def solve(self): 34 | """Executes the natural frequency finite element solver and saves the relevant results.""" 35 | 36 | if self.solver_settings.natural_frequency.time_info: 37 | print('\n-Starting the natural frequency solver...') 38 | 39 | # assign the global degree of freedom numbers 40 | if self.solver_settings.linear_static.time_info: 41 | str = '--Assigning the global degree of freedom numbers...' 42 | self.function_timer(str, self.assign_dofs) 43 | else: 44 | self.assign_dofs() 45 | 46 | # loop through each analysis case 47 | for (i, analysis_case) in enumerate(self.analysis_cases): 48 | if self.solver_settings.natural_frequency.time_info: 49 | print('\n--Analysis case {0}:'.format(i)) 50 | 51 | # assemble the global stiffness matrix 52 | if self.solver_settings.natural_frequency.time_info: 53 | str = '---Assembling the global stiffness matrix...' 54 | (K, _) = self.function_timer(str, self.assemble_stiff_matrix) 55 | else: 56 | (K, _) = self.assemble_stiff_matrix() 57 | 58 | # assemble the global mass matrix 59 | if self.solver_settings.natural_frequency.time_info: 60 | str = '---Assembling the global mass matrix...' 61 | M = self.function_timer(str, self.assemble_mass_matrix) 62 | else: 63 | M = self.assemble_mass_matrix() 64 | 65 | # apply the boundary conditions 66 | K_mod = self.remove_constrained_dofs(K=K, analysis_case=analysis_case) 67 | M_mod = self.remove_constrained_dofs(K=M, analysis_case=analysis_case) 68 | 69 | # solve for the eigenvalues 70 | if self.solver_settings.natural_frequency.time_info: 71 | str = '---Solving for eigenvalues and eigenvectors ({0} modes)...'.format( 72 | self.solver_settings.natural_frequency.num_modes) 73 | (w, v) = self.function_timer( 74 | str, self.solve_eigenvalue, K_mod, M_mod, 75 | self.solver_settings.natural_frequency) 76 | else: 77 | (w, v) = self.solve_eigenvalue( 78 | A=K_mod, M=M_mod, eigen_settings=self.solver_settings.natural_frequency) 79 | 80 | # compute natural frequencies in Hz 81 | w = np.sqrt(w) / 2 / np.pi 82 | 83 | self.save_frequency_results(w=w, v=v, analysis_case=analysis_case) 84 | -------------------------------------------------------------------------------- /docs/build/html/_static/js/theme.js: -------------------------------------------------------------------------------- 1 | require=function r(s,a,l){function c(i,n){if(!a[i]){if(!s[i]){var e="function"==typeof require&&require;if(!n&&e)return e(i,!0);if(u)return u(i,!0);var t=new Error("Cannot find module '"+i+"'");throw t.code="MODULE_NOT_FOUND",t}var o=a[i]={exports:{}};s[i][0].call(o.exports,function(n){var e=s[i][1][n];return c(e||n)},o,o.exports,r,s,a,l)}return a[i].exports}for(var u="function"==typeof require&&require,n=0;n"),i("table.docutils.footnote").wrap("
"),i("table.docutils.citation").wrap("
"),i(".wy-menu-vertical ul").not(".simple").siblings("a").each(function(){var e=i(this);expand=i(''),expand.on("click",function(n){return t.toggleCurrent(e),n.stopPropagation(),!1}),e.prepend(expand)})},reset:function(){var n=encodeURI(window.location.hash)||"#";try{var e=$(".wy-menu-vertical"),i=e.find('[href="'+n+'"]');if(0===i.length){var t=$('.document [id="'+n.substring(1)+'"]').closest("div.section");0===(i=e.find('[href="#'+t.attr("id")+'"]')).length&&(i=e.find('[href="#"]'))}0this.docHeight||(this.navBar.scrollTop(i),this.winPosition=n)},onResize:function(){this.winResize=!1,this.winHeight=this.win.height(),this.docHeight=$(document).height()},hashChange:function(){this.linkScroll=!0,this.win.one("hashchange",function(){this.linkScroll=!1})},toggleCurrent:function(n){var e=n.closest("li");e.siblings("li.current").removeClass("current"),e.siblings().find("li.current").removeClass("current"),e.find("> ul li.current").removeClass("current"),e.toggleClass("current")}},"undefined"!=typeof window&&(window.SphinxRtdTheme={Navigation:e.exports.ThemeNav,StickyNav:e.exports.ThemeNav}),function(){for(var r=0,n=["ms","moz","webkit","o"],e=0;e