├── .github └── workflows │ ├── black.yaml │ └── build.yaml ├── .gitignore ├── LICENSE.md ├── README.md ├── examples ├── README.md ├── __init__.py ├── cylinder.py ├── geo │ └── cylinder.geo ├── msh │ ├── cylinder-custom.msh │ ├── cylinder-quad_coarse.msh │ ├── cylinder-quad_refined.msh │ ├── cylinder-tri_coarse.msh │ └── cylinder-tri_refined.msh └── out │ ├── NeoHookean │ ├── custom │ │ └── cylinder-results_Nsteps-10.msh │ ├── quad_coarse │ │ └── cylinder-results_Nsteps-10.msh │ ├── quad_refined │ │ └── cylinder-results_Nsteps-10.msh │ ├── tri_coarse │ │ └── cylinder-results_Nsteps-10.msh │ └── tri_refined │ │ └── cylinder-results_Nsteps-10.msh │ └── StVenant │ ├── custom │ └── cylinder-results_Nsteps-10.msh │ ├── quad_coarse │ └── cylinder-results_Nsteps-10.msh │ ├── quad_refined │ └── cylinder-results_Nsteps-10.msh │ ├── tri_coarse │ └── cylinder-results_Nsteps-10.msh │ └── tri_refined │ └── cylinder-results_Nsteps-10.msh ├── pyproject.toml ├── requirements.txt ├── requirements_dev.txt ├── setup.cfg ├── setup.py ├── src └── hyper │ ├── __init__.py │ ├── elasticity.py │ ├── fem.py │ ├── geometry.py │ ├── gmsh2.py │ ├── mesh.py │ ├── plot.py │ ├── readme.md │ └── tensor.py ├── tests ├── __init__.py ├── geo │ └── compare_residual.geo ├── msh │ ├── meshfile-quad8-ref.msh │ ├── meshfile-quad8.msh │ ├── meshfile-tri8-ref.msh │ ├── meshfile-tri8.msh │ ├── triangle-quad11.msh │ ├── triangle-quad44-ref.msh │ ├── triangle-quad44.msh │ ├── triangle-tri14.msh │ ├── triangle-tri56-ref.msh │ └── triangle-tri56.msh ├── readme.md ├── test_elasticity.py ├── test_fem.py ├── test_geometry.py ├── test_mesh.py ├── test_residual.py ├── test_tangent.py └── test_tensor.py └── tox.ini /.github/workflows/black.yaml: -------------------------------------------------------------------------------- 1 | name: Lint with Black 2 | 3 | on: 4 | push: 5 | paths: 6 | - src/** 7 | - tests/** 8 | branches: 9 | - main 10 | pull_request: 11 | 12 | jobs: 13 | lint: 14 | runs-on: ubuntu-latest 15 | steps: 16 | - uses: actions/checkout@v2 17 | 18 | - uses: psf/black@stable 19 | with: 20 | options: "--check --verbose --exclude docs" 21 | 22 | 23 | -------------------------------------------------------------------------------- /.github/workflows/build.yaml: -------------------------------------------------------------------------------- 1 | # This is a basic workflow to help you get started with Actions 2 | 3 | name: Tests 4 | 5 | # Controls when the workflow will run 6 | on: 7 | push: 8 | paths: 9 | - src/** 10 | - tests/** 11 | branches: [ main ] 12 | pull_request: 13 | branches: [ main ] 14 | workflow_dispatch: 15 | 16 | # A workflow run is made up of one or more jobs that can run sequentially or in parallel 17 | jobs: 18 | # This workflow contains a single job called "build" 19 | build: 20 | # The type of runner that the job will run on 21 | runs-on: ${{ matrix.os }} 22 | strategy: 23 | matrix: 24 | os: [ubuntu-latest, windows-latest] 25 | python-version: ['3.9', '3.10'] 26 | steps: 27 | - name: Checkout sources 28 | uses: actions/checkout@v2 29 | 30 | - name: Set up Python ${{ matrix.python-version }} 31 | uses: actions/setup-python@v2 32 | with: 33 | python-version: ${{ matrix.python-version }} 34 | 35 | - name: Install dependencies 36 | run: | 37 | python -m pip install --upgrade pip 38 | python -m pip install tox tox-gh-actions 39 | 40 | - name: Run with tox 41 | run: tox 42 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Custom 2 | *val.msh 3 | 4 | # Byte-compiled / optimized / DLL files 5 | __pycache__/ 6 | *.py[cod] 7 | *$py.class 8 | 9 | # C extensions 10 | *.so 11 | 12 | # Distribution / packaging 13 | .Python 14 | build/ 15 | develop-eggs/ 16 | dist/ 17 | downloads/ 18 | eggs/ 19 | .eggs/ 20 | lib/ 21 | lib64/ 22 | parts/ 23 | sdist/ 24 | var/ 25 | wheels/ 26 | pip-wheel-metadata/ 27 | share/python-wheels/ 28 | *.egg-info/ 29 | .installed.cfg 30 | *.egg 31 | MANIFEST 32 | 33 | # PyInstaller 34 | # Usually these files are written by a python script from a template 35 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 36 | *.manifest 37 | *.spec 38 | 39 | # Installer logs 40 | pip-log.txt 41 | pip-delete-this-directory.txt 42 | 43 | # Unit test / coverage reports 44 | htmlcov/ 45 | .tox/ 46 | .nox/ 47 | .coverage 48 | .coverage.* 49 | .cache 50 | nosetests.xml 51 | coverage.xml 52 | *.cover 53 | .hypothesis/ 54 | .pytest_cache/ 55 | 56 | # Translations 57 | *.mo 58 | *.pot 59 | 60 | # Django stuff: 61 | *.log 62 | local_settings.py 63 | db.sqlite3 64 | db.sqlite3-journal 65 | 66 | # Flask stuff: 67 | instance/ 68 | .webassets-cache 69 | 70 | # Scrapy stuff: 71 | .scrapy 72 | 73 | # Sphinx documentation 74 | docs/_build/ 75 | 76 | # PyBuilder 77 | target/ 78 | 79 | # Jupyter Notebook 80 | .ipynb_checkpoints 81 | 82 | # IPython 83 | profile_default/ 84 | ipython_config.py 85 | 86 | # pyenv 87 | .python-version 88 | 89 | # pipenv 90 | # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. 91 | # However, in case of collaboration, if having platform-specific dependencies or dependencies 92 | # having no cross-platform support, pipenv may install dependencies that don't work, or not 93 | # install all needed dependencies. 94 | #Pipfile.lock 95 | 96 | # celery beat schedule file 97 | celerybeat-schedule 98 | 99 | # SageMath parsed files 100 | *.sage.py 101 | 102 | # Environments 103 | .env 104 | .venv 105 | env/ 106 | venv/ 107 | ENV/ 108 | env.bak/ 109 | venv.bak/ 110 | 111 | # Spyder project settings 112 | .spyderproject 113 | .spyproject 114 | 115 | # Rope project settings 116 | .ropeproject 117 | 118 | # mkdocs documentation 119 | /site 120 | 121 | # mypy 122 | .mypy_cache/ 123 | .dmypy.json 124 | dmypy.json 125 | 126 | # Pyre type checker 127 | .pyre/ 128 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![Build Status][build-img]][build-url] 2 | 3 | # Hyper-elastic materials 4 | 5 | ### Introduction 6 | 7 | This repository contains the code used in the cours HYPER (Numerical Methods for NonLinear Mechanics) at the [École Centrale de Nantes](https://www.ec-nantes.fr/). 8 | 9 | This cours describes the fundamentals of Hyper-elastic materials and how to implement finite element method with them. 10 | 11 | 12 | ### Subject 13 | 14 | Hyper-elastic materials are used when the hypothesis of small deformations is not valid anymore. 15 | 16 | For exemple, applying pressure in a steel cylinder is different from applying pressure in a rubber pipe, which makes the pipe inflates and reduces its thickness: 17 | 18 | ![Neo Hook model - Rubber](https://raw.githubusercontent.com/carlos-adir/Non-linear-mechanics/docs/img/LinearMechanics.gif) 19 | 20 | The main difference between the approachs are: 21 | 22 | * Linear elastic materials 23 | + Valid for small deformations 24 | + The stiffness matrix is constant 25 | + Linear problem: solves a directly a single linear system 26 | * Hyper-elastic materials 27 | + Valid for small and large deformations 28 | + Needs recalculation of stiffness matrix, to consider the deformed space 29 | + Non-linear problems: Needs to 'walk', solving a linear system for each step 30 | 31 | ![Difference linear / nonlinear](https://ars.els-cdn.com/content/image/3-s2.0-B9780323898225000104-f04-01-9780323898225.jpg) 32 | 33 | 34 | ### How to use 35 | 36 | Python is used to implement the finite element method, along with the libraries: 37 | 38 | * [Numpy](https://numpy.org/doc/): Used for tensor calculs 39 | * [Gmsh](https://gmsh.info/): Used to get the mesh and elements 40 | * [Scipy](https://scipy.org/): Used to get the mesh and elements 41 | 42 | To install them, you can either use [Anaconda](https://www.anaconda.com/) that installs all you need, or you can install them manually: 43 | 44 | ``` 45 | pip install numpy 46 | pip install scipy 47 | pip install gmsh 48 | ``` 49 | 50 | After getting the libraries and downloading your own copy, you can test it with `pytest`: 51 | 52 | ``` 53 | pip install pytest 54 | pytest 55 | ``` 56 | 57 | There are some examples in the folder `examples` explaining how to run 58 | 59 | 60 | 61 | 62 | [build-img]: https://github.com/compmec/hyper/actions/workflows/build.yaml/badge.svg 63 | [build-url]: https://github.com/compmec/hyper/actions/workflows/build.yaml 64 | -------------------------------------------------------------------------------- /examples/README.md: -------------------------------------------------------------------------------- 1 | # Example 2 | 3 | This folder contains examples of how to use the code made. 4 | 5 | 6 | ### Cylinder 7 | 8 | For the moment, there's only one file: **cylinder.py** 9 | 10 | Just run it on your terminal: 11 | 12 | ``` 13 | python cylinder.py 14 | ``` 15 | 16 | The result will depend on the used parameters, which are: 17 | 18 | * material: meaning the stiffness and the used law 19 | + **StVenant: steel** 20 | + NeoHookean: rubber 21 | * mesh: the definition of nodes position and elements (triangles, squares): 22 | + **cylinder-custom.msh** 23 | + cylinder-tri_coarse.msh 24 | + cylinder-tri_refined.msh 25 | + cylinder-quad_coarse.msh 26 | + cylinder-quad_refined.msh 27 | * iteration: tells how fast we want to approach the solution 28 | + nSteps: more steps means solving more linear systems, but increases change of convergence 29 | + rdisp: the charge applied on the center 30 | * solver: tells how we want to solve one step, from a time (t0) to a time (t0 + delta T) 31 | + precision: the zero machine 32 | + tolerance: tell when should we stop solving the linear system 33 | + itermax: the number maximal of iteration to solve the linear system. The computation is stoped if there's no convergence 34 | 35 | 36 | The default is marked in **bold** and you can change it as you want: 37 | 38 | ``` 39 | ============================================ 40 | = = 41 | = 2D plane strain thick cylinder = 42 | = = 43 | ============================================ 44 | ############################ 45 | # MATERIAL # 46 | ############################ 47 | Material: steel 48 | E = 2.10e+07 49 | v = 3.00e-01 50 | model = StVenant 51 | 52 | ############################ 53 | # ITERATION PARAMETERS # 54 | ############################ 55 | Number of steps = 10 56 | delta T = 0.1 57 | radial displacement = 1.00e-04 58 | 59 | ############################ 60 | # SOLVER PARAMETERS # 61 | ############################ 62 | PRECISION = 1.00e-15 63 | TOLERANCE = 1.00e-06 64 | ITERMAX = 10.00 65 | 66 | ############################ 67 | # FILES AND FOLDERS # 68 | ############################ 69 | mesh = cylinder-custom.msh 70 | geom = cylinder.geo 71 | Geometry cylinder: 72 | Internal radius Ri = 2.00e-02 m 73 | External radius Re = 6.00e-02 m 74 | Mesh read: 75 | File: msh/cylinder-custom.msh 76 | Nodes: 8 77 | Elements: 8 78 | 79 | ############################ 80 | # PRE PROCESSING # 81 | ############################ 82 | Mesh information: 83 | Total nodes: 8 84 | Total elements: 8 85 | Dimention: 2 86 | Number of nodes: 87 | Left: 2 88 | Center: 3 89 | Bottom: 2 90 | Degrees of freedom: 91 | Total: 16 92 | BC Left: 2 93 | BC Center: 6 94 | BC Bottom: 2 95 | BC Total: 8 96 | Free: 8 97 | 98 | ############################ 99 | # SIMULATION # 100 | ############################ 101 | --> Step [1/10] 102 | time = 0.10/1.00 103 | disp = 1.00e-05 104 | *** Iteration 00: residual norm =2.465e+02 *** 105 | *** Iteration 01: residual norm =6.998e-02 *** 106 | *** Iteration 02: residual norm =7.345e-09 *** 107 | COMPLETE: norm < test 108 | norm = 7.34500e-09 109 | test = 2.46498e-04 110 | ... 111 | --> Step [10/10] 112 | time = 1.00/1.00 113 | disp = 1.00e-04 114 | *** Iteration 00: residual norm =2.572e+02 *** 115 | *** Iteration 01: residual norm =5.599e+00 *** 116 | *** Iteration 02: residual norm =4.787e-05 *** 117 | COMPLETE: norm < test 118 | norm = 4.78701e-05 119 | test = 2.57201e-04 120 | ``` 121 | 122 | 123 | **PS:** The geo folder contains the initial and vectorized geometry. It's used to make the `.msh` files, but in the simulation it has no much importance. 124 | It's used only to get the value of the internal radius, to then get the points near the inner center to apply the displacement. 125 | -------------------------------------------------------------------------------- /examples/__init__.py: -------------------------------------------------------------------------------- 1 | import sys 2 | 3 | sys.path.append("./src") 4 | -------------------------------------------------------------------------------- /examples/geo/cylinder.geo: -------------------------------------------------------------------------------- 1 | r1 = 0.02; 2 | r2 = 0.06; 3 | lcr = 0.002; 4 | nbElems_1 = r1/lcr+1; 5 | nbElems_2 = r2/lcr+1; 6 | nbElems_lateral = (r2-r1)/lcr+1; 7 | // Inside 8 | Point(1) = {0, 0, 0, lcr}; 9 | Point(2) = {0, r1, 0, lcr}; 10 | Point(3) = {r1, 0, 0, lcr}; 11 | Circle(1) = {2,1,3}; 12 | /* Transfinite Curve {1} = nbElems_1 Using Progression 1; */ 13 | 14 | // Outside 15 | Point(4) = {0, r2, 0, lcr}; 16 | Point(5) = {r2, 0, 0, lcr}; 17 | Circle(2) = {5,1,4}; 18 | 19 | // Lateral 20 | Line(3) = {3, 5}; 21 | Line(4) = {4,2}; 22 | 23 | /* Transfinite Curve {2} = nbElems_2 Using Progression 1; */ 24 | Transfinite Curve {3} = nbElems_lateral Using Progression 1; 25 | Transfinite Curve {4} = nbElems_lateral Using Progression 1; 26 | Line Loop(5) = {4, 1, 3, 2}; 27 | 28 | Plane Surface(1) = {5}; 29 | 30 | // Physical lines 31 | Physical Line("bord_int") = {1}; 32 | Physical Line("bord_ext") = {2}; 33 | Physical Line("bord_inf") = {3}; 34 | Physical Line("bord_gauche") = {4}; 35 | Physical Surface("domaine") = {1}; 36 | 37 | // Mesh 38 | Mesh 2; 39 | //+ 40 | -------------------------------------------------------------------------------- /examples/msh/cylinder-custom.msh: -------------------------------------------------------------------------------- 1 | $MeshFormat 2 | 2.2 0 8 3 | $EndMeshFormat 4 | $Nodes 5 | 8 6 | 2 0.02 0 0 7 | 3 0.06 0 0 8 | 4 0 0.06 0 9 | 5 0 0.02 0 10 | 6 0.04242640677399726 0.04242640696838844 0 11 | 7 0.01414213565643166 0.01414213559103024 0 12 | 8 0.0298980551378275 0.01755287322798955 0 13 | 9 0.01729331951365129 0.03082428315748164 0 14 | $EndNodes 15 | $Elements 16 | 19 17 | 1 15 2 0 1 1 18 | 2 15 2 0 2 2 19 | 3 15 2 0 3 3 20 | 4 15 2 0 4 4 21 | 5 15 2 0 5 5 22 | 6 1 2 0 1 2 3 23 | 7 1 2 0 2 3 6 24 | 8 1 2 0 2 6 4 25 | 9 1 2 0 3 4 5 26 | 10 1 2 0 4 5 7 27 | 11 1 2 0 4 7 2 28 | 12 2 2 0 1 3 6 8 29 | 13 2 2 0 1 6 4 9 30 | 14 2 2 0 1 7 8 9 31 | 15 2 2 0 1 8 6 9 32 | 16 2 2 0 1 7 2 8 33 | 17 2 2 0 1 5 7 9 34 | 18 2 2 0 1 2 3 8 35 | 19 2 2 0 1 4 5 9 36 | $EndElements 37 | -------------------------------------------------------------------------------- /examples/msh/cylinder-quad_coarse.msh: -------------------------------------------------------------------------------- 1 | $MeshFormat 2 | 2.2 0 8 3 | $EndMeshFormat 4 | $PhysicalNames 5 | 5 6 | 1 1 "bord_int" 7 | 1 2 "bord_ext" 8 | 1 3 "bord_inf" 9 | 1 4 "bord_gauche" 10 | 2 5 "domaine" 11 | $EndPhysicalNames 12 | $Nodes 13 | 228 14 | 1 0 0.02 0 15 | 2 0.02 0 0 16 | 3 0.003901806449627635 0.01961570560621372 0 17 | 4 0.007653668668350959 0.01847759064150689 0 18 | 5 0.01111140468888053 0.0166293922270155 0 19 | 6 0.01414213565643167 0.01414213559103023 0 20 | 7 0.01662939226487506 0.01111140463221971 0 21 | 8 0.01847759065988117 0.00765366862399152 0 22 | 9 0.01961570561047773 0.003901806428190969 0 23 | 10 0 0.06 0 24 | 11 0.06 0 0 25 | 12 0.05987153539371622 0.003924187762962777 0 26 | 13 0.05948669168006057 0.00783157155119025 0 27 | 14 0.0588471168182586 0.0117054193508061 0 28 | 15 0.05795554956667294 0.01552914274597653 0 29 | 16 0.0568158077517052 0.01928636797121935 0 30 | 17 0.05543277192430627 0.02296100600557045 0 31 | 18 0.05381236445636934 0.02653732148531343 0 32 | 19 0.05196152418345558 0.03000000007553601 0 33 | 20 0.04988817668023694 0.03333421406785322 0 34 | 21 0.04760120034468259 0.03652568583538699 0 35 | 22 0.04511038836358067 0.03956074900310819 0 36 | 23 0.04242640677341155 0.04242640696897415 0 37 | 24 0.03956074881198433 0.0451103885311918 0 38 | 25 0.03652568565209998 0.04760120048532366 0 39 | 26 0.0333342138957829 0.04988817679521065 0 40 | 27 0.02999999991630592 0.05196152427538712 0 41 | 28 0.02653732133585785 0.05381236453007267 0 42 | 29 0.0229610058734211 0.05543277197904432 0 43 | 30 0.01928636785875561 0.05681580778988149 0 44 | 31 0.01552914265787349 0.05795554959028008 0 45 | 32 0.01170541928367925 0.05884711683161096 0 46 | 33 0.007831571508402873 0.05948669168569364 0 47 | 34 0.003924187742057789 0.0598715353950864 0 48 | 35 0.02444444444443728 0 0 49 | 36 0.02888888888886576 0 0 50 | 37 0.03333333333329943 0 0 51 | 38 0.03777777777772762 0 0 52 | 39 0.04222222222217221 0 0 53 | 40 0.04666666666662823 0 0 54 | 41 0.05111111111108549 0 0 55 | 42 0.05555555555554817 0 0 56 | 43 0 0.05555555555556654 0 57 | 44 0 0.05111111111113173 0 58 | 45 0 0.04666666666670098 0 59 | 46 0 0.04222222222227174 0 60 | 47 0 0.03777777777782834 0 61 | 48 0 0.03333333333337126 0 62 | 49 0 0.02888888888891418 0 63 | 50 0 0.02444444444445167 0 64 | 51 0.02533397223088884 0.03078937170857331 0 65 | 52 0.03788047304809539 0.01802576526149828 0 66 | 53 0.01594269526702575 0.0423587253673345 0 67 | 54 0.01294917130422262 0.02992659854279037 0 68 | 55 0.03726037814805204 0.03057880221360906 0 69 | 56 0.02590941421820724 0.01882031485369049 0 70 | 57 0.04743653542490554 0.01147456188090451 0 71 | 58 0.02700894656651174 0.04107904370656872 0 72 | 59 0.03136880458357965 0.01009945434229929 0 73 | 60 0.009597496440225207 0.0492403228448695 0 74 | 61 0.0439195900214837 0.02457964867046046 0 75 | 62 0.01787003942235711 0.02296099399483827 0 76 | 63 0.03460311441347019 0.03846807711700456 0 77 | 64 0.008655510630856676 0.03761153696798753 0 78 | 65 0.03077497153030524 0.02453377907990194 0 79 | 66 0.02157095158213384 0.04800818384695743 0 80 | 67 0.03949786768514245 0.008020704213208427 0 81 | 68 0.01800891422146875 0.03504019098533596 0 82 | 69 0.04916018080275406 0.01892864490897905 0 83 | 70 0.02380053303508244 0.01163688974903064 0 84 | 71 0.007500047759169108 0.02551927308735921 0 85 | 72 0.05254697916768546 0.006818833186245973 0 86 | 73 0.04379139594795982 0.03107579380385874 0 87 | 74 0.01591530157467762 0.05110339264894986 0 88 | 75 0.03135148408985141 0.03291956106201323 0 89 | 76 0.01991950893294855 0.01655144742025048 0 90 | 77 0.02374494563306486 0.02475612731447064 0 91 | 78 0.006432085554829578 0.03168673311333401 0 92 | 79 0.01899251085681777 0.02881421951218831 0 93 | 80 0.03740231497630152 0.02428391846003589 0 94 | 81 0.0313295998759139 0.01642555058483119 0 95 | 82 0.03983898857958348 0.03592348725088829 0 96 | 83 0.006124979780461069 0.04395661037728275 0 97 | 84 0.02670147125459126 0.005895783242337109 0 98 | 85 0.03226970006450004 0.04385704593808514 0 99 | 86 0.04358690130904359 0.0161075166839804 0 100 | 87 0.02454424097478421 0.03652653973458223 0 101 | 88 0.05240444800559607 0.01403552024379759 0 102 | 89 0.02720127229099659 0.04709814604085963 0 103 | 90 0.006062161844239425 0.05476907012885479 0 104 | 91 0.0457461875038461 0.005930756278690451 0 105 | 92 0.01222377066834478 0.02210042999694562 0 106 | 93 0.02139885818128789 0.04126479856212611 0 107 | 94 0.03628025751668627 0.01270617860911507 0 108 | 95 0.01349490412810716 0.03523011059212761 0 109 | 96 0.03417432878347954 0.00572300008289351 0 110 | 97 0.04956271033213165 0.02370077049913071 0 111 | 98 0.02954208990449772 0.03742612653002921 0 112 | 99 0.01152848010466734 0.04468005261041615 0 113 | 100 0.01242007625683288 0.05369423118946521 0 114 | 101 0.03425382835464365 0.02066735915515855 0 115 | 102 0.04705068662273046 0.02897715405130784 0 116 | 103 0.01513761166917756 0.01834356248597466 0 117 | 104 0.04069657804587622 0.02775483657651695 0 118 | 105 0.04259047641737829 0.02045837957050412 0 119 | 106 0.004754754073718524 0.04836548679201316 0 120 | 107 0.01465705113175252 0.02549573062484387 0 121 | 108 0.03799528471915845 0.04116696560751339 0 122 | 109 0.02183417828698766 0.02066694178279857 0 123 | 110 0.01719820916685033 0.04688392833178744 0 124 | 111 0.04230424807923476 0.01190446697906087 0 125 | 112 0.02000335070176541 0.05223663830076181 0 126 | 113 0.0292553375372869 0.02955347038202058 0 127 | 114 0.02725265154148677 0.01462288663421405 0 128 | 115 0.004312318880868486 0.03588991264192926 0 129 | 116 0.02755503588999747 0.02278292207550601 0 130 | 117 0.03562788220561675 0.03441289839875949 0 131 | 118 0.03334909612994345 0.02867267634497593 0 132 | 119 0.02278096395378935 0.00778676138582495 0 133 | 120 0.05458271074403988 0.01058635756573257 0 134 | 121 0.01255098305782788 0.0399629782638186 0 135 | 122 0.04876017553487898 0.003738322336090562 0 136 | 123 0.004257416161115639 0.02782582096289703 0 137 | 124 0.02090787251195933 0.03226063516431703 0 138 | 125 0.02386027023230251 0.04415444323496167 0 139 | 126 0.02037797157274726 0.01294166338602833 0 140 | 127 0.02490678587962705 0.04999009379725747 0 141 | 128 0.01646565583441229 0.03177450909643224 0 142 | 129 0.04045665103646628 0.003313989992282543 0 143 | 130 0.02724207832247794 0.03411436427627227 0 144 | 131 0.004456674590345423 0.04049442922488523 0 145 | 132 0.04356104886064702 0.03541744413837969 0 146 | 133 0.05346626301274526 0.01697855605101289 0 147 | 134 0.02992442336844378 0.003560707026812285 0 148 | 135 0.05572901864928476 0.003873182574059657 0 149 | 136 0.01637273477352253 0.03833894390263509 0 150 | 137 0.003993364834128882 0.02368046245511765 0 151 | 138 0.04641120432754249 0.02186111837072526 0 152 | 139 0.03573142634969954 0.04424380335964091 0 153 | 140 0.01012689511025793 0.03315574919858011 0 154 | 141 0.02363764647526434 0.01566950395478266 0 155 | 142 0.01347291761057693 0.04802388307929832 0 156 | 143 0.03965297785594993 0.01462227850585258 0 157 | 144 0.02971470919898061 0.02012349661740847 0 158 | 145 0.04743657957227151 0.01528311647604976 0 159 | 146 0.009060153708437008 0.02892408782437405 0 160 | 147 0.02268913185883729 0.02805706472615795 0 161 | 148 0.05086371348720362 0.01061164299289936 0 162 | 149 0.03042464201769855 0.04761695788768595 0 163 | 150 0.02737091348308399 0.009996910126898491 0 164 | 151 0.02337024288651288 0.003705858708732151 0 165 | 152 0.04012937863128922 0.03252721039700204 0 166 | 153 0.02036136615003793 0.02530497506287108 0 167 | 154 0.05237767928752936 0.02145266020959079 0 168 | 155 0.04836266889204924 0.007954129345368358 0 169 | 156 0.01970995419566411 0.0438744821419706 0 170 | 157 0.02697553172866723 0.0263290307333466 0 171 | 158 0.009248878353728229 0.05608842383186094 0 172 | 159 0.008144982428797271 0.02205861725686719 0 173 | 160 0.008964636004575817 0.04187147885887385 0 174 | 161 0.01605042939237971 0.05469929383729945 0 175 | 162 0.03528463863910942 0.009702807396203141 0 176 | 163 0.03134550356711861 0.04034695735790729 0 177 | 164 0.04078107826862824 0.02390480510635973 0 178 | 165 0.01087709150344224 0.02560118459112589 0 179 | 166 0.04126379117481569 0.03883386492538363 0 180 | 167 0.04684713807666799 0.03265313310541659 0 181 | 168 0.02100747541973918 0.03745224467985755 0 182 | 169 0.01724132401923602 0.01461804270310068 0 183 | 170 0.02868505578985467 0.04402543236101139 0 184 | 171 0.0183864204920929 0.01966414811409439 0 185 | 172 0.04978178901787478 0.02755254318413311 0 186 | 173 0.0443415873800266 0.02780398171287806 0 187 | 174 0.00300036411936274 0.03152493778808915 0 188 | 175 0.03519379197879593 0.01596152125599021 0 189 | 176 0.05616782003640663 0.007457187964013789 0 190 | 177 0.03322786855389473 0.01293711917829556 0 191 | 178 0.003311684143652516 0.05648646708257402 0 192 | 179 0.03240264341286196 0.03597144795265261 0 193 | 180 0.03652842782257246 0.02741325615194745 0 194 | 181 0.002792339397443887 0.04444444444448634 0 195 | 182 0.03874590610101109 0.02113068646265816 0 196 | 183 0.008642126001643879 0.05253020829677481 0 197 | 184 0.02408049464178141 0.03976309633419008 0 198 | 185 0.03420443116202167 0.02411590044955755 0 199 | 186 0.05260042561718953 0.003014085728240591 0 200 | 187 0.04433187028448593 0.009293185943547227 0 201 | 188 0.008400264980319296 0.04614296584293234 0 202 | 189 0.05551305966627738 0.01354449879686769 0 203 | 190 0.03746618996099065 0.03784544404241265 0 204 | 191 0.003567602395081671 0.05237993670711828 0 205 | 192 0.02476089350706431 0.02175657650661643 0 206 | 193 0.02990798829463565 0.007055170964248137 0 207 | 194 0.0336571335959562 0.04664143689318926 0 208 | 195 0.01605162724745513 0.02856167589263598 0 209 | 196 0.0266658941685702 0.002632469795576309 0 210 | 197 0.007351707389813244 0.0347304665816745 0 211 | 198 0.03439721014336591 0.03164598450483943 0 212 | 199 0.04437295499808716 0.002866301658375006 0 213 | 200 0.03888865823997228 0.01138397359516541 0 214 | 201 0.0105620554435464 0.01958968683081177 0 215 | 202 0.01453557553728009 0.0454866473472091 0 216 | 203 0.02778521870936802 0.0500800113274317 0 217 | 204 0.01875645669123103 0.04945263712338734 0 218 | 205 0.0120095835767913 0.05091840761187153 0 219 | 206 0.02666317647606293 0.03810150808704421 0 220 | 207 0.04086413328427123 0.01779385958393292 0 221 | 208 0.03704799172322306 0.003411538857676896 0 222 | 209 0.02400424704397358 0.03348397242964313 0 223 | 210 0.03438900582278936 0.04161656987603027 0 224 | 211 0.04583706848579799 0.01852775520204772 0 225 | 212 0.01537733696271419 0.02163513809509801 0 226 | 213 0.01859364014390658 0.04061815300974234 0 227 | 214 0.04288110630160559 0.005884987617220731 0 228 | 215 0.04500614153350424 0.01334291681561987 0 229 | 216 0.03001208244270599 0.0127727035405045 0 230 | 217 0.02310576193445977 0.05232273949826954 0 231 | 218 0.05037263861952591 0.01579164872772883 0 232 | 219 0.0175865189616841 0.0262275190174755 0 233 | 220 0.0491903200037512 0.0305885067357131 0 234 | 221 0.01314833730437326 0.05639014350445824 0 235 | 222 0.02051365981752827 0.00982670388160054 0 236 | 223 0.04965215718479887 0.0133257704076316 0 237 | 224 0.006075696718416166 0.05734043762481396 0 238 | 225 0.04697612142113421 0.02563107929707054 0 239 | 226 0.024384819996265 0.04731271673000905 0 240 | 227 0.02855159370864713 0.01749806217253605 0 241 | 228 0.05778902739963728 0.001949342584255608 0 242 | $EndNodes 243 | $Elements 244 | 253 245 | 1 1 2 1 1 1 3 246 | 2 1 2 1 1 3 4 247 | 3 1 2 1 1 4 5 248 | 4 1 2 1 1 5 6 249 | 5 1 2 1 1 6 7 250 | 6 1 2 1 1 7 8 251 | 7 1 2 1 1 8 9 252 | 8 1 2 1 1 9 2 253 | 9 1 2 2 2 11 12 254 | 10 1 2 2 2 12 13 255 | 11 1 2 2 2 13 14 256 | 12 1 2 2 2 14 15 257 | 13 1 2 2 2 15 16 258 | 14 1 2 2 2 16 17 259 | 15 1 2 2 2 17 18 260 | 16 1 2 2 2 18 19 261 | 17 1 2 2 2 19 20 262 | 18 1 2 2 2 20 21 263 | 19 1 2 2 2 21 22 264 | 20 1 2 2 2 22 23 265 | 21 1 2 2 2 23 24 266 | 22 1 2 2 2 24 25 267 | 23 1 2 2 2 25 26 268 | 24 1 2 2 2 26 27 269 | 25 1 2 2 2 27 28 270 | 26 1 2 2 2 28 29 271 | 27 1 2 2 2 29 30 272 | 28 1 2 2 2 30 31 273 | 29 1 2 2 2 31 32 274 | 30 1 2 2 2 32 33 275 | 31 1 2 2 2 33 34 276 | 32 1 2 2 2 34 10 277 | 33 1 2 3 3 2 35 278 | 34 1 2 3 3 35 36 279 | 35 1 2 3 3 36 37 280 | 36 1 2 3 3 37 38 281 | 37 1 2 3 3 38 39 282 | 38 1 2 3 3 39 40 283 | 39 1 2 3 3 40 41 284 | 40 1 2 3 3 41 42 285 | 41 1 2 3 3 42 11 286 | 42 1 2 4 4 10 43 287 | 43 1 2 4 4 43 44 288 | 44 1 2 4 4 44 45 289 | 45 1 2 4 4 45 46 290 | 46 1 2 4 4 46 47 291 | 47 1 2 4 4 47 48 292 | 48 1 2 4 4 48 49 293 | 49 1 2 4 4 49 50 294 | 50 1 2 4 4 50 1 295 | 51 2 2 5 1 228 135 42 296 | 52 2 2 5 1 42 11 228 297 | 53 3 2 5 1 106 183 90 191 298 | 54 3 2 5 1 209 168 68 124 299 | 55 3 2 5 1 189 15 16 133 300 | 56 3 2 5 1 51 113 75 130 301 | 57 3 2 5 1 97 154 17 18 302 | 58 3 2 5 1 137 3 4 159 303 | 59 3 2 5 1 193 96 162 59 304 | 60 3 2 5 1 128 68 136 95 305 | 61 3 2 5 1 208 67 162 96 306 | 62 3 2 5 1 121 53 202 99 307 | 63 3 2 5 1 169 76 171 103 308 | 64 3 2 5 1 3 137 50 1 309 | 65 3 2 5 1 64 160 83 131 310 | 66 3 2 5 1 128 95 140 54 311 | 67 3 2 5 1 79 124 68 128 312 | 68 3 2 5 1 9 2 35 151 313 | 69 3 2 5 1 17 154 133 16 314 | 70 3 2 5 1 175 52 182 101 315 | 71 3 2 5 1 161 100 205 74 316 | 72 3 2 5 1 137 123 49 50 317 | 73 3 2 5 1 138 69 154 97 318 | 74 3 2 5 1 5 6 169 103 319 | 75 3 2 5 1 152 82 190 117 320 | 76 3 2 5 1 163 58 206 98 321 | 77 3 2 5 1 147 157 113 51 322 | 78 3 2 5 1 130 75 179 98 323 | 79 3 2 5 1 13 176 135 12 324 | 80 3 2 5 1 13 14 120 176 325 | 81 3 2 5 1 113 118 198 75 326 | 82 3 2 5 1 45 106 191 44 327 | 83 3 2 5 1 142 60 188 99 328 | 84 3 2 5 1 144 101 185 65 329 | 85 3 2 5 1 70 150 216 114 330 | 86 3 2 5 1 8 9 151 119 331 | 87 3 2 5 1 182 80 185 101 332 | 88 3 2 5 1 175 101 144 81 333 | 89 3 2 5 1 201 103 212 92 334 | 90 3 2 5 1 26 27 203 149 335 | 91 3 2 5 1 170 89 226 125 336 | 92 3 2 5 1 47 48 174 115 337 | 93 3 2 5 1 152 55 180 104 338 | 94 3 2 5 1 167 73 173 102 339 | 95 3 2 5 1 118 113 157 65 340 | 96 3 2 5 1 183 106 188 60 341 | 97 3 2 5 1 144 65 157 116 342 | 98 3 2 5 1 34 10 43 178 343 | 99 3 2 5 1 37 96 193 134 344 | 100 3 2 5 1 58 163 85 170 345 | 101 3 2 5 1 170 125 184 58 346 | 102 3 2 5 1 178 43 44 191 347 | 103 3 2 5 1 188 106 181 83 348 | 104 3 2 5 1 138 61 164 105 349 | 105 3 2 5 1 64 95 136 121 350 | 106 3 2 5 1 126 70 114 141 351 | 107 3 2 5 1 159 71 123 137 352 | 108 3 2 5 1 52 175 94 143 353 | 109 3 2 5 1 211 105 207 86 354 | 110 3 2 5 1 68 168 213 136 355 | 111 3 2 5 1 24 108 166 23 356 | 112 3 2 5 1 65 185 180 118 357 | 113 3 2 5 1 97 225 61 138 358 | 114 3 2 5 1 115 131 46 47 359 | 115 3 2 5 1 40 122 91 199 360 | 116 3 2 5 1 152 104 173 73 361 | 117 3 2 5 1 152 132 166 82 362 | 118 3 2 5 1 153 109 192 77 363 | 119 3 2 5 1 95 64 197 140 364 | 120 3 2 5 1 164 61 173 104 365 | 121 3 2 5 1 165 54 140 146 366 | 122 3 2 5 1 212 107 165 92 367 | 123 3 2 5 1 99 188 83 160 368 | 124 3 2 5 1 212 62 219 107 369 | 125 3 2 5 1 165 107 195 54 370 | 126 3 2 5 1 98 179 63 163 371 | 127 3 2 5 1 150 70 222 119 372 | 128 3 2 5 1 141 109 171 76 373 | 129 3 2 5 1 156 66 204 110 374 | 130 3 2 5 1 153 62 171 109 375 | 131 3 2 5 1 30 112 217 29 376 | 132 3 2 5 1 108 190 82 166 377 | 133 3 2 5 1 210 63 190 108 378 | 134 3 2 5 1 141 56 192 109 379 | 135 3 2 5 1 142 110 204 74 380 | 136 3 2 5 1 141 114 227 56 381 | 137 3 2 5 1 67 200 94 162 382 | 138 3 2 5 1 156 110 202 53 383 | 139 3 2 5 1 92 165 71 159 384 | 140 3 2 5 1 174 78 197 115 385 | 141 3 2 5 1 131 115 197 64 386 | 142 3 2 5 1 70 126 7 222 387 | 143 3 2 5 1 99 160 64 121 388 | 144 3 2 5 1 161 74 204 112 389 | 145 3 2 5 1 217 112 204 66 390 | 146 3 2 5 1 187 111 200 67 391 | 147 3 2 5 1 96 37 38 208 392 | 148 3 2 5 1 216 81 227 114 393 | 149 3 2 5 1 87 130 98 206 394 | 150 3 2 5 1 123 71 165 146 395 | 151 3 2 5 1 94 177 59 162 396 | 152 3 2 5 1 184 125 156 93 397 | 153 3 2 5 1 41 42 135 186 398 | 154 3 2 5 1 83 181 46 131 399 | 155 3 2 5 1 60 205 100 183 400 | 156 3 2 5 1 7 8 119 222 401 | 157 3 2 5 1 190 63 179 117 402 | 158 3 2 5 1 157 147 153 77 403 | 159 3 2 5 1 127 203 27 28 404 | 160 3 2 5 1 144 116 192 56 405 | 161 3 2 5 1 124 79 153 147 406 | 162 3 2 5 1 157 77 192 116 407 | 163 3 2 5 1 148 72 176 120 408 | 164 3 2 5 1 112 30 31 161 409 | 165 3 2 5 1 152 117 198 55 410 | 166 3 2 5 1 180 55 198 118 411 | 167 3 2 5 1 155 122 186 72 412 | 168 3 2 5 1 120 14 15 189 413 | 169 3 2 5 1 24 139 210 108 414 | 170 3 2 5 1 179 75 198 117 415 | 171 3 2 5 1 141 76 169 126 416 | 172 3 2 5 1 22 132 167 21 417 | 173 3 2 5 1 148 120 189 88 418 | 174 3 2 5 1 53 213 93 156 419 | 175 3 2 5 1 146 78 174 123 420 | 176 3 2 5 1 132 22 23 166 421 | 177 3 2 5 1 72 148 57 155 422 | 178 3 2 5 1 37 134 196 36 423 | 179 3 2 5 1 203 89 170 149 424 | 180 3 2 5 1 152 73 167 132 425 | 181 3 2 5 1 87 209 51 130 426 | 182 3 2 5 1 126 169 6 7 427 | 183 3 2 5 1 86 111 187 215 428 | 184 3 2 5 1 127 28 29 217 429 | 185 3 2 5 1 123 174 48 49 430 | 186 3 2 5 1 97 18 19 172 431 | 187 3 2 5 1 103 171 62 212 432 | 188 3 2 5 1 176 72 186 135 433 | 189 3 2 5 1 40 41 186 122 434 | 190 3 2 5 1 111 86 207 143 435 | 191 3 2 5 1 129 199 91 214 436 | 192 3 2 5 1 106 45 46 181 437 | 193 3 2 5 1 147 51 209 124 438 | 194 3 2 5 1 104 180 185 80 439 | 195 3 2 5 1 208 129 214 67 440 | 196 3 2 5 1 196 134 193 84 441 | 197 3 2 5 1 54 195 79 128 442 | 198 3 2 5 1 217 66 226 127 443 | 199 3 2 5 1 226 89 203 127 444 | 200 3 2 5 1 100 161 31 221 445 | 201 3 2 5 1 156 125 226 66 446 | 202 3 2 5 1 103 201 4 5 447 | 203 3 2 5 1 36 196 151 35 448 | 204 3 2 5 1 207 105 164 182 449 | 205 3 2 5 1 129 39 40 199 450 | 206 3 2 5 1 189 133 218 88 451 | 207 3 2 5 1 24 25 194 139 452 | 208 3 2 5 1 154 69 218 133 453 | 209 3 2 5 1 25 26 149 194 454 | 210 3 2 5 1 39 129 208 38 455 | 211 3 2 5 1 215 187 155 57 456 | 212 3 2 5 1 194 85 210 139 457 | 213 3 2 5 1 104 80 182 164 458 | 214 3 2 5 1 102 173 61 225 459 | 215 3 2 5 1 209 87 184 168 460 | 216 3 2 5 1 20 220 172 19 461 | 217 3 2 5 1 121 136 213 53 462 | 218 3 2 5 1 158 221 31 32 463 | 219 3 2 5 1 122 155 187 91 464 | 220 3 2 5 1 167 102 172 220 465 | 221 3 2 5 1 182 52 143 207 466 | 222 3 2 5 1 213 168 184 93 467 | 223 3 2 5 1 56 227 81 144 468 | 224 3 2 5 1 105 211 69 138 469 | 225 3 2 5 1 21 167 220 20 470 | 226 3 2 5 1 135 228 11 12 471 | 227 3 2 5 1 146 140 197 78 472 | 228 3 2 5 1 60 142 74 205 473 | 229 3 2 5 1 110 142 99 202 474 | 230 3 2 5 1 111 143 94 200 475 | 231 3 2 5 1 102 225 97 172 476 | 232 3 2 5 1 67 214 91 187 477 | 233 3 2 5 1 119 151 196 84 478 | 234 3 2 5 1 221 158 183 100 479 | 235 3 2 5 1 81 177 94 175 480 | 236 3 2 5 1 119 84 193 150 481 | 237 3 2 5 1 170 85 194 149 482 | 238 3 2 5 1 216 150 193 59 483 | 239 3 2 5 1 211 145 218 69 484 | 240 3 2 5 1 211 86 215 145 485 | 241 3 2 5 1 215 57 223 145 486 | 242 3 2 5 1 4 201 92 159 487 | 243 3 2 5 1 33 34 178 224 488 | 244 3 2 5 1 88 223 57 148 489 | 245 3 2 5 1 32 33 224 158 490 | 246 3 2 5 1 62 153 79 219 491 | 247 3 2 5 1 183 158 224 90 492 | 248 3 2 5 1 85 163 63 210 493 | 249 3 2 5 1 58 184 87 206 494 | 250 3 2 5 1 191 90 224 178 495 | 251 3 2 5 1 81 216 59 177 496 | 252 3 2 5 1 79 195 107 219 497 | 253 3 2 5 1 145 223 88 218 498 | $EndElements 499 | -------------------------------------------------------------------------------- /pyproject.toml: -------------------------------------------------------------------------------- 1 | [tool.poetry] 2 | name = "hyper" 3 | version = "0.1.0" 4 | description = "Hyperelastic mechanics" 5 | authors = ["Carlos Adir "] 6 | readme = "README.md" 7 | packages = [{ include = "hyper", from = "src" }] 8 | 9 | [tool.poetry.dependencies] 10 | numpy = "^1.0.0" 11 | matplotlib = "^3.4.0" 12 | python = "^3.7" 13 | 14 | [tool.poetry.dev-dependencies] 15 | pytest = "^5.2" 16 | black = "^23.0.0" 17 | isort = "^5.12.0" 18 | flake8 = "^5.0.0" 19 | pylint = "^3.0.0" 20 | pre-commit = "^3.0.0" 21 | mypy = "^1.0.0" 22 | 23 | [tool.poetry.group.dev.dependencies] 24 | pre-commit = "^3.3.3" 25 | scriv = {extras = ["toml"], version = "^1.3.1"} 26 | 27 | [build-system] 28 | requires = ["poetry-core"] 29 | build-backend = "poetry.core.masonry.api" 30 | 31 | [tool.scriv] 32 | version = "literal: src/hyper/__init__.py: __version__" 33 | 34 | [tool.black] 35 | line-length = 79 36 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | tox==3.24.4 2 | numpy==1.21.2 -------------------------------------------------------------------------------- /requirements_dev.txt: -------------------------------------------------------------------------------- 1 | tox==3.24.4 2 | pytest==6.2.5 -------------------------------------------------------------------------------- /setup.cfg: -------------------------------------------------------------------------------- 1 | [metadata] 2 | name = hyper 3 | description = Hyperelastic mechanics 4 | author = Carlos Leite 5 | license = MIT 6 | license_file = LICENSE.md 7 | platforms = unix, linux, osx, win32 8 | classifiers = 9 | Programming Language :: Python :: 3 10 | Programming Language :: Python :: 3 :: Only 11 | Programming Language :: Python :: 3.6 12 | Programming Language :: Python :: 3.7 13 | Programming Language :: Python :: 3.8 14 | Programming Language :: Python :: 3.9 15 | 16 | [options] 17 | packages = 18 | hyper 19 | install_requires = 20 | numpy>=1 21 | python_requires = >=3.6 22 | zip_safe = no 23 | 24 | [options.extras_require] 25 | testing = 26 | pytest>=6.0 27 | tox>=3.24 -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | from setuptools import setup 2 | 3 | 4 | if __name__ == "__main__": 5 | setup() 6 | -------------------------------------------------------------------------------- /src/hyper/__init__.py: -------------------------------------------------------------------------------- 1 | import sys 2 | 3 | sys.path.append("./src") 4 | 5 | __version__ = "0.1.0" 6 | 7 | if __name__ == "__main__": 8 | pass 9 | -------------------------------------------------------------------------------- /src/hyper/elasticity.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | from abc import ABC, abstractmethod # For abstract classes 4 | 5 | import numpy as np 6 | 7 | from . import tensor 8 | 9 | 10 | class Elasticity(ABC): 11 | """ 12 | Data structure for (isotropic) hyperelaticity models 13 | 1ST_lamdaE_CONSTANT is the frist lamé parameter lambda 14 | 2ST_lamdaE_CONSTANT is the second lamé parameter mu 15 | """ 16 | 17 | prop = dict() 18 | 19 | def __init__(self, E, nu): 20 | G = E / (2 * (1.0 + nu)) 21 | K = E / (3 * (1 - 2 * nu)) 22 | lamda = K - (2 / 3) * G 23 | mu = G 24 | self.prop["YOUNG_MODULUS"] = E 25 | self.prop["POISSON_COEFFICIENT"] = nu 26 | self.prop["SHEAR_MODULUS"] = G 27 | self.prop["BULK_MODULUS"] = K 28 | self.prop["1ST_LAME_CONSTANT"] = lamda 29 | self.prop["2ND_LAME_CONSTANT"] = mu 30 | 31 | def stress_stiffness(self, C): 32 | """ 33 | Compute 2nd Piola-Kirchhoff stress and material tangent at the same time 34 | """ 35 | PK2 = self.stress(C) 36 | M = self.stiffness(C) 37 | return (PK2, M) 38 | 39 | @abstractmethod 40 | def potential(self, C): 41 | raise Exception("Elasticity - Potential Function not implemented!") 42 | 43 | @abstractmethod 44 | def stress(self, C): 45 | raise Exception("Elasticity - Stress Function not implemented!") 46 | 47 | @abstractmethod 48 | def stiffness(self, C): 49 | raise Exception("Elasticity - Stiffness Function not implemented!") 50 | 51 | @property 52 | def G(self): 53 | return self.prop["SHEAR_MODULUS"] 54 | 55 | @property 56 | def E(self): 57 | return self.prop["YOUNG_MODULUS"] 58 | 59 | @property 60 | def K(self): 61 | return self.prop["BULK_MODULUS"] 62 | 63 | @property 64 | def nu(self): 65 | return self.prop["POISSON_COEFFICIENT"] 66 | 67 | @property 68 | def LAME1(self): 69 | return self.prop["1ST_LAME_CONSTANT"] 70 | 71 | @property 72 | def LAME2(self): 73 | return self.prop["2ND_LAME_CONSTANT"] 74 | 75 | def get1LAME(self): 76 | return self.LAME1 77 | 78 | def get2LAME(self): 79 | return self.LAME2 80 | 81 | 82 | class StVenantKirchhoffElasticity(Elasticity): 83 | 84 | def __init__(self, E, nu): 85 | super(StVenantKirchhoffElasticity, self).__init__(E, nu) 86 | 87 | def potential(self, C): 88 | """ 89 | Compute hyperelastic potential: phi = lamdabda/2 * tr(E)^2 - mu*(E:E) 90 | """ 91 | lamda = self.get1LAME() 92 | mu = self.get2LAME() 93 | EL = 0.5 * (C - tensor.I(len(C))) # Lagrangian strain E 94 | phi = lamda / 2.0 * (tensor.trace(EL)) ** 2 + mu * np.tensordot( 95 | EL, EL, 2 96 | ) 97 | return phi 98 | 99 | def stress(self, C): 100 | """ 101 | Compute 2nd Piola-Kirchhoff stress 102 | PK2 = 2*dphi/dC 103 | = lambda * tr(E) * I + 2 * mu * E 104 | """ 105 | dim = len(C) 106 | PK2 = tensor.tensor(dim) 107 | lamda = self.get1LAME() 108 | mu = self.get2LAME() 109 | E = tensor.tensor(dim) 110 | E = 0.5 * (C - tensor.I(dim)) 111 | II = tensor.I(dim) 112 | PK2 = lamda * tensor.trace(E) * II + 2 * mu * E 113 | return PK2 114 | 115 | def stiffness(self, C): 116 | """ 117 | Compute material tangent M = 2*dS/dC 118 | """ 119 | dim = len(C) 120 | lamda = self.get1LAME() 121 | mu = self.get2LAME() 122 | I = tensor.I(dim) 123 | IxI = tensor.outerProd4(I, I) 124 | IIsym = tensor.IISym(dim) 125 | M = lamda * IxI + 2 * mu * IIsym 126 | return M 127 | 128 | 129 | class NeoHookeanElasticity(Elasticity): 130 | 131 | def __init__(self, E, nu): 132 | # self.VERBOSE = True 133 | super(NeoHookeanElasticity, self).__init__(E, nu) 134 | 135 | def potential(self, C): 136 | """ 137 | Compute hyperelastic potential: phi = mu/2 * (tr(C)-3) - mu*ln(J) + lamda/2 *ln(J)^2 138 | """ 139 | lamda = self.get1LAME() 140 | mu = self.get2LAME() 141 | dim = len(C) 142 | if dim == 2: 143 | K = np.copy(C) 144 | C = np.zeros((3, 3)) 145 | C[:2, :2] = K[:, :] 146 | J = np.sqrt(tensor.det(C)) # J = det(F) and det(C) = J^2 147 | part1 = (mu / 2) * (tensor.trace(C) - 3.0) 148 | part2 = mu * np.log(J) 149 | part3 = (lamda / 2) * (np.log(J)) ** 2 150 | phi = part1 - part2 + part3 151 | return phi 152 | 153 | def stress(self, C): 154 | """ 155 | Compute 2nd Piola-Kirchhoff stress 156 | """ 157 | 158 | dim = len(C) 159 | if dim == 2: 160 | K = np.copy(C) 161 | C = np.eye(3) 162 | C[:2, :2] = K[:, :] 163 | PK2 = tensor.tensor(dim) 164 | detC = tensor.det(C) 165 | detF = np.sqrt(detC) 166 | lnJ = np.log(detF) 167 | lamda = self.get1LAME() 168 | mu = self.get2LAME() 169 | invC = tensor.inv(C) 170 | I = tensor.I(3) 171 | PK2 = mu * (I - invC) + lamda * lnJ * invC 172 | if dim == 2: 173 | return PK2[:2, :2] 174 | return PK2 175 | 176 | def stiffness(self, C): 177 | """ 178 | Compute material tangent M = 2*dS/dC 179 | """ 180 | d = len(C) 181 | lnJ = np.log(np.sqrt(tensor.det(C))) 182 | lamda = self.get1LAME() 183 | mu = self.get2LAME() 184 | invC = tensor.inv(C) 185 | invCC = tensor.outerProd4(invC, invC) 186 | terme1 = lamda * invCC 187 | dinvC = tensor.tensor4(d) 188 | for i in range(d): 189 | for j in range(d): 190 | for k in range(d): 191 | for l in range(d): 192 | part1 = invC[i, k] * invC[j, l] 193 | part2 = invC[i, l] * invC[j, k] 194 | dinvC[i, j, k, l] = -(part1 + part2) / 2 195 | 196 | M = lamda * invCC + 2 * (lamda * lnJ - mu) * dinvC 197 | 198 | return M 199 | -------------------------------------------------------------------------------- /src/hyper/fem.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # 3 | # Data structures for finite element model 4 | # 5 | 6 | 7 | import numpy as np 8 | from scipy.linalg import polar 9 | 10 | from . import geometry, tensor 11 | 12 | ######################################################################## 13 | # Definition of elements for Finite Elements Method # 14 | ######################################################################## 15 | 16 | 17 | class FiniteElement: 18 | """ 19 | Data structure for finite element 20 | """ 21 | 22 | def __init__(self, t, xNod): 23 | 24 | # 25 | # --- initialise mechanical tensors at each integration point 26 | # 27 | self.calculate_shapes(t, xNod) 28 | 29 | self.F = [] # deformation gradient F = Grad(u) + I 30 | self.hencky = [] # hencky strain ln(V) with F = V.R 31 | self.E_GL = [] # lagrangian strain E = 1/2 (C - I) 32 | self.E_EA = [] # E_EA strain e = 1/2 (I - b^-1) 33 | self.PK1 = [] # piola kirchoff I : P = F*S 34 | self.sigma = [] # cauchy stress : \sigma 35 | self.K = [] # lagrangian tangent operator dP/dF 36 | d = self.getDim() # space dimension 37 | npg = self.getNIntPts() 38 | for n in range(npg): 39 | self.F.append(tensor.tensor(d)) 40 | self.hencky.append(tensor.tensor(d)) 41 | self.E_GL.append(tensor.tensor(d)) 42 | self.E_EA.append(tensor.tensor(d)) 43 | self.PK1.append(tensor.tensor(d)) 44 | self.sigma.append(tensor.tensor(d)) 45 | self.K.append(tensor.tensor4(d)) 46 | 47 | def calculate_shapes(self, t, xNod): 48 | self.type = t 49 | self.shape = [] 50 | self.dshape = [] 51 | self.weight = [] 52 | 53 | if t == 2: # triangle T3 (1 int. pt.) 54 | npg = 3 # Number of integration points 55 | npN = 3 # Number of nodes in the element 56 | dim = 2 57 | IP = geometry.IPTri # class to get Integration Info 58 | Shape = geometry.SFT3 # Function to get N(X) et dN(X) 59 | 60 | if t == 3: # square Q4 (1 int. pt.) 61 | npg = 4 # Number of integration points 62 | npN = 4 # Number of nodes in the element 63 | dim = 2 64 | IP = geometry.IPQua # class to get Integration Info 65 | Shape = geometry.SFQ4 # Function to get N(X) et dN(X) 66 | 67 | X = IP.getX(npg) 68 | W = IP.getW(npg) 69 | for i in range(npg): # loop on integration points 70 | Xi = X[i] 71 | Wi = W[i] 72 | shapei = Shape.N(Xi) 73 | dshapei = Shape.dN(Xi) 74 | 75 | dshapei = np.array(dshapei) 76 | J = np.dot(np.transpose(xNod), dshapei) 77 | # for n in range(npN): # loop on nodes 78 | # xn = xNod[n][:dim] 79 | # dshapein = dshapei[n] 80 | # J += tensor.outerProd(xn, dshapein) 81 | detJ = tensor.det(J) 82 | Jinv = tensor.inv(J) 83 | dshapei = np.dot(dshapei, Jinv) 84 | weighti = Wi * detJ 85 | self.shape.append(shapei) 86 | self.dshape.append(dshapei) 87 | self.weight.append(weighti) 88 | 89 | def getNpg(self): 90 | return np.shape(self.dshape)[0] 91 | 92 | def getNNodes(self): 93 | return np.shape(self.dshape)[1] 94 | 95 | def getDim(self): 96 | return np.shape(self.dshape)[2] 97 | 98 | def getNIntPts(self): 99 | return len(self.shape) 100 | 101 | def gradient(self, dShp, uNod): 102 | """ 103 | Compute gradient of the displacement field 104 | """ 105 | # ===================================================================== 106 | # TODO: compute the gradient of the displacement field from the local 107 | # nodal field 'uNod' and the shape functions 'dShp' (20pts) 108 | # ... 109 | # np.dot(np.transpose(uNod),dShp) 110 | uNod = np.transpose(np.array(uNod)) 111 | # dShp = np.transpose(dShp 112 | grad = np.dot(uNod, dShp) 113 | return grad 114 | # ===================================================================== 115 | 116 | def update(self, uNod, mater): 117 | """ 118 | update strain and stress tensors of the element from the displacement 119 | field 'uNod' with the material model 'mater' 120 | """ 121 | # dshape = np.shape(self.dshape) 122 | # dshape = (npg, npN, dim) 123 | # npg is the number of gauss points to integration 124 | # npN is the number of nodes in each element 125 | # dim is the dimention of the problem. If 2D -> dim = 2 126 | npg = self.getNpg() 127 | for i in range(npg): # loop on integration points 128 | # compute CG stretch tensor and GL strain tensor 129 | G = self.gradient(self.dshape[i], uNod) 130 | F = G + tensor.I(len(G)) 131 | self.F[i] = F # store deformation gradient at integration point i 132 | C = tensor.rightCauchyGreen(F) 133 | self.E_GL[i] = 0.5 * (C - tensor.I(len(C))) 134 | # compute spatial description 135 | # from scipy.linalg.polar() method with u=R and p=V, 136 | _, V = polar(F, side="left") 137 | # replace pure zeros by very low values to prevent "nan" in np.log(V) 138 | V[V < 1e-10] = 1e-15 139 | self.hencky[i] = np.log(V) # ln(V) with F = V.R, "true" strain 140 | b = tensor.leftCauchyGreen(F) 141 | self.E_EA[i] = 0.5 * (tensor.I(len(b)) - tensor.inv(b)) 142 | ### 143 | if mater == 0: # skip next lines: do not compute stress 144 | # print("Whahat") 145 | continue 146 | # compute PK2 stress tensor and material tangent operator M=2*dS/dC 147 | # print("type(mater) = " + str(type(mater))) 148 | # print("mater = " + str(mater)) 149 | 150 | (PK2, M) = mater.stress_stiffness(C) 151 | 152 | # compute PK1 stress and lagrangian tangent operator K = dP/dF 153 | # print("PK2 = ") 154 | # print(PK2) 155 | # print("F = ") 156 | # print(F) 157 | self.PK1[i] = tensor.PK2toPK1(F, PK2) 158 | # print("PK1[i] = ") 159 | # print(self.PK1[i]) 160 | # print("PK1[i] = ") 161 | # print(self.PK1[i]) 162 | self.K[i] = tensor.MaterialToLagrangian(F, PK2, M) 163 | # compute cauchy stress (spatial description) 164 | self.sigma[i] = tensor.PK1toCauchy(F, self.PK1[i]) 165 | 166 | # def computeForces(self, fNod): 167 | def computeForces(self): 168 | """ 169 | compute internal forces of the element 170 | """ 171 | npg = self.getNpg() 172 | nNodes = self.getNNodes() 173 | dim = self.getDim() 174 | fNod = np.zeros((nNodes, dim)) 175 | # dshape = (npg, npN, dim) 176 | # npg is the number of gauss points to integration 177 | # npN is the number of nodes in each element 178 | # dim is the dimention of the problem. If 2D -> dim = 2 179 | for i in range(npg): 180 | PK1i = np.transpose(self.PK1[i]) 181 | dshapei = self.dshape[i] 182 | weighti = self.weight[i] 183 | fNod += weighti * dshapei @ PK1i 184 | # print("fNod = " + str(fNod)) 185 | return fNod 186 | 187 | # def computeStiffness(self, KNod): 188 | def computeStiffness(self): 189 | """ 190 | compute internal stiffness of the element 191 | """ 192 | npg = self.getNpg() 193 | nNodes = self.getNNodes() 194 | dim = self.getDim() 195 | KNod = np.zeros((nNodes, dim, nNodes, dim)) 196 | for ind in range(npg): 197 | Ki = self.K[ind] 198 | wi = self.weight[ind] 199 | dshi = self.dshape[ind] 200 | KNod += wi * np.einsum("iw,jwlz,kz->ijkl", dshi, Ki, dshi) 201 | return KNod 202 | 203 | 204 | class FEModel: 205 | """ 206 | Data structure for FE model 207 | """ 208 | 209 | def __init__(self, theMesh, m=0): 210 | self.dim = theMesh.getDimension() # mesh dimension 211 | self.elems = [] # list of FiniteElement instances 212 | self.connect = [] # table of connectivity (list of list) 213 | self.nNodes = theMesh.getNNodes() # Number of nodes in the mesh 214 | self.nelem = theMesh.getNElements() # Number of elements in the mesh 215 | for n in range(self.nelem): 216 | elem = theMesh.getElement(n) 217 | if (elem.type < 1) or (elem.type > 3): 218 | continue 219 | self.connect.append(elem.nodes) 220 | xNod = [] 221 | nNodes_elem = elem.getNNodes() 222 | for i in range(nNodes_elem): 223 | label_nodei = elem.nodes[i] 224 | nodei = theMesh.getNode(label_nodei) 225 | xnodei = nodei.getX() 226 | # Since we don't need z, we cut it out 227 | xnodei = xnodei[: self.dim] 228 | xNod.append(xnodei) 229 | xNod = np.array(xNod) 230 | new_FiniteElement = FiniteElement(elem.type, xNod) 231 | self.elems.append(new_FiniteElement) 232 | self.material = m # constitutive model instance from elasticity module 233 | 234 | def getDim(self): 235 | """ 236 | get the dimension of the mesh 237 | """ 238 | return self.dim 239 | 240 | def getNNodes(self): 241 | """ 242 | get number of nodes in the mesh 243 | """ 244 | return self.nNodes 245 | 246 | def getNElements(self): 247 | """ 248 | get number of elements 249 | """ 250 | return self.nelem 251 | 252 | def nElements(self): 253 | return self.getNElements() 254 | 255 | def assemble2(self, e, vNod): 256 | """ 257 | Assemble nodal values for element e, 2-entry array 258 | """ 259 | loc = self.connect[e] 260 | self.Tint[loc, :] += vNod[:, :] 261 | # raise Exception("assemble2: Not implemented") 262 | 263 | def assemble4(self, e, KNod): 264 | """ 265 | Assemble nodal values for element e, 4-entry array 266 | """ 267 | loc = self.connect[e] 268 | dim = self.getDim() 269 | # self.Kint[loc[:], :, loc[:], :] += KNod[:, :, :, :] 270 | for i, I in enumerate(loc): 271 | for j in range(dim): 272 | for k, K in enumerate(loc): 273 | for l in range(dim): 274 | self.Kint[I, j, K, l] += KNod[i, j, k, l] 275 | # raise Exception("assemble4: Not implemented") 276 | 277 | def extract(self, U, e): 278 | """ 279 | Extract nodal values for element e 280 | """ 281 | if not isinstance(e, (int)): 282 | raise Exception( 283 | "The element 'e' in 'extract' function is not a integer" 284 | ) 285 | # print("index = " + str(index)) 286 | connect_e = self.connect[e] 287 | # print("connect_e = " + str(connect_e)) 288 | return [U[i] for i in connect_e] 289 | 290 | # def computeInternalForces(self, U, T): 291 | def computeInternalForces(self, U): 292 | """ 293 | Compute generalized internal forces Tint 294 | """ 295 | # T shape = (number of nodes in mesh, space dimension) 296 | # n, dim = T.shape 297 | nNodes = self.getNNodes() 298 | dim = self.getDim() 299 | nElements = self.getNElements() 300 | self.Tint = np.zeros((nNodes, dim)) 301 | for e in range(nElements): 302 | uNod = self.extract(U, e) 303 | elem = self.elems[e] 304 | elem.update(uNod, self.material) 305 | vNod = elem.computeForces() 306 | self.assemble2(e, vNod) 307 | # print("Tint = ") 308 | # print(self.Tint) 309 | return self.Tint 310 | # raise Exception("computeInternalForces: Not implemented") 311 | 312 | # def computeResidual(self, U, R): 313 | def computeResidual(self, U): 314 | """ 315 | Compute residual R = Tint - Text 316 | """ 317 | # nNodes = self.getNNodes() 318 | # dim = self.getDim() 319 | # R = np.zeros((nNodes, dim)) 320 | # R[:, :] = 0.0 # size = (number of nodes in mesh, space dimension) 321 | # R = self.computeInternalForces(U, R) 322 | R = self.computeInternalForces(U) # R = Tint 323 | # R -= Text 324 | return R 325 | 326 | # def computeInternalStiffness(self, U, Kint): 327 | def computeInternalStiffness(self, U): 328 | """ 329 | Compute generalized internal stiffness tangent Kint 330 | """ 331 | # K shape = (number of nodes in mesh, space dimension, 332 | # number of nodes in mesh, space dimension) 333 | self.computeStress(U) 334 | 335 | nNodes = self.getNNodes() 336 | dim = self.getDim() 337 | nElements = self.getNElements() 338 | self.Kint = np.zeros((nNodes, dim, nNodes, dim)) 339 | for e in range(nElements): 340 | # uNod = self.extract(U, e) 341 | elem = self.elems[e] 342 | KNod = elem.computeStiffness() 343 | self.assemble4(e, KNod) 344 | # print("Kint = ") 345 | # print(self.Kint) 346 | return self.Kint 347 | # size = (number of nodes in mesh, space dimension,number of nodes in mesh, space dimension) 348 | # raise Exception("computeInternalStiffness: Not implemented") 349 | 350 | def computeTangent(self, U): 351 | """ 352 | Compute tangent K = Kint - Kext = Kint: in the absence of displacement- 353 | depend external forces Kext = 0. 354 | """ 355 | # size = (number of nodes in mesh, space dimension,number of nodes in mesh, space dimension) 356 | K = self.computeInternalStiffness(U) # K = Kint 357 | return K 358 | 359 | def computeStrain(self, U): 360 | """ 361 | Compute strains on all elements 362 | """ 363 | # loop on elements 364 | for n in range(len(self.elems)): 365 | # get nodal displacements for element 366 | uNod = self.extract(U, n) 367 | # compute gradients (and strains) 368 | # print("uNod = " + str(uNod)) 369 | self.elems[n].update(uNod, mater=0) 370 | 371 | def computeStress(self, U): 372 | """ 373 | Compute stresses on all elements 374 | """ 375 | # loop on elements 376 | for n in range(len(self.elems)): 377 | # get nodal displacements for element 378 | uNod = self.extract(U, n) 379 | # compute stresses 380 | self.elems[n].update(uNod, self.material) 381 | 382 | def getDeformationGradient(self, n): 383 | """ 384 | Return average of deformation gradient at all integration points of element n 385 | """ 386 | avg = tensor.tensor(self.dim) 387 | for tens in self.elems[n].F: 388 | avg += tens 389 | avg /= self.elems[n].getNIntPts() 390 | return avg 391 | 392 | def getStrainGreenLagrange(self, n): 393 | """ 394 | Return average of GL strain at all integration points of element n 395 | """ 396 | avg = tensor.tensor(self.dim) 397 | for tens in self.elems[n].E_GL: 398 | avg += tens 399 | avg /= self.elems[n].getNIntPts() 400 | return avg 401 | 402 | def getStressPK1(self, n): 403 | """ 404 | Return average of PK1 stress at all integration points of element n 405 | """ 406 | avg = tensor.tensor(self.dim) 407 | for tens in self.elems[n].PK1: 408 | avg += tens 409 | avg /= self.elems[n].getNIntPts() 410 | return avg 411 | 412 | def getStrainEulerAlmansi(self, n): 413 | """Return average of EA strain at all integration points of element n""" 414 | avg = tensor.tensor(self.dim) 415 | for tens in self.elems[n].E_EA: 416 | avg += tens 417 | avg /= self.elems[n].getNIntPts() 418 | return avg 419 | 420 | def getStrainHencky(self, n): 421 | """ 422 | Return average of hencky strain at all integration points of element n 423 | """ 424 | avg = tensor.tensor(self.dim) 425 | for tens in self.elems[n].hencky: 426 | avg += tens 427 | avg /= self.elems[n].getNIntPts() 428 | return avg 429 | 430 | def getStressCauchy(self, n): 431 | """ 432 | Return average of cauchy stress at all integration points of element n 433 | """ 434 | avg = tensor.tensor(self.dim) 435 | for tens in self.elems[n].sigma: 436 | avg += tens 437 | avg /= self.elems[n].getNIntPts() 438 | return avg 439 | -------------------------------------------------------------------------------- /src/hyper/geometry.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | 3 | ######################################################################## 4 | # Gauss Quadrature # 5 | ######################################################################## 6 | # 7 | # 8 | # In 1D, we have: ----- Integration in the interval [-1, 1] 9 | # ________________________________________________________________ 10 | # | Nb Points | Position of the points | Weight | 11 | # |-----------|-----------------------------|----------------------| 12 | # | 1 | 0 | 2 | 13 | # |-----------|-----------------------------|----------------------| 14 | # | 2 | -a, a | 1, 1 | 15 | # |-----------|-----------------------------|----------------------| 16 | # | 3 | -b, 0, b | 5/9, 8/9, 5/9 | 17 | # ‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾ 18 | # Where a = 1/sqrt(3) and b = sqrt(3/5) 19 | # 20 | # 21 | # In 2D, we have: ----- Integration in the interval [-1, 1] x [-1, 1] 22 | # ________________________________________________________________ 23 | # | Nb Points | Position of the points | Weight | 24 | # |-----------|-----------------------------|----------------------| 25 | # | 1 | (0, 0) | 4 | 26 | # |-----------|-----------------------------|----------------------| 27 | # | 4 | (-a, a), (a, a), | 1, 1, | 28 | # | | (-a, -a), (a, -a) | 1, 1 | 29 | # |-----------|-----------------------------|----------------------| 30 | # | | (-b, b), (0, b), (b, b) | 25/81, 40/81, 25/81 | 31 | # | 9 | (-b, 0), (0, 0), (b, 0) | 40/81, 64/81, 40/81 | 32 | # | | (-b, -b), (0, -b), (b, -b) | 25/81, 40/81, 25/81 | 33 | # ‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾ 34 | 35 | 36 | class IPTri: 37 | """ 38 | Numerical integration rules for triangles 39 | Vertices: 40 | P1 = (0, 0) 41 | P2 = (1, 0) 42 | P3 = (0, 1) 43 | """ 44 | 45 | @staticmethod 46 | def getX(npg=3): 47 | if npg == 1: 48 | X = [(1.0 / 3.0, 1 / 3.0)] 49 | elif npg == 3: 50 | X = [(2 / 3, 1 / 6), (1 / 6, 1 / 6), (1 / 6, 2 / 3)] 51 | elif npg == 4: 52 | X = [ 53 | (1 / 3, 1 / 3), 54 | (3 / 5, 1 / 5), 55 | (1 / 5, 1 / 5), 56 | (1 / 5, 3 / 5), 57 | ] 58 | else: 59 | raise ValueError("Not found npg = " + str(npg)) 60 | return X 61 | 62 | @staticmethod 63 | def getW(npg=3): 64 | if npg == 1: 65 | W = [1.0 / 2.0] 66 | elif npg == 3: 67 | W = [1 / 6, 1 / 6, 1 / 6] 68 | elif npg == 4: 69 | W = [-9 / 32, 25 / 96, 25 / 96, 25 / 96] 70 | else: 71 | raise ValueError("Not found npg = " + str(npg)) 72 | return W 73 | 74 | 75 | class IPQua: 76 | """ 77 | Numerical integration rules for quadrangles 78 | Vertices: 79 | P1 = (-1, -1) 80 | P2 = ( 1, -1) 81 | P3 = ( 1, 1) 82 | P4 = (-1, 1) 83 | """ 84 | 85 | @staticmethod 86 | def getX(npg=3): 87 | if npg == 1: 88 | X = [(0, 0)] 89 | elif npg == 4: 90 | a = 1 / np.sqrt(3) 91 | X = [(-a, a), (-a, -a), (a, -a), (a, a)] 92 | elif npg == 9: 93 | b = np.sqrt(3 / 5) 94 | X = [ 95 | (-b, b), 96 | (0, b), 97 | (b, b), 98 | (-b, 0), 99 | (0, 0), 100 | (b, 0), 101 | (-b, -b), 102 | (0, -b), 103 | (b, -b), 104 | ] 105 | else: 106 | raise ValueError("Not found npg = " + str(npg)) 107 | return X 108 | 109 | @staticmethod 110 | def getW(npg=4): 111 | if npg == 1: 112 | W = [4] 113 | elif npg == 4: 114 | W = [1, 1, 1, 1] 115 | elif npg == 9: 116 | W = [ 117 | 25 / 81, 118 | 40 / 81, 119 | 25 / 81, 120 | 40 / 81, 121 | 64 / 81, 122 | 40 / 81, 123 | 25 / 81, 124 | 40 / 81, 125 | 25 / 81, 126 | ] 127 | else: 128 | raise ValueError("Not found npg = " + str(npg)) 129 | return W 130 | 131 | 132 | ######################################################################## 133 | # Definition of interpolation functions in 2D # 134 | ######################################################################## 135 | # 136 | # We have two geometries: 137 | # Triangle: 138 | # . (0, 1) 139 | # |╲ 140 | # | ╲ 141 | # | ╲ 142 | # | ╲ 143 | # |____╲(1, 0) 144 | # (0,0) 145 | # 146 | # Square: 147 | # (-1, 1)_________(1, 1) 148 | # | | 149 | # | | 150 | # | | 151 | # | | 152 | # (-1, -1)‾‾‾‾‾‾‾‾‾(1, -1) 153 | # 154 | 155 | 156 | class SFT3: 157 | """ 158 | Shape functions for 3-node triangle 159 | Vertices: 160 | P1 = (0, 0) 161 | P2 = (1, 0) 162 | P3 = (0, 1) 163 | """ 164 | 165 | @staticmethod 166 | def N(x): 167 | N1 = 1 - x[0] - x[1] 168 | N2 = x[0] 169 | N3 = x[1] 170 | return [N1, N2, N3] 171 | 172 | @staticmethod 173 | def dN(x): 174 | dN1_dx0 = -1 175 | dN1_dx1 = -1 176 | dN2_dx0 = 1 177 | dN2_dx1 = 0 178 | dN3_dx0 = 0 179 | dN3_dx1 = 1 180 | dN1 = [dN1_dx0, dN1_dx1] 181 | dN2 = [dN2_dx0, dN2_dx1] 182 | dN3 = [dN3_dx0, dN3_dx1] 183 | return [dN1, dN2, dN3] 184 | 185 | @staticmethod 186 | def P(): 187 | P1 = (0, 0) 188 | P2 = (1, 0) 189 | P3 = (0, 1) 190 | return [P1, P2, P3] 191 | 192 | 193 | class SFT6: 194 | """ 195 | Shape functions for 3-node triangle 196 | Vertices: 197 | P1 = (0, 0) 198 | P2 = (0.5, 0) 199 | P3 = (1, 0) 200 | P4 = (0.5, 0.5) 201 | P5 = (0, 1) 202 | P6 = (0, 0.5) 203 | """ 204 | 205 | @staticmethod 206 | def N(x): 207 | # Ni(Pj) = delta_ij 208 | N1 = (x[0] + x[1] - 1) * (2 * x[0] + 2 * x[1] - 1) 209 | N2 = 4 * x[0] * (1 - x[0] - x[1]) 210 | N3 = x[0] * (2 * x[0] - 1) 211 | N4 = 4 * x[0] * x[1] 212 | N5 = x[1] * (2 * x[1] - 1) 213 | N6 = 4 * x[1] * (1 - x[0] - x[1]) 214 | return [N1, N2, N3, N4, N5, N6] 215 | 216 | @staticmethod 217 | def dN(x): 218 | dN1 = [4 * (x[0] + x[1]) - 3, 4 * (x[0] + x[1]) - 3] 219 | dN2 = [4 * (1 - 2 * x[0] - x[1]), -4 * x[0]] 220 | dN3 = [4 * x[0] - 1, 0] 221 | dN4 = [4 * x[1], 4 * x[0]] 222 | dN5 = [0, 4 * x[1] - 1] 223 | dN6 = [-4 * x[1], 4 * (1 - x[0] - 2 * x[1])] 224 | return [dN1, dN2, dN3, dN4, dN5, dN6] 225 | 226 | @staticmethod 227 | def P(): 228 | P1 = (0, 0) 229 | P2 = (0.5, 0) 230 | P3 = (1, 0) 231 | P4 = (0.5, 0.5) 232 | P5 = (0, 1) 233 | P6 = (0, 0.5) 234 | return [P1, P2, P3, P4, P5, P6] 235 | 236 | 237 | class SFQ4: 238 | """ 239 | Shape functions for 4-node quadrangle 240 | Vertices: 241 | P1 = (-1, -1) 242 | P2 = (1, -1) 243 | P3 = (1, 1) 244 | P4 = (-1, 1) 245 | """ 246 | 247 | @staticmethod 248 | def N(x): 249 | N1 = (x[0] - 1) * (x[1] - 1) / 4 250 | N2 = (x[0] + 1) * (1 - x[1]) / 4 251 | N3 = (x[0] + 1) * (x[1] + 1) / 4 252 | N4 = (1 - x[0]) * (x[1] + 1) / 4 253 | return [N1, N2, N3, N4] 254 | 255 | @staticmethod 256 | def dN(x): 257 | dN1 = [(x[1] - 1) / 4, (x[0] - 1) / 4] 258 | dN2 = [(1 - x[1]) / 4, -(x[0] + 1) / 4] 259 | dN3 = [(x[1] + 1) / 4, (x[0] + 1) / 4] 260 | dN4 = [-(x[1] + 1) / 4, (1 - x[0]) / 4] 261 | return [dN1, dN2, dN3, dN4] 262 | 263 | @staticmethod 264 | def P(): 265 | P1 = (-1, -1) 266 | P2 = (1, -1) 267 | P3 = (1, 1) 268 | P4 = (-1, 1) 269 | return [P1, P2, P3, P4] 270 | 271 | 272 | class SFQ8: 273 | """ 274 | Shape functions for 8-node quadrangle 275 | Vertices: 276 | P1 = (-1, -1) 277 | P2 = (0, -1) 278 | P3 = (1, -1) 279 | P4 = (1, 0) 280 | P5 = (1, 1) 281 | P6 = (0, 1) 282 | P7 = (-1, 1) 283 | P8 = (-1, 0) 284 | """ 285 | 286 | @staticmethod 287 | def N(x): 288 | N1 = -(x[0] - 1) * (x[1] - 1) * (x[0] + x[1] + 1) / 4 289 | N2 = (x[0] - 1) * (x[0] + 1) * (x[1] - 1) / 2 290 | N3 = -(x[0] + 1) * (x[1] - 1) * (x[0] - x[1] - 1) / 4 291 | N4 = -(x[0] + 1) * (x[1] - 1) * (x[1] + 1) / 2 292 | N5 = (x[0] + 1) * (x[1] + 1) * (x[0] + x[1] - 1) / 4 293 | N6 = -(x[0] - 1) * (x[0] + 1) * (x[1] + 1) / 2 294 | N7 = (x[0] - 1) * (x[1] + 1) * (x[0] - x[1] + 1) / 4 295 | N8 = (x[0] - 1) * (x[1] - 1) * (x[1] + 1) / 2 296 | return [N1, N2, N3, N4, N5, N6, N7, N8] 297 | 298 | @staticmethod 299 | def dN(x): 300 | dN1 = [ 301 | (2 * x[0] + x[1]) * (1 - x[1]) / 4, 302 | (1 - x[0]) * (x[0] + 2 * x[1]) / 4, 303 | ] 304 | dN2 = [x[0] * (x[1] - 1), (x[0] ** 2 - 1) / 2] 305 | dN3 = [ 306 | (-2 * x[0] + x[1]) * (x[1] - 1) / 4, 307 | (-x[0] + 2 * x[1]) * (x[0] + 1) / 4, 308 | ] 309 | dN4 = [(1 - x[1] ** 2) / 2, -x[1] * (x[0] + 1)] 310 | dN5 = [ 311 | (2 * x[0] + x[1]) * (x[1] + 1) / 4, 312 | (x[0] + 1) * (x[0] + 2 * x[1]) / 4, 313 | ] 314 | dN6 = [-x[0] * (x[1] + 1), (1 - x[0] ** 2) / 2] 315 | dN7 = [ 316 | (2 * x[0] - x[1]) * (x[1] + 1) / 4, 317 | (x[0] - 1) * (x[0] - 2 * x[1]) / 4, 318 | ] 319 | dN8 = [(x[1] ** 2 - 1) / 2, x[1] * (x[0] - 1)] 320 | return [dN1, dN2, dN3, dN4, dN5, dN6, dN7, dN8] 321 | 322 | @staticmethod 323 | def P(): 324 | P1 = (-1, -1) 325 | P2 = (0, -1) 326 | P3 = (1, -1) 327 | P4 = (1, 0) 328 | P5 = (1, 1) 329 | P6 = (0, 1) 330 | P7 = (-1, 1) 331 | P8 = (-1, 0) 332 | return [P1, P2, P3, P4, P5, P6, P7, P8] 333 | -------------------------------------------------------------------------------- /src/hyper/gmsh2.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # 3 | # Functions to write Gmsh output files 4 | # 5 | import numpy as np 6 | 7 | from . import mesh as msh 8 | 9 | # 10 | # Read mesh data from a .msh file in Gmsh V.2 or V.4 format 11 | # INPUT: - inp : input stream 12 | # - d : spatial dimension required for mesh data object (default = 2) 13 | # NOTE: all Gmsh mesh files are 3d 14 | # OUTPUT: a MeshData object (as defined in mesh.py) 15 | # 16 | 17 | 18 | def gmshInput_mesh(inp, d=2): 19 | """Read mesh in Gmsh format""" 20 | lines = inp.readlines() 21 | mesh = msh.MeshData() 22 | iTab = dict() # table matching node labels to internal indices 23 | # 24 | # --- determine format (v.2 or v.4 more recent) 25 | # 26 | words = lines[1].split() # $MeshFormat information 27 | fmt = int(float(words[0])) # version format 2 or 4 28 | fbin = int(words[1]) # whether binary file or not 29 | llen = int(words[2]) # data-size, unused 30 | # loop on lines 31 | l = 0 32 | # 33 | # --- version 2 34 | # 35 | if fmt == 2: 36 | while l < len(lines): 37 | if lines[l].startswith("$Nodes"): 38 | l += 1 39 | nNodes = int(lines[l].strip()) 40 | i0 = len(iTab) 41 | for n in range(nNodes): 42 | l += 1 43 | words = lines[l].split() 44 | lbl = int(words[0]) 45 | iTab[lbl] = i0 + n 46 | if d == 1: 47 | mesh.addNode(lbl, float(words[1])) 48 | elif d == 2: 49 | mesh.addNode(lbl, float(words[1]), float(words[2])) 50 | elif d == 3: 51 | mesh.addNode( 52 | lbl, 53 | float(words[1]), 54 | float(words[2]), 55 | float(words[3]), 56 | ) 57 | elif lines[l].startswith("$Elements"): 58 | l += 1 59 | nElems = int(lines[l].strip()) 60 | for n in range(nElems): 61 | l += 1 62 | words = lines[l].split() 63 | lbl = int(words[0]) 64 | typ = int(words[1]) 65 | ntg = int(words[2]) 66 | iNodes = [] 67 | if d == 1 and typ == 1: # 2-node edge 68 | iNodes.append(iTab[int(words[ntg + 3])]) 69 | iNodes.append(iTab[int(words[ntg + 4])]) 70 | mesh.addElement(lbl, typ, iNodes) 71 | elif d == 2 and typ == 2: # 3-node triangle 72 | iNodes.append(iTab[int(words[ntg + 3])]) 73 | iNodes.append(iTab[int(words[ntg + 4])]) 74 | iNodes.append(iTab[int(words[ntg + 5])]) 75 | mesh.addElement(lbl, typ, iNodes) 76 | elif d == 2 and typ == 3: # 4-node quadrangle 77 | iNodes.append(iTab[int(words[ntg + 3])]) 78 | iNodes.append(iTab[int(words[ntg + 4])]) 79 | iNodes.append(iTab[int(words[ntg + 5])]) 80 | iNodes.append(iTab[int(words[ntg + 6])]) 81 | mesh.addElement(lbl, typ, iNodes) 82 | else: 83 | l += 1 # ignore line 84 | # 85 | # --- version 4 86 | # 87 | elif fmt == 4: 88 | while l < len(lines): 89 | if lines[l].startswith("$Nodes"): 90 | l += 1 91 | words = lines[l].split() 92 | nEntityBlocks = int(words[0]) 93 | nNodes = int(words[1]) 94 | i0 = len(iTab) 95 | numNode = -1 96 | for n in range(nEntityBlocks): 97 | l += 1 98 | words = lines[l].split() 99 | tagE = int(words[0]) 100 | dimE = int(words[1]) 101 | param = int(words[2]) # if parametric, 1, else 0 102 | if param != 0: 103 | # != instead of <> in Python 3 104 | raise ValueError( 105 | "parametric nodes are not handled for now" 106 | ) 107 | numNodes = int(words[3]) 108 | for n in range(numNodes): 109 | l += 1 110 | words = lines[l].split() 111 | lbl = int(words[0]) 112 | numNode += 1 113 | iTab[lbl] = i0 + numNode 114 | if d == 1: 115 | mesh.addNode(lbl, float(words[1])) 116 | elif d == 2: 117 | mesh.addNode(lbl, float(words[1]), float(words[2])) 118 | elif d == 3: 119 | mesh.addNode( 120 | lbl, 121 | float(words[1]), 122 | float(words[2]), 123 | float(words[3]), 124 | ) 125 | elif lines[l].startswith("$Elements"): 126 | l += 1 127 | words = lines[l].split() 128 | nEntityBlocks = int(words[0]) 129 | nElems = int(words[1]) 130 | for n in range(nEntityBlocks): 131 | l += 1 132 | words = lines[l].split() 133 | # tagE = int(words[0]) 134 | # dimE = int(words[1]) 135 | typ = int(words[2]) # type of the element (entity) 136 | numElems = int(words[3]) # number of elements of that type 137 | for n in range(numElems): 138 | l += 1 139 | words = lines[l].split() 140 | lbl = int(words[0]) 141 | iNodes = [] 142 | if d == 1 and typ == 1: # 2-node edge 143 | iNodes.append(iTab[int(words[1])]) 144 | iNodes.append(iTab[int(words[2])]) 145 | mesh.addElement(lbl, typ, iNodes) 146 | elif d == 2 and typ == 2: # 3-node triangle 147 | iNodes.append(iTab[int(words[1])]) 148 | iNodes.append(iTab[int(words[2])]) 149 | iNodes.append(iTab[int(words[3])]) 150 | mesh.addElement(lbl, typ, iNodes) 151 | elif d == 2 and typ == 3: # 4-node quadrangle 152 | iNodes.append(iTab[int(words[1])]) 153 | iNodes.append(iTab[int(words[2])]) 154 | iNodes.append(iTab[int(words[3])]) 155 | iNodes.append(iTab[int(words[4])]) 156 | mesh.addElement(lbl, typ, iNodes) 157 | else: 158 | l += 1 # ignore line 159 | assert numNode + 1 == nNodes 160 | else: 161 | raise ValueError( 162 | "Format of the meshfile is incorrect. Verify the header $MeshFormat" 163 | ) 164 | return mesh 165 | 166 | 167 | # 168 | # Write mesh data in Gmsh v.2 format 169 | # INPUT: - out : output stream 170 | # - mesh : MeshData object 171 | # 172 | 173 | 174 | def gmshOutput_mesh(out, mesh): 175 | """Write mesh in Gmsh v.2 format""" 176 | dim = mesh.getDimension() 177 | # HEADER 178 | out.write("$MeshFormat\n") 179 | out.write("%d.%d %d %d\n" % (2, 2, 0, 8)) 180 | out.write("$EndMeshFormat\n") 181 | # NODES 182 | out.write("$Nodes\n") 183 | out.write("%d\n" % mesh.nNodes()) 184 | for n in range(mesh.nNodes()): 185 | out.write("%d" % (n + 1)) 186 | for i in range(dim): 187 | out.write(" %13.6e" % mesh.getNode(n).getX(i)) 188 | for i in range(dim, 3): 189 | out.write(" %f" % 0.0) 190 | out.write("\n") 191 | out.write("$EndNodes\n") 192 | # ELEMENTS 193 | out.write("$Elements\n") 194 | out.write("%d\n" % mesh.nElements()) 195 | for n in range(mesh.nElements()): 196 | out.write( 197 | "%d %d %d %d %d" % (n + 1, mesh.getElement(n).getType(), 2, 1, 1) 198 | ) 199 | for i in range(mesh.getElement(n).nNodes()): 200 | out.write(" %d" % (mesh.getElement(n).getNode(i) + 1)) 201 | out.write("\n") 202 | out.write("$EndElements\n") 203 | out.flush() 204 | 205 | 206 | # 207 | # Write nodal field defined on a mesh, in Gmsh V.2 format 208 | # INPUT: - out : output stream 209 | # - label : string defining the field name 210 | # - V[nNodes][iDim] : array-like (e.g. NumPy) containing nodal values 211 | # - it : (time) step number 212 | # - t : load factor / time 213 | # NOTE: this function must be called after writing the mesh data 214 | # no attempt is made to check consistency between mesh and field data 215 | # 216 | 217 | 218 | def gmshOutput_nodal(out, label, V, it, t): 219 | """Write nodal field in Gmsh format""" 220 | out.write("$NodeData\n") 221 | out.write("%d\n" % 1) 222 | out.write('"%s"\n' % label) 223 | out.write("%d\n" % 1) 224 | out.write("%f\n" % t) 225 | out.write("%d\n" % 3) 226 | out.write("%d\n" % it) 227 | sz0 = np.shape(V)[1] 228 | if sz0 == 2: 229 | sz1 = 3 230 | elif sz0 > 3: 231 | sz1 = 9 232 | else: 233 | sz1 = 1 234 | out.write("%d\n" % sz1) 235 | out.write("%d\n" % np.shape(V)[0]) 236 | for n in range(np.shape(V)[0]): 237 | out.write("%d" % (n + 1)) 238 | for i in range(sz0): 239 | out.write(" %13.6e" % V[n][i]) 240 | for i in range(sz0, sz1): 241 | out.write(" %13.6e" % 0.0) 242 | out.write("\n") 243 | out.write("$EndNodeData\n") 244 | out.flush() 245 | 246 | 247 | # 248 | # Write element field defined on a mesh, in Gmsh V.2 format 249 | # INPUT: - out : output stream 250 | # - label : string defining the field name 251 | # - V[nElems][iDim] : array-like (e.g. NumPy) containing element values 252 | # - it : (time) step number 253 | # - t : load factor / time 254 | # NOTE: this function must be called after writing the mesh data 255 | # no attempt is made to check consistency between mesh and field data 256 | # 257 | def gmshOutput_element(out, label, V, it, t): 258 | """Write element field in Gmsh format""" 259 | out.write("$ElementData\n") 260 | out.write("%d\n" % 1) 261 | out.write('"%s"\n' % label) 262 | out.write("%d\n" % 1) 263 | out.write("%f\n" % t) 264 | out.write("%d\n" % 3) 265 | out.write("%d\n" % it) 266 | sz0 = np.shape(V)[1] 267 | if sz0 == 2 or sz0 == 3: 268 | sz1 = 3 269 | elif sz0 > 3: 270 | sz1 = 9 271 | else: 272 | sz1 = 1 273 | out.write("%d\n" % sz1) 274 | out.write("%d\n" % np.shape(V)[0]) 275 | for n in range(np.shape(V)[0]): 276 | out.write("%d" % (n + 1)) 277 | if sz1 == 3: 278 | for i in range(sz0): 279 | out.write(" %13.6e" % V[n][i]) 280 | for i in range(sz0, sz1): 281 | out.write(" %13.6e" % 0.0) 282 | elif sz1 == 9: 283 | if sz0 == 4: 284 | out.write( 285 | " %13.6e %13.6e %13.6e %13.6e %13.6e" 286 | % (V[n][0], V[n][1], 0.0, V[n][2], V[n][3]) 287 | ) 288 | for i in range(4): 289 | out.write(" %13.6e" % 0.0) 290 | else: 291 | for i in range(sz1): 292 | out.write(" %13.6e" % V[n][i]) 293 | out.write("\n") 294 | out.write("$EndElementData\n") 295 | out.flush() 296 | -------------------------------------------------------------------------------- /src/hyper/mesh.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # 3 | # Data structures for unstructured mesh 4 | # 5 | """ 6 | MNMNL Homework 7 | Module 2: nodal field on a mesh 8 | complete code below where indicated by 9 | 10 | ---------------------------- 11 | 12 | Here we have all the definitions of the base elements: 13 | * Nodes 14 | * Elements 15 | * Mesh 16 | And we are going to use it futher 17 | 18 | """ 19 | 20 | 21 | class Node: 22 | """Basic data structure for nodes""" 23 | 24 | def __init__(self, i, x, y, z=None, dim=2): 25 | """Create node of label i and coordinates (x,y,z)""" 26 | self.id = i 27 | if dim == 2 or z is None: 28 | self.X = (x, y) 29 | else: 30 | self.X = (x, y, z) 31 | 32 | def getID(self): 33 | return self.id 34 | 35 | def getX(self, i=None): 36 | if i is None: 37 | return self.X 38 | else: 39 | return self.X[i] 40 | 41 | 42 | class Element: 43 | """Basic data structure for elements""" 44 | 45 | def __init__(self, i, t, n): 46 | """Create element of label i, type t, with list of nodes n""" 47 | self.id = i 48 | self.type = t # 2:Triangle, 3:Quadrangle 49 | self.nodes = [] # list of nodes labels (int) 50 | self.nodes.extend(n) 51 | 52 | def getID(self): 53 | return self.id 54 | 55 | def getType(self): 56 | return self.type 57 | 58 | def getNNodes(self): 59 | return len(self.nodes) 60 | 61 | def getNode(self, i): 62 | return self.nodes[i] 63 | 64 | def getNodes(self): 65 | return self.nodes 66 | 67 | def nNodes(self): 68 | return self.getNNodes() 69 | 70 | 71 | class MeshData: 72 | """Class containing basic data structure for unstructured mesh""" 73 | 74 | def __init__(self, d=2): 75 | """Create mesh of dimension d""" 76 | self.dim = d # dimension of the mesh as an integer, 2 by default 77 | self.nodes = [] # list of all the nodes in the mesh as Node instances 78 | self.elems = ( 79 | [] 80 | ) # list of all the elements in the mesh as Element instances 81 | 82 | def getDimension(self): 83 | # Returns the dimention of the Mesh 84 | return self.dim 85 | 86 | def getDim(self): 87 | return self.getDimension() 88 | 89 | def addNode(self, i, x, y=0.0, z=0.0): 90 | self.nodes.append(Node(i, x, y, z)) 91 | 92 | def getNode(self, i): 93 | return self.nodes[i] 94 | 95 | def getNNodes(self): 96 | return len(self.nodes) 97 | 98 | def addElement(self, i, t, n): 99 | new_element = Element(i, t, n) 100 | self.elems.append(new_element) 101 | 102 | def getElement(self, i): 103 | return self.elems[i] 104 | 105 | def getNElements(self): 106 | return len(self.elems) 107 | 108 | def nNodes(self): 109 | return self.getNNodes() 110 | 111 | def nElements(self): 112 | return self.getNElements() 113 | 114 | 115 | if __name__ == "__main__": 116 | print("You should use it as a libray, not main file") 117 | -------------------------------------------------------------------------------- /src/hyper/plot.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | from matplotlib import pyplot as plt 3 | 4 | 5 | def plot_mesh(mesh, label=None, color=None): 6 | 7 | if label is None: 8 | label = "Mesh" 9 | if color is None: 10 | color = "k" 11 | 12 | show_nodename = False 13 | 14 | nElements = mesh.getNElements() 15 | nNodes = mesh.getNNodes() 16 | X_all = np.zeros(nNodes) 17 | Y_all = np.zeros(nNodes) 18 | all_connections = [] 19 | for i in range(nElements): 20 | elem = mesh.getElement(i) 21 | connections = elem.getNodes() 22 | all_connections.append(connections) 23 | if max([len(c) for c in all_connections]) == 4: 24 | return 25 | for i in range(nNodes): 26 | Nodei = mesh.getNode(i) 27 | X_all[i] = Nodei.getX(0) 28 | Y_all[i] = Nodei.getX(1) 29 | 30 | if show_nodename: 31 | for i in range(nNodes): 32 | txt = str(mesh.getNode(i).id) 33 | txt = str(i) 34 | x = X_all[i] 35 | y = Y_all[i] 36 | plt.annotate(txt, (x, y)) 37 | 38 | plt.triplot(X_all, Y_all, all_connections, color=color, label=label) 39 | plt.axis("equal") 40 | -------------------------------------------------------------------------------- /src/hyper/readme.md: -------------------------------------------------------------------------------- 1 | # Source 2 | 3 | In this folder there are the main files used to make calculus and solve the problem. 4 | 5 | 6 | ### Files 7 | 8 | * The file ```tensor.py``` contains all the tensor operations that we need to solve the problem. It uses ```numpy``` as base library. 9 | * The file ```gmsh2.py``` are responsible for read and writing in the ```.msh```files. As there is a ```gmsh``` python's native library, it could be a problem, so we changed the name. 10 | * The file ```mesh.py``` contains the classes to store the informations of the mesh 11 | + ```Node``` contains the position of the points 12 | + ```Element``` contain the relation of many ```Node``` 13 | + ```MeshData``` storage all the nodes and the elements 14 | * The file ```geometry.py``` that contains all the functions of interpolations and the integrations points. 15 | + The functions of interpolation is explained in [Base Element's Geometry](https://github.com/carlos-adir/Non-linear-mechanics/wiki/Base-Elements'-Geometry) 16 | - Elements T3, T6, Q4 and Q8 17 | + The integrations points are shown in [Gauss Integration Points](https://github.com/carlos-adir/Non-linear-mechanics/wiki/Gauss-Integration-Points) 18 | - In a triangle and in a square. 19 | - Order ```O(1)```, ```O(h)``` and ```O(h^2)``` 20 | * The file ```fem.py``` has the elements to calculate the values of the tensors ```F``` and ```E``` if we already know the value of the displacement field ```u``` of the elements 21 | + ```FiniteElement``` class stores and treat the informations of only one element 22 | + ```FEModel``` class stores and treat the information of all elements 23 | * The file ```elasticity.py``` contains the hyperelastic models of the material. 24 | + ```StVenantKirchhoffElasticity``` class is the [Saint Venant-Kirchhoff][stvenantkirchhoff] model 25 | + ```NeoHookeanElasticity``` class is the [NeoHookean][neohookean] model 26 | * The file ```plot.py``` contains the functions to plot the mesh. It's an alternative to visualize the data instead using the software [Gmsh][gmsh_website]. It's not yet finished. 27 | 28 | ### Architecture 29 | 30 | The relation of import and dependency between the files are: 31 | 32 | architecture 33 | 34 | 35 | [stvenantkirchhoff]: https://en.wikipedia.org/w/index.php?title=Hyperelastic_material&oldid=993354665 36 | [neohookean]: https://en.wikipedia.org/w/index.php?title=Neo-Hookean_solid&oldid=980304435 37 | [gmsh_website]: https://gmsh.info/ -------------------------------------------------------------------------------- /src/hyper/tensor.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # 3 | # @author: Clément Fuchs 4 | # Carlos Adir Ely Murussi Leite 5 | # 6 | # 7 | # Set of methods for manipulating 2nd-order and 4th-order tensors 8 | # 9 | 10 | import numpy as np 11 | import numpy.linalg as la 12 | 13 | ############################################################################### 14 | # Vectors # 15 | ############################################################################### 16 | 17 | 18 | def vector(d=2): 19 | """ 20 | Constructor of a vector object (dimension d) 21 | """ 22 | return np.zeros(d) 23 | 24 | 25 | ############################################################################### 26 | # 2nd Order Tensors # 27 | ############################################################################### 28 | 29 | 30 | def tensor(d=2): 31 | """ 32 | Constructor of 2nd-order tensor (dimension d) 33 | """ 34 | return np.zeros((d, d)) 35 | 36 | 37 | def I(d=2): 38 | """ 39 | Identity second-order tensor 40 | """ 41 | return np.eye(d) 42 | 43 | 44 | def det(A): 45 | """ 46 | Compute determinant of a matrix/tensor 47 | """ 48 | if 1e-13 < np.abs(la.det(A)) < 1e-10: 49 | print("A = ") 50 | print(A) 51 | print("detA = ") 52 | print(la.det(A)) 53 | raise Exception("Not good") 54 | return la.det(A) 55 | 56 | 57 | def inv(A): 58 | """ 59 | Compute inverse of a matrix/tensor 60 | """ 61 | return la.inv(A) 62 | 63 | 64 | def trace(A): 65 | """ 66 | Compute trace of a matrix/tensor 67 | """ 68 | return np.trace(A) 69 | 70 | 71 | def outerProd(a, b): 72 | """ 73 | Compute outer product of two vectors 74 | Mij = ai * bj 75 | """ 76 | return np.tensordot(a, b, axes=0) 77 | 78 | 79 | def rightCauchyGreen(F): 80 | """ 81 | Compute right Cauchy-Green tensor from deformation gradient 82 | """ 83 | FT = np.transpose(F) 84 | C = np.dot(FT, F) 85 | return C 86 | 87 | 88 | def leftCauchyGreen(F): 89 | """ 90 | Compute left Cauchy-Green tensor from deformation gradient 91 | """ 92 | b = np.dot(F, np.transpose(F)) 93 | return b 94 | 95 | 96 | def PK2toPK1(F, S): 97 | """ 98 | Compute Piola stress tensor from second Piola-Kirchhoff stress 99 | """ 100 | # FT = np.transpose(F) 101 | if not check_symmetric(S): 102 | raise Exception("S is not symmetrical") 103 | return np.dot(F, S) 104 | 105 | 106 | def PK1toCauchy(F, P): 107 | """ 108 | Compute Cauchy stress tensor from first Piola-Kirchhoff stress 109 | """ 110 | FT = np.transpose(F) 111 | return np.dot(P, FT) 112 | 113 | 114 | def check_symmetric(a, rtol=1e-05, atol=1e-08): 115 | return np.allclose(a, a.T, rtol=rtol, atol=atol) 116 | 117 | 118 | ############################################################################### 119 | # 4th Order Tensors # 120 | ############################################################################### 121 | 122 | 123 | def tensor4(d=2): 124 | """ 125 | Constructor of 4th-order tensor (dimension d) 126 | """ 127 | return np.zeros((d, d, d, d)) 128 | 129 | 130 | def II(d=2): 131 | """ 132 | Identity fourth-order tensor 133 | II1_ijkl = delta_ik * delta_jl 134 | """ 135 | II1 = tensor4(d) 136 | for i in range(d): 137 | for j in range(d): 138 | II1[i, j, i, j] = 1 139 | return II1 140 | 141 | 142 | def JJ(d=2): 143 | """ 144 | Transpose fourth-order tensor 145 | JJ1_ijkl = delta_il * delta_jk 146 | If we have the tensor A, so 147 | A^T = JJ : A 148 | """ 149 | JJ1 = tensor4(d) 150 | for i in range(d): 151 | for j in range(d): 152 | JJ1[i, j, j, i] = 1 153 | return JJ1 154 | 155 | 156 | def IISym(d=2): 157 | """ 158 | Symmetrical identity fourth - order tensor: 159 | IISym_ijkl = 1 / 2 * (delta_ik delta_jl + delta_il delta_jk) 160 | If we have the 2nd order tensor A: 161 | IISym : A = (A + A^T)/2 162 | """ 163 | return (II(d) + JJ(d)) / 2 164 | 165 | 166 | def KK(d=2): 167 | """ 168 | Spherical operator 169 | """ 170 | S = tensor4(d) 171 | for i in range(d): 172 | for k in range(d): 173 | S[i, i, k, k] = 1 174 | return S 175 | 176 | 177 | def outerProd4(a, b): 178 | """ 179 | Compute outer product of two tensors 180 | M_ijkl = a_ij * b_kl 181 | """ 182 | return np.tensordot(a, b, axes=0) 183 | 184 | 185 | def MaterialToLagrangian(F, S, M): 186 | """ 187 | Compute Lagrangian tangent operator from material tensor and stress 188 | (partial P/partial F)_{iJkL} = delta_{ik}*S_{JL} + F_{iI}*M_{IJKL}*F_{kK} 189 | """ 190 | d, _ = F.shape 191 | dPdF = tensor4(d) 192 | # print("F = " + str(F.shape)) 193 | # print("S = " + str(S.shape)) 194 | # print("M = " + str(M.shape)) 195 | 196 | # value1 = np.einsum('iI,IJKL,kK->iJkL', F, M, F) 197 | dPdF += np.einsum("iI,IJKL,kK->iJkL", F, M, F) 198 | # ident = np.eye(d) 199 | # w = outerProd4(ident, S) 200 | dPdF += np.einsum("ik,JL->iJkL", np.eye(d), S) 201 | 202 | # value1 = np.einsum("ik,JL->iJkL", np.eye(d), S) 203 | # w = outerProd4(np.eye(d), S) 204 | # value2 = tensor4(d) 205 | # # for i in range(d): 206 | # # for k in range(d): 207 | # # for J in range(d): 208 | # # for L in range(d): 209 | # # for I in range(d): 210 | # # for K in range(d): 211 | # # value2[i, J, k, L] += F[i, I] * \ 212 | # # M[I, J, K, L] * F[k, K] 213 | # # print("S = ") 214 | # # print(S) 215 | # for i in range(d): 216 | # for J in range(d): 217 | # for L in range(d): 218 | # for k in range(d): 219 | # if i == k: 220 | # value2[i, J, k, L] += w[i, k, J, L] 221 | 222 | # raise Exception("Stop") 223 | 224 | # Result = np.einsum('ji,j->ji',A,b) 225 | return dPdF 226 | # raise Exception("MaterialToLagrangian: Not implemented") 227 | # return "not implemented" 228 | -------------------------------------------------------------------------------- /tests/__init__.py: -------------------------------------------------------------------------------- 1 | import sys 2 | 3 | sys.path.append("./src") 4 | -------------------------------------------------------------------------------- /tests/geo/compare_residual.geo: -------------------------------------------------------------------------------- 1 | // Given mesh files (reference solution) 2 | //Merge "tests/msh/triangle-tri56-ref.msh"; 3 | Merge "tests/msh/triangle-quad44-ref.msh"; 4 | /* 5 | Solution file first: 6 | view[0] = ref nodal displacement field (U) 7 | view[1] = ref nodal residual field (R) 8 | view[2] = ref element def. gradient field (F) 9 | view[3] = ref element eng. stress field (P) 10 | */ 11 | 12 | // Your mesh files 13 | //Merge "tests/msh/triangle-tri56-val.msh"; 14 | Merge "tests/msh/triangle-quad44-val.msh"; 15 | /* 16 | Your solution second: 17 | view[4] = nodal displacement field (U) 18 | view[5] = nodal residual field (R) 19 | view[6] = element def. gradient field (F) 20 | view[7] = element eng. stress field (P) 21 | */ 22 | 23 | // Apply the view as the current background mesh 24 | Background Mesh View[0]; 25 | For numview In {0:PostProcessing.NbViews-1} 26 | View[numview].Visible = 0; 27 | EndFor 28 | // Compare views 29 | // vector fields : 2D vectors are stored in v0 and v1 components of the view (vi = 0, i>=2) 30 | Plugin(MathEval).TimeStep = -1; 31 | Plugin(MathEval).OtherTimeStep = -1; //If `TimeStep' < 0, the plugin extracts data from all the time steps in the view. 32 | Plugin(MathEval).ForceInterpolation = 0; 33 | Plugin(MathEval).PhysicalRegion = -1; //If `PhysicalRegion' < 0, the plugin is run on all physical regions. 34 | Plugin(MathEval).View = 1; 35 | Plugin(MathEval).OtherView = 5; 36 | Plugin(MathEval).Expression0 = " Fabs(v0 - w0)"; 37 | Plugin(MathEval).Expression1 = " Fabs(v1 - w1)"; 38 | Plugin(MathEval).Run; 39 | View[PostProcessing.NbViews-1].Name = "Absolute error on the residual field"; 40 | // tensor fields : 2D tensors are stored in v0, v1, v3 and v4 components of the view (_11, _12, _21, _22 components respectively) 41 | Plugin(MathEval).TimeStep = -1; 42 | Plugin(MathEval).OtherTimeStep = -1; //If `TimeStep' < 0, the plugin extracts data from all the time steps in the view. 43 | Plugin(MathEval).ForceInterpolation = 0; 44 | Plugin(MathEval).PhysicalRegion = -1; //If `PhysicalRegion' < 0, the plugin is run on all physical regions. 45 | Plugin(MathEval).View = 2; 46 | Plugin(MathEval).OtherView = 6; 47 | Plugin(MathEval).Expression0 = " Fabs(v0 - w0)"; 48 | Plugin(MathEval).Expression1 = " Fabs(v1 - w1)"; 49 | Plugin(MathEval).Expression3 = " Fabs(v3 - w3)"; 50 | Plugin(MathEval).Expression4 = " Fabs(v4 - w4)"; 51 | Plugin(MathEval).Run; 52 | View[PostProcessing.NbViews-1].Name = "Absolute error on the def. gradient field"; 53 | // tensor fields : 2D tensors are stored in v0, v1, v3 and v4 components of the view (_11, _12, _21, _22 components respectively) 54 | Plugin(MathEval).TimeStep = -1; 55 | Plugin(MathEval).OtherTimeStep = -1; //If `TimeStep' < 0, the plugin extracts data from all the time steps in the view. 56 | Plugin(MathEval).ForceInterpolation = 0; 57 | Plugin(MathEval).PhysicalRegion = -1; //If `PhysicalRegion' < 0, the plugin is run on all physical regions. 58 | Plugin(MathEval).View = 3; 59 | Plugin(MathEval).OtherView = 7; 60 | Plugin(MathEval).Expression0 = " Fabs(v0 - w0)"; 61 | Plugin(MathEval).Expression1 = " Fabs(v1 - w1)"; 62 | Plugin(MathEval).Expression3 = " Fabs(v3 - w3)"; 63 | Plugin(MathEval).Expression4 = " Fabs(v4 - w4)"; 64 | Plugin(MathEval).Run; 65 | View[PostProcessing.NbViews-1].Name = "Absolute error on the eng. stress field"; 66 | -------------------------------------------------------------------------------- /tests/msh/meshfile-quad8-ref.msh: -------------------------------------------------------------------------------- 1 | $MeshFormat 2 | 2.2 0 8 3 | $EndMeshFormat 4 | $Nodes 5 | 15 6 | 1 0.000000e+00 0.000000e+00 0.000000 7 | 2 1.000000e+00 0.000000e+00 0.000000 8 | 3 1.000000e+00 3.000000e-01 0.000000 9 | 4 0.000000e+00 3.000000e-01 0.000000 10 | 5 2.500000e-01 0.000000e+00 0.000000 11 | 6 5.000000e-01 0.000000e+00 0.000000 12 | 7 7.500000e-01 0.000000e+00 0.000000 13 | 8 1.000000e+00 1.500000e-01 0.000000 14 | 9 7.500000e-01 3.000000e-01 0.000000 15 | 10 5.000000e-01 3.000000e-01 0.000000 16 | 11 2.500000e-01 3.000000e-01 0.000000 17 | 12 0.000000e+00 1.500000e-01 0.000000 18 | 13 5.000000e-01 1.500000e-01 0.000000 19 | 14 2.500000e-01 1.500000e-01 0.000000 20 | 15 7.500000e-01 1.500000e-01 0.000000 21 | $EndNodes 22 | $Elements 23 | 8 24 | 1 3 2 1 1 4 12 14 11 25 | 2 3 2 1 1 12 1 5 14 26 | 3 3 2 1 1 14 5 6 13 27 | 4 3 2 1 1 11 14 13 10 28 | 5 3 2 1 1 10 13 15 9 29 | 6 3 2 1 1 13 6 7 15 30 | 7 3 2 1 1 15 7 2 8 31 | 8 3 2 1 1 9 15 8 3 32 | $EndElements 33 | $NodeData 34 | 1 35 | "ref scalar field" 36 | 1 37 | 0.000000 38 | 3 39 | 0 40 | 1 41 | 15 42 | 1 0.000000e+00 43 | 2 1.000000e+00 44 | 3 1.090000e+00 45 | 4 9.000000e-02 46 | 5 6.250000e-02 47 | 6 2.500000e-01 48 | 7 5.625000e-01 49 | 8 1.022500e+00 50 | 9 6.525000e-01 51 | 10 3.400000e-01 52 | 11 1.525000e-01 53 | 12 2.250000e-02 54 | 13 2.725000e-01 55 | 14 8.500000e-02 56 | 15 5.850000e-01 57 | $EndNodeData 58 | $NodeData 59 | 1 60 | "ref vector field" 61 | 1 62 | 0.000000 63 | 3 64 | 0 65 | 3 66 | 15 67 | 1 0.000000e+00 -0.000000e+00 0.000000e+00 68 | 2 2.000000e+00 -0.000000e+00 0.000000e+00 69 | 3 2.000000e+00 -6.000000e-02 0.000000e+00 70 | 4 0.000000e+00 -6.000000e-02 0.000000e+00 71 | 5 5.000000e-01 -0.000000e+00 0.000000e+00 72 | 6 1.000000e+00 -0.000000e+00 0.000000e+00 73 | 7 1.500000e+00 -0.000000e+00 0.000000e+00 74 | 8 2.000000e+00 -3.000000e-02 0.000000e+00 75 | 9 1.500000e+00 -6.000000e-02 0.000000e+00 76 | 10 1.000000e+00 -6.000000e-02 0.000000e+00 77 | 11 5.000000e-01 -6.000000e-02 0.000000e+00 78 | 12 0.000000e+00 -3.000000e-02 0.000000e+00 79 | 13 1.000000e+00 -3.000000e-02 0.000000e+00 80 | 14 5.000000e-01 -3.000000e-02 0.000000e+00 81 | 15 1.500000e+00 -3.000000e-02 0.000000e+00 82 | $EndNodeData 83 | -------------------------------------------------------------------------------- /tests/msh/meshfile-quad8.msh: -------------------------------------------------------------------------------- 1 | $MeshFormat 2 | 4 0 8 3 | $EndMeshFormat 4 | $Entities 5 | 4 4 1 0 6 | 1 0 0 0 0 0 0 0 7 | 2 1 0 0 1 0 0 0 8 | 3 1 0.3 0 1 0.3 0 0 9 | 4 0 0.3 0 0 0.3 0 0 10 | 1 0 0 0 1 0 0 0 2 1 -2 11 | 2 1 0 0 1 0.3 0 0 2 2 -3 12 | 3 0 0.3 0 1 0.3 0 0 2 3 -4 13 | 4 0 0 0 0 0.3 0 0 2 4 -1 14 | 1 0 0 0 1 0.3 0 0 4 4 1 2 3 15 | $EndEntities 16 | $Nodes 17 | 9 15 18 | 1 0 0 1 19 | 1 0 0 0 20 | 2 0 0 1 21 | 2 1 0 0 22 | 3 0 0 1 23 | 3 1 0.3 0 24 | 4 0 0 1 25 | 4 0 0.3 0 26 | 1 1 0 3 27 | 7 0.2499999999994194 0 0 28 | 5 0.499999999998694 0 0 29 | 8 0.749999999999347 0 0 30 | 2 1 0 1 31 | 9 1 0.1499999999996522 0 32 | 3 1 0 3 33 | 10 0.7500000000009891 0.3 0 34 | 6 0.5000000000020591 0.3 0 35 | 11 0.2500000000010296 0.3 0 36 | 4 1 0 1 37 | 12 0 0.1500000000002887 0 38 | 1 2 0 3 39 | 13 0.5000000000003766 0.15 0 40 | 14 0.2500000000002245 0.1500000000001444 0 41 | 15 0.7500000000001681 0.1499999999998261 0 42 | $EndNodes 43 | $Elements 44 | 9 24 45 | 1 0 15 1 46 | 1 1 47 | 2 0 15 1 48 | 2 2 49 | 3 0 15 1 50 | 3 3 51 | 4 0 15 1 52 | 4 4 53 | 1 1 1 4 54 | 21 1 7 55 | 22 7 5 56 | 23 5 8 57 | 24 8 2 58 | 2 1 1 2 59 | 25 2 9 60 | 26 9 3 61 | 3 1 1 4 62 | 27 3 10 63 | 28 10 6 64 | 29 6 11 65 | 30 11 4 66 | 4 1 1 2 67 | 31 4 12 68 | 32 12 1 69 | 1 2 3 8 70 | 33 4 12 14 11 71 | 34 12 1 7 14 72 | 35 14 7 5 13 73 | 36 11 14 13 6 74 | 37 6 13 15 10 75 | 38 13 5 8 15 76 | 39 15 8 2 9 77 | 40 10 15 9 3 78 | $EndElements 79 | -------------------------------------------------------------------------------- /tests/msh/meshfile-tri8-ref.msh: -------------------------------------------------------------------------------- 1 | $MeshFormat 2 | 2.2 0 8 3 | $EndMeshFormat 4 | $Nodes 5 | 8 6 | 1 0.000000e+00 0.000000e+00 0.000000 7 | 2 1.000000e+00 0.000000e+00 0.000000 8 | 3 1.000000e+00 3.000000e-01 0.000000 9 | 4 0.000000e+00 3.000000e-01 0.000000 10 | 5 5.000000e-01 0.000000e+00 0.000000 11 | 6 5.000000e-01 3.000000e-01 0.000000 12 | 7 2.500000e-01 1.500000e-01 0.000000 13 | 8 7.500000e-01 1.500000e-01 0.000000 14 | $EndNodes 15 | $Elements 16 | 8 17 | 1 2 2 1 1 5 6 7 18 | 2 2 2 1 1 6 5 8 19 | 3 2 2 1 1 4 1 7 20 | 4 2 2 1 1 2 3 8 21 | 5 2 2 1 1 1 5 7 22 | 6 2 2 1 1 5 2 8 23 | 7 2 2 1 1 3 6 8 24 | 8 2 2 1 1 6 4 7 25 | $EndElements 26 | $NodeData 27 | 1 28 | "ref scalar field" 29 | 1 30 | 0.000000 31 | 3 32 | 0 33 | 1 34 | 8 35 | 1 0.000000e+00 36 | 2 1.000000e+00 37 | 3 1.090000e+00 38 | 4 9.000000e-02 39 | 5 2.500000e-01 40 | 6 3.400000e-01 41 | 7 8.500000e-02 42 | 8 5.850000e-01 43 | $EndNodeData 44 | $NodeData 45 | 1 46 | "ref vector field" 47 | 1 48 | 0.000000 49 | 3 50 | 0 51 | 3 52 | 8 53 | 1 0.000000e+00 -0.000000e+00 0.000000e+00 54 | 2 2.000000e+00 -0.000000e+00 0.000000e+00 55 | 3 2.000000e+00 -6.000000e-02 0.000000e+00 56 | 4 0.000000e+00 -6.000000e-02 0.000000e+00 57 | 5 1.000000e+00 -0.000000e+00 0.000000e+00 58 | 6 1.000000e+00 -6.000000e-02 0.000000e+00 59 | 7 5.000000e-01 -3.000000e-02 0.000000e+00 60 | 8 1.500000e+00 -3.000000e-02 0.000000e+00 61 | $EndNodeData 62 | -------------------------------------------------------------------------------- /tests/msh/meshfile-tri8.msh: -------------------------------------------------------------------------------- 1 | $MeshFormat 2 | 4 0 8 3 | $EndMeshFormat 4 | $Entities 5 | 4 4 1 0 6 | 1 0 0 0 0 0 0 0 7 | 2 1 0 0 1 0 0 0 8 | 3 1 0.3 0 1 0.3 0 0 9 | 4 0 0.3 0 0 0.3 0 0 10 | 1 0 0 0 1 0 0 0 2 1 -2 11 | 2 1 0 0 1 0.3 0 0 2 2 -3 12 | 3 0 0.3 0 1 0.3 0 0 2 3 -4 13 | 4 0 0 0 0 0.3 0 0 2 4 -1 14 | 1 0 0 0 1 0.3 0 0 4 4 1 2 3 15 | $EndEntities 16 | $Nodes 17 | 9 8 18 | 1 0 0 1 19 | 1 0 0 0 20 | 2 0 0 1 21 | 2 1 0 0 22 | 3 0 0 1 23 | 3 1 0.3 0 24 | 4 0 0 1 25 | 4 0 0.3 0 26 | 1 1 0 1 27 | 5 0.499999999998694 0 0 28 | 2 1 0 0 29 | 3 1 0 1 30 | 6 0.5000000000020591 0.3 0 31 | 4 1 0 0 32 | 1 2 0 2 33 | 7 0.2500000000001883 0.15 0 34 | 8 0.7500000000001883 0.15 0 35 | $EndNodes 36 | $Elements 37 | 9 18 38 | 1 0 15 1 39 | 1 1 40 | 2 0 15 1 41 | 2 2 42 | 3 0 15 1 43 | 3 3 44 | 4 0 15 1 45 | 4 4 46 | 1 1 1 2 47 | 5 1 5 48 | 6 5 2 49 | 2 1 1 1 50 | 7 2 3 51 | 3 1 1 2 52 | 8 3 6 53 | 9 6 4 54 | 4 1 1 1 55 | 10 4 1 56 | 1 2 2 8 57 | 11 5 6 7 58 | 12 6 5 8 59 | 13 4 1 7 60 | 14 2 3 8 61 | 15 1 5 7 62 | 16 5 2 8 63 | 17 3 6 8 64 | 18 6 4 7 65 | $EndElements 66 | -------------------------------------------------------------------------------- /tests/msh/triangle-quad11.msh: -------------------------------------------------------------------------------- 1 | $MeshFormat 2 | 4 0 8 3 | $EndMeshFormat 4 | $Entities 5 | 3 3 1 0 6 | 1 0 0 0 0 0 0 0 7 | 2 1 1 0 1 1 0 0 8 | 3 1 -1 0 1 -1 0 0 9 | 1 0 0 0 1 1 0 0 2 1 -2 10 | 2 1 -1 0 1 1 0 0 2 2 -3 11 | 3 0 -1 0 1 0 0 0 2 3 -1 12 | 1 0 -1 0 1 1 0 0 3 1 2 3 13 | $EndEntities 14 | $Nodes 15 | 7 16 16 | 1 0 0 1 17 | 1 0 0 0 18 | 2 0 0 1 19 | 2 1 1 0 20 | 3 0 0 1 21 | 3 1 -1 0 22 | 1 1 0 3 23 | 4 0.2499999999994115 0.2499999999994115 0 24 | 5 0.4999999999986928 0.4999999999986928 0 25 | 6 0.7499999999993409 0.7499999999993409 0 26 | 2 1 0 3 27 | 7 1 0.5000000000013871 0 28 | 8 1 2.752797989558076e-12 0 29 | 9 1 -0.4999999999986129 0 30 | 3 1 0 3 31 | 10 0.7500000000003473 -0.7500000000003473 0 32 | 11 0.5000000000020606 -0.5000000000020606 0 33 | 12 0.2500000000010412 -0.2500000000010412 0 34 | 1 2 0 4 35 | 13 0.6665104760064872 5.545182368837942e-13 0 36 | 14 0.6836179339733084 0.369365717684617 0 37 | 15 0.6836179339739235 -0.3693657176842984 0 38 | 16 0.4080026808247026 -2.154840574236846e-13 0 39 | $EndNodes 40 | $Elements 41 | 8 26 42 | 1 0 15 1 43 | 1 1 44 | 2 0 15 1 45 | 2 2 46 | 3 0 15 1 47 | 3 3 48 | 1 1 1 4 49 | 4 1 4 50 | 5 4 5 51 | 6 5 6 52 | 7 6 2 53 | 2 1 1 4 54 | 8 2 7 55 | 9 7 8 56 | 10 8 9 57 | 11 9 3 58 | 3 1 1 4 59 | 12 3 10 60 | 13 10 11 61 | 14 11 12 62 | 15 12 1 63 | 1 2 2 4 64 | 16 15 10 11 65 | 17 11 12 15 66 | 18 5 6 14 67 | 19 14 4 5 68 | 1 2 3 7 69 | 20 14 13 16 4 70 | 21 15 12 16 13 71 | 22 9 15 13 8 72 | 23 7 8 13 14 73 | 24 12 1 4 16 74 | 25 14 6 2 7 75 | 26 15 9 3 10 76 | $EndElements 77 | -------------------------------------------------------------------------------- /tests/msh/triangle-quad44-ref.msh: -------------------------------------------------------------------------------- 1 | $MeshFormat 2 | 2.2 0 8 3 | $EndMeshFormat 4 | $Nodes 5 | 49 6 | 1 0.000000e+00 0.000000e+00 0.000000 7 | 2 1.000000e+00 1.000000e+00 0.000000 8 | 3 1.000000e+00 -1.000000e+00 0.000000 9 | 4 1.250000e-01 1.250000e-01 0.000000 10 | 5 2.500000e-01 2.500000e-01 0.000000 11 | 6 3.750000e-01 3.750000e-01 0.000000 12 | 7 5.000000e-01 5.000000e-01 0.000000 13 | 8 6.250000e-01 6.250000e-01 0.000000 14 | 9 7.500000e-01 7.500000e-01 0.000000 15 | 10 8.750000e-01 8.750000e-01 0.000000 16 | 11 1.000000e+00 7.500000e-01 0.000000 17 | 12 1.000000e+00 5.000000e-01 0.000000 18 | 13 1.000000e+00 2.500000e-01 0.000000 19 | 14 1.000000e+00 2.752798e-12 0.000000 20 | 15 1.000000e+00 -2.500000e-01 0.000000 21 | 16 1.000000e+00 -5.000000e-01 0.000000 22 | 17 1.000000e+00 -7.500000e-01 0.000000 23 | 18 8.750000e-01 -8.750000e-01 0.000000 24 | 19 7.500000e-01 -7.500000e-01 0.000000 25 | 20 6.250000e-01 -6.250000e-01 0.000000 26 | 21 5.000000e-01 -5.000000e-01 0.000000 27 | 22 3.750000e-01 -3.750000e-01 0.000000 28 | 23 2.500000e-01 -2.500000e-01 0.000000 29 | 24 1.250000e-01 -1.250000e-01 0.000000 30 | 25 6.665105e-01 5.545182e-13 0.000000 31 | 26 6.836179e-01 3.693657e-01 0.000000 32 | 27 6.836179e-01 -3.693657e-01 0.000000 33 | 28 4.080027e-01 -2.154841e-13 0.000000 34 | 29 7.168090e-01 -5.596829e-01 0.000000 35 | 30 5.918090e-01 -4.346829e-01 0.000000 36 | 31 4.668090e-01 -3.096829e-01 0.000000 37 | 32 7.168090e-01 5.596829e-01 0.000000 38 | 33 5.918090e-01 4.346829e-01 0.000000 39 | 34 4.668090e-01 3.096829e-01 0.000000 40 | 35 6.750642e-01 1.846829e-01 0.000000 41 | 36 5.372566e-01 1.695171e-13 0.000000 42 | 37 3.290013e-01 1.250000e-01 0.000000 43 | 38 5.020328e-01 1.548414e-01 0.000000 44 | 39 3.290013e-01 -1.250000e-01 0.000000 45 | 40 6.750642e-01 -1.846829e-01 0.000000 46 | 41 5.020328e-01 -1.548414e-01 0.000000 47 | 42 8.418090e-01 -4.346829e-01 0.000000 48 | 43 8.332552e-01 1.653658e-12 0.000000 49 | 44 8.375321e-01 -2.173414e-01 0.000000 50 | 45 8.418090e-01 4.346829e-01 0.000000 51 | 46 8.375321e-01 2.173414e-01 0.000000 52 | 47 2.270007e-01 -4.264297e-13 0.000000 53 | 48 8.584045e-01 6.548414e-01 0.000000 54 | 49 8.584045e-01 -6.548414e-01 0.000000 55 | $EndNodes 56 | $Elements 57 | 44 58 | 1 2 2 1 1 27 29 30 59 | 2 2 2 1 1 29 20 30 60 | 3 2 2 1 1 29 19 20 61 | 4 2 2 1 1 30 20 21 62 | 5 2 2 1 1 21 22 30 63 | 6 2 2 1 1 22 31 30 64 | 7 2 2 1 1 22 23 31 65 | 8 2 2 1 1 30 31 27 66 | 9 2 2 1 1 7 8 33 67 | 10 2 2 1 1 8 32 33 68 | 11 2 2 1 1 8 9 32 69 | 12 2 2 1 1 33 32 26 70 | 13 2 2 1 1 26 34 33 71 | 14 2 2 1 1 34 6 33 72 | 15 2 2 1 1 34 5 6 73 | 16 2 2 1 1 33 6 7 74 | 17 3 2 1 1 26 35 38 34 75 | 18 3 2 1 1 35 25 36 38 76 | 19 3 2 1 1 38 36 28 37 77 | 20 3 2 1 1 34 38 37 5 78 | 21 3 2 1 1 27 31 41 40 79 | 22 3 2 1 1 31 23 39 41 80 | 23 3 2 1 1 41 39 28 36 81 | 24 3 2 1 1 40 41 36 25 82 | 25 3 2 1 1 16 42 44 15 83 | 26 3 2 1 1 42 27 40 44 84 | 27 3 2 1 1 44 40 25 43 85 | 28 3 2 1 1 15 44 43 14 86 | 29 3 2 1 1 12 13 46 45 87 | 30 3 2 1 1 13 14 43 46 88 | 31 3 2 1 1 46 43 25 35 89 | 32 3 2 1 1 45 46 35 26 90 | 33 3 2 1 1 23 24 47 39 91 | 34 3 2 1 1 24 1 4 47 92 | 35 3 2 1 1 47 4 5 37 93 | 36 3 2 1 1 39 47 37 28 94 | 37 3 2 1 1 26 32 48 45 95 | 38 3 2 1 1 32 9 10 48 96 | 39 3 2 1 1 48 10 2 11 97 | 40 3 2 1 1 45 48 11 12 98 | 41 3 2 1 1 27 42 49 29 99 | 42 3 2 1 1 42 16 17 49 100 | 43 3 2 1 1 49 17 3 18 101 | 44 3 2 1 1 29 49 18 19 102 | $EndElements 103 | $NodeData 104 | 1 105 | "ref displacement" 106 | 1 107 | 0.000000 108 | 3 109 | 0 110 | 3 111 | 49 112 | 1 0.000000e+00 0.000000e+00 0.000000e+00 113 | 2 1.000000e+00 1.000000e+00 0.000000e+00 114 | 3 -1.000000e+00 -1.000000e+00 0.000000e+00 115 | 4 1.562500e-02 1.562500e-02 0.000000e+00 116 | 5 6.250000e-02 6.250000e-02 0.000000e+00 117 | 6 1.406250e-01 1.406250e-01 0.000000e+00 118 | 7 2.500000e-01 2.500000e-01 0.000000e+00 119 | 8 3.906250e-01 3.906250e-01 0.000000e+00 120 | 9 5.625000e-01 5.625000e-01 0.000000e+00 121 | 10 7.656250e-01 7.656250e-01 0.000000e+00 122 | 11 7.500000e-01 7.500000e-01 0.000000e+00 123 | 12 5.000000e-01 5.000000e-01 0.000000e+00 124 | 13 2.500000e-01 2.500000e-01 0.000000e+00 125 | 14 2.752798e-12 2.752798e-12 0.000000e+00 126 | 15 -2.500000e-01 -2.500000e-01 0.000000e+00 127 | 16 -5.000000e-01 -5.000000e-01 0.000000e+00 128 | 17 -7.500000e-01 -7.500000e-01 0.000000e+00 129 | 18 -7.656250e-01 -7.656250e-01 0.000000e+00 130 | 19 -5.625000e-01 -5.625000e-01 0.000000e+00 131 | 20 -3.906250e-01 -3.906250e-01 0.000000e+00 132 | 21 -2.500000e-01 -2.500000e-01 0.000000e+00 133 | 22 -1.406250e-01 -1.406250e-01 0.000000e+00 134 | 23 -6.250000e-02 -6.250000e-02 0.000000e+00 135 | 24 -1.562500e-02 -1.562500e-02 0.000000e+00 136 | 25 3.695922e-13 3.695922e-13 0.000000e+00 137 | 26 2.525050e-01 2.525050e-01 0.000000e+00 138 | 27 -2.525050e-01 -2.525050e-01 0.000000e+00 139 | 28 -8.791807e-14 -8.791807e-14 0.000000e+00 140 | 29 -4.011857e-01 -4.011857e-01 0.000000e+00 141 | 30 -2.572492e-01 -2.572492e-01 0.000000e+00 142 | 31 -1.445627e-01 -1.445627e-01 0.000000e+00 143 | 32 4.011857e-01 4.011857e-01 0.000000e+00 144 | 33 2.572492e-01 2.572492e-01 0.000000e+00 145 | 34 1.445627e-01 1.445627e-01 0.000000e+00 146 | 35 1.246728e-01 1.246728e-01 0.000000e+00 147 | 36 9.107417e-14 9.107417e-14 0.000000e+00 148 | 37 4.112517e-02 4.112517e-02 0.000000e+00 149 | 38 7.773547e-02 7.773547e-02 0.000000e+00 150 | 39 -4.112517e-02 -4.112517e-02 0.000000e+00 151 | 40 -1.246728e-01 -1.246728e-01 0.000000e+00 152 | 41 -7.773547e-02 -7.773547e-02 0.000000e+00 153 | 42 -3.659199e-01 -3.659199e-01 0.000000e+00 154 | 43 1.377919e-12 1.377919e-12 0.000000e+00 155 | 44 -1.820304e-01 -1.820304e-01 0.000000e+00 156 | 45 3.659199e-01 3.659199e-01 0.000000e+00 157 | 46 1.820304e-01 1.820304e-01 0.000000e+00 158 | 47 -9.679983e-14 -9.679983e-14 0.000000e+00 159 | 48 5.621188e-01 5.621188e-01 0.000000e+00 160 | 49 -5.621188e-01 -5.621188e-01 0.000000e+00 161 | $EndNodeData 162 | $NodeData 163 | 1 164 | "ref residual" 165 | 1 166 | 0.000000 167 | 3 168 | 0 169 | 3 170 | 49 171 | 1 4.569169e+05 -2.875830e+03 0.000000e+00 172 | 2 -1.334700e+06 -1.171257e+06 0.000000e+00 173 | 3 6.110357e+05 4.591794e+05 0.000000e+00 174 | 4 1.139163e+06 -6.469754e+05 0.000000e+00 175 | 5 1.716599e+06 -1.454842e+06 0.000000e+00 176 | 6 2.217465e+06 -2.106283e+06 0.000000e+00 177 | 7 2.707081e+06 -2.638791e+06 0.000000e+00 178 | 8 3.161088e+06 -3.124522e+06 0.000000e+00 179 | 9 3.570775e+06 -3.546153e+06 0.000000e+00 180 | 10 3.922892e+06 -3.918935e+06 0.000000e+00 181 | 11 -6.564299e+06 1.909050e+06 0.000000e+00 182 | 12 -6.242383e+06 2.081718e+06 0.000000e+00 183 | 13 -5.816644e+06 2.205394e+06 0.000000e+00 184 | 14 -5.223102e+06 2.251425e+06 0.000000e+00 185 | 15 -4.351558e+06 2.166808e+06 0.000000e+00 186 | 16 -3.007721e+06 1.856749e+06 0.000000e+00 187 | 17 -7.786426e+05 1.119474e+06 0.000000e+00 188 | 18 3.246608e+05 4.937182e+05 0.000000e+00 189 | 19 -4.402568e+05 6.705984e+05 0.000000e+00 190 | 20 1.465138e+05 4.569477e+05 0.000000e+00 191 | 21 1.973496e+05 3.703819e+05 0.000000e+00 192 | 22 2.153904e+05 3.862816e+05 0.000000e+00 193 | 23 5.746405e+05 5.047180e+05 0.000000e+00 194 | 24 4.085803e+05 4.541919e+05 0.000000e+00 195 | 25 3.329776e+05 6.008065e+04 0.000000e+00 196 | 26 1.202964e+05 5.073088e+04 0.000000e+00 197 | 27 9.217643e+05 -1.774027e+04 0.000000e+00 198 | 28 2.430028e+05 1.029551e+05 0.000000e+00 199 | 29 1.350956e+06 -2.067385e+05 0.000000e+00 200 | 30 8.951360e+05 3.209321e+03 0.000000e+00 201 | 31 9.682681e+05 1.816749e+05 0.000000e+00 202 | 32 3.454749e+04 2.064937e+04 0.000000e+00 203 | 33 7.080559e+04 5.076818e+04 0.000000e+00 204 | 34 1.739680e+05 8.421969e+04 0.000000e+00 205 | 35 1.850460e+05 6.778974e+04 0.000000e+00 206 | 36 3.345318e+05 9.900181e+04 0.000000e+00 207 | 37 3.322288e+05 2.154554e+05 0.000000e+00 208 | 38 2.551397e+05 1.204400e+05 0.000000e+00 209 | 39 6.626050e+05 2.368728e+05 0.000000e+00 210 | 40 6.054374e+05 3.169751e+04 0.000000e+00 211 | 41 6.409044e+05 1.246934e+05 0.000000e+00 212 | 42 9.336437e+05 -1.213956e+05 0.000000e+00 213 | 43 3.090644e+05 2.523714e+04 0.000000e+00 214 | 44 5.456378e+05 -1.833916e+04 0.000000e+00 215 | 45 8.488217e+04 3.277865e+04 0.000000e+00 216 | 46 1.677347e+05 3.647058e+04 0.000000e+00 217 | 47 5.966567e+05 3.663515e+05 0.000000e+00 218 | 48 3.517902e+04 2.011759e+04 0.000000e+00 219 | 49 1.588742e+06 -3.429833e+05 0.000000e+00 220 | $EndNodeData 221 | $ElementData 222 | 1 223 | "ref deformation gradient" 224 | 1 225 | 0.000000 226 | 3 227 | 0 228 | 9 229 | 44 230 | 1 5.515197e-01 7.030115e-01 0.000000e+00 -4.484803e-01 1.703011e+00 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 231 | 2 4.541146e-01 6.056064e-01 0.000000e+00 -5.458854e-01 1.605606e+00 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 232 | 3 3.612025e-01 7.362025e-01 0.000000e+00 -6.387975e-01 1.736203e+00 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 233 | 4 4.862025e-01 6.112025e-01 0.000000e+00 -5.137975e-01 1.611203e+00 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 234 | 5 5.901272e-01 4.651272e-01 0.000000e+00 -4.098728e-01 1.465127e+00 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 235 | 6 6.001899e-01 5.016817e-01 0.000000e+00 -3.998101e-01 1.501682e+00 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 236 | 7 7.151272e-01 3.401272e-01 0.000000e+00 -2.848728e-01 1.340127e+00 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 237 | 8 6.554444e-01 5.569362e-01 0.000000e+00 -3.445556e-01 1.556936e+00 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 238 | 9 1.513797e+00 6.112025e-01 0.000000e+00 5.137975e-01 1.611203e+00 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 239 | 10 1.545885e+00 6.056064e-01 0.000000e+00 5.458854e-01 1.605606e+00 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 240 | 11 1.638797e+00 7.362025e-01 0.000000e+00 6.387975e-01 1.736203e+00 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 241 | 12 1.448480e+00 7.030115e-01 0.000000e+00 4.484803e-01 1.703011e+00 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 242 | 13 1.344556e+00 5.569362e-01 0.000000e+00 3.445556e-01 1.556936e+00 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 243 | 14 1.399810e+00 5.016817e-01 0.000000e+00 3.998101e-01 1.501682e+00 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 244 | 15 1.284873e+00 3.401272e-01 0.000000e+00 2.848728e-01 1.340127e+00 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 245 | 16 1.409873e+00 4.651272e-01 0.000000e+00 4.098728e-01 1.465127e+00 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 246 | 17 1.258197e+00 5.917946e-01 0.000000e+00 2.581971e-01 1.591795e+00 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 247 | 18 1.091710e+00 6.014996e-01 0.000000e+00 9.171028e-02 1.601500e+00 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 248 | 19 1.072536e+00 4.522236e-01 0.000000e+00 7.253551e-02 1.452224e+00 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 249 | 20 1.210041e+00 3.990233e-01 0.000000e+00 2.100412e-01 1.399023e+00 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 250 | 21 7.418029e-01 5.917946e-01 0.000000e+00 -2.581971e-01 1.591795e+00 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 251 | 22 7.899588e-01 3.990233e-01 0.000000e+00 -2.100412e-01 1.399023e+00 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 252 | 23 9.274645e-01 4.522236e-01 0.000000e+00 -7.253551e-02 1.452224e+00 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 253 | 24 9.082897e-01 6.014996e-01 0.000000e+00 -9.171028e-02 1.601500e+00 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 254 | 25 6.514381e-01 9.232840e-01 0.000000e+00 -3.485619e-01 1.923284e+00 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 255 | 26 7.001545e-01 7.635181e-01 0.000000e+00 -2.998455e-01 1.763518e+00 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 256 | 27 9.003696e-01 7.574552e-01 0.000000e+00 -9.963040e-02 1.757455e+00 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 257 | 28 8.844060e-01 9.214456e-01 0.000000e+00 -1.155940e-01 1.921446e+00 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 258 | 29 1.348562e+00 9.232840e-01 0.000000e+00 3.485619e-01 1.923284e+00 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 259 | 30 1.115594e+00 9.214456e-01 0.000000e+00 1.155940e-01 1.921446e+00 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 260 | 31 1.099630e+00 7.574552e-01 0.000000e+00 9.963040e-02 1.757455e+00 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 261 | 32 1.299845e+00 7.635181e-01 0.000000e+00 2.998455e-01 1.763518e+00 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 262 | 33 8.752659e-01 2.385248e-01 0.000000e+00 -1.247341e-01 1.238525e+00 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 263 | 34 1.000000e+00 1.250000e-01 0.000000e+00 -1.882275e-13 1.125000e+00 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 264 | 35 1.124734e+00 2.385248e-01 0.000000e+00 1.247341e-01 1.238525e+00 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 265 | 36 1.000000e+00 3.290013e-01 0.000000e+00 -3.201484e-13 1.329001e+00 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 266 | 37 1.502061e+00 7.766134e-01 0.000000e+00 5.020613e-01 1.776613e+00 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 267 | 38 1.708134e+00 7.999926e-01 0.000000e+00 7.081343e-01 1.799993e+00 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 268 | 39 1.815655e+00 9.336079e-01 0.000000e+00 8.156554e-01 1.933608e+00 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 269 | 40 1.580457e+00 9.264151e-01 0.000000e+00 5.804575e-01 1.926415e+00 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 270 | 41 4.979387e-01 7.766134e-01 0.000000e+00 -5.020613e-01 1.776613e+00 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 271 | 42 4.195425e-01 9.264151e-01 0.000000e+00 -5.804575e-01 1.926415e+00 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 272 | 43 1.843446e-01 9.336079e-01 0.000000e+00 -8.156554e-01 1.933608e+00 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 273 | 44 2.918657e-01 7.999926e-01 0.000000e+00 -7.081343e-01 1.799993e+00 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 274 | $EndElementData 275 | $ElementData 276 | 1 277 | "ref engineering stress" 278 | 1 279 | 0.000000 280 | 3 281 | 0 282 | 9 283 | 44 284 | 1 6.774039e+06 3.707262e+06 0.000000e+00 -3.557772e+06 7.450329e+06 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 285 | 2 -9.311573e+05 1.239327e+06 0.000000e+00 -9.405127e+05 4.830326e+06 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 286 | 3 3.537416e+05 2.210517e+06 0.000000e+00 -1.824606e+06 5.801377e+06 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 287 | 4 8.489812e+05 1.843688e+06 0.000000e+00 -1.457777e+06 5.306137e+06 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 288 | 5 -4.353136e+05 9.128330e+05 0.000000e+00 -6.291401e+05 4.057196e+06 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 289 | 6 1.473220e+06 1.571150e+06 0.000000e+00 -1.179410e+06 4.939844e+06 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 290 | 7 2.064735e+05 6.925511e+05 0.000000e+00 -4.088583e+05 3.415409e+06 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 291 | 8 5.507280e+06 2.639071e+06 0.000000e+00 -2.349662e+06 6.735732e+06 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 292 | 9 2.034228e+07 -2.714761e+06 0.000000e+00 -3.964857e+06 1.976394e+07 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 293 | 10 2.050179e+07 -3.069698e+06 0.000000e+00 -3.839928e+06 2.014343e+07 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 294 | 11 2.275461e+07 -3.754258e+06 0.000000e+00 -5.049689e+06 2.213094e+07 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 295 | 12 2.108628e+07 -1.813451e+06 0.000000e+00 -5.096175e+06 1.955894e+07 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 296 | 13 1.814302e+07 -1.068595e+06 0.000000e+00 -3.643370e+06 1.703294e+07 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 297 | 14 1.785421e+07 -1.738467e+06 0.000000e+00 -2.973498e+06 1.732174e+07 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 298 | 15 1.401288e+07 -8.640680e+05 0.000000e+00 -1.449686e+06 1.380833e+07 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 299 | 16 1.741114e+07 -1.906869e+06 0.000000e+00 -2.570682e+06 1.712840e+07 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 300 | 17 1.777633e+07 -1.456222e+05 0.000000e+00 -4.112567e+06 1.611006e+07 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 301 | 18 1.592670e+07 1.363597e+06 0.000000e+00 -4.259225e+06 1.381967e+07 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 302 | 19 1.284201e+07 1.087063e+06 0.000000e+00 -2.612046e+06 1.176144e+07 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 303 | 20 1.398546e+07 -1.036181e+05 0.000000e+00 -2.087329e+06 1.330507e+07 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 304 | 21 8.984879e+06 3.035146e+06 0.000000e+00 -3.310001e+06 8.501744e+06 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 305 | 22 4.903883e+06 1.671096e+06 0.000000e+00 -1.380515e+06 6.052717e+06 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 306 | 23 1.004910e+07 1.888869e+06 0.000000e+00 -2.395905e+06 9.383356e+06 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 307 | 24 1.298389e+07 2.616112e+06 0.000000e+00 -4.026911e+06 1.112162e+07 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 308 | 25 1.511992e+07 5.466126e+06 0.000000e+00 -7.394517e+06 1.103063e+07 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 309 | 26 1.237275e+07 4.271665e+06 0.000000e+00 -5.363941e+06 1.007068e+07 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 310 | 27 1.601295e+07 3.316430e+06 0.000000e+00 -5.917317e+06 1.269014e+07 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 311 | 28 1.883288e+07 4.101711e+06 0.000000e+00 -7.974219e+06 1.390894e+07 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 312 | 29 2.327059e+07 -1.976170e+05 0.000000e+00 -7.738232e+06 1.969358e+07 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 313 | 30 2.138805e+07 2.109456e+06 0.000000e+00 -8.016561e+06 1.681963e+07 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 314 | 31 1.867454e+07 1.754893e+06 0.000000e+00 -6.075763e+06 1.538061e+07 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 315 | 32 2.072785e+07 -1.369360e+05 0.000000e+00 -6.001928e+06 1.806060e+07 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 316 | 33 2.900880e+06 8.097075e+05 0.000000e+00 -4.080461e+05 4.188360e+06 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 317 | 34 3.655336e+06 4.310345e+05 0.000000e+00 -2.300664e+04 4.063363e+06 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 318 | 35 9.481889e+06 2.577803e+05 0.000000e+00 -6.492554e+05 9.359617e+06 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 319 | 36 8.827069e+06 1.134487e+06 0.000000e+00 -1.331549e+06 8.630008e+06 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 320 | 37 2.240554e+07 -2.195572e+06 0.000000e+00 -5.799387e+06 2.069518e+07 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 321 | 38 2.388535e+07 -4.325073e+06 0.000000e+00 -5.555896e+06 2.328803e+07 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 322 | 39 2.590177e+07 -5.067730e+06 0.000000e+00 -6.670675e+06 2.511229e+07 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 323 | 40 2.470520e+07 -2.611253e+06 0.000000e+00 -7.258714e+06 2.244365e+07 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 324 | 41 7.042320e+06 4.035254e+06 0.000000e+00 -4.102370e+06 7.723143e+06 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 325 | 42 9.419329e+06 5.482878e+06 0.000000e+00 -5.860547e+06 8.468128e+06 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 326 | 43 -1.378109e+04 2.699756e+06 0.000000e+00 -2.543347e+06 6.807000e+06 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 327 | 44 -1.036385e+06 1.627580e+06 0.000000e+00 -1.611455e+06 6.125456e+06 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 328 | $EndElementData 329 | -------------------------------------------------------------------------------- /tests/msh/triangle-quad44.msh: -------------------------------------------------------------------------------- 1 | $MeshFormat 2 | 4 0 8 3 | $EndMeshFormat 4 | $Entities 5 | 3 3 1 0 6 | 1 0 0 0 0 0 0 0 7 | 2 1 1 0 1 1 0 0 8 | 3 1 -1 0 1 -1 0 0 9 | 1 0 0 0 1 1 0 0 2 1 -2 10 | 2 1 -1 0 1 1 0 0 2 2 -3 11 | 3 0 -1 0 1 0 0 0 2 3 -1 12 | 1 0 -1 0 1 1 0 0 3 1 2 3 13 | $EndEntities 14 | $Nodes 15 | 7 49 16 | 1 0 0 1 17 | 1 0 0 0 18 | 2 0 0 1 19 | 2 1 1 0 20 | 3 0 0 1 21 | 3 1 -1 0 22 | 1 1 0 7 23 | 17 0.1249999999997755 0.1249999999997755 0 24 | 4 0.2499999999994115 0.2499999999994115 0 25 | 18 0.3749999999990521 0.3749999999990521 0 26 | 5 0.4999999999986928 0.4999999999986928 0 27 | 19 0.6249999999990168 0.6249999999990168 0 28 | 6 0.7499999999993409 0.7499999999993409 0 29 | 20 0.8749999999996704 0.8749999999996704 0 30 | 2 1 0 7 31 | 21 1 0.7500000000004964 0 32 | 7 1 0.5000000000013871 0 33 | 22 1 0.2500000000020699 0 34 | 8 1 2.752797989558076e-12 0 35 | 23 1 -0.2499999999979301 0 36 | 9 1 -0.4999999999986129 0 37 | 24 1 -0.7499999999993063 0 38 | 3 1 0 7 39 | 25 0.8750000000001034 -0.8750000000001034 0 40 | 10 0.7500000000003473 -0.7500000000003473 0 41 | 26 0.625000000001338 -0.625000000001338 0 42 | 11 0.5000000000020606 -0.5000000000020606 0 43 | 27 0.3750000000015509 -0.3750000000015509 0 44 | 12 0.2500000000010412 -0.2500000000010412 0 45 | 28 0.1250000000005206 -0.1250000000005206 0 46 | 1 2 0 25 47 | 13 0.6665104760064872 5.545182368837942e-13 0 48 | 14 0.6836179339733084 0.369365717684617 0 49 | 15 0.6836179339739235 -0.3693657176842984 0 50 | 16 0.4080026808247026 -2.154840574236846e-13 0 51 | 29 0.7168089669871354 -0.5596828588423228 0 52 | 30 0.591808966987992 -0.4346828588431795 0 53 | 31 0.4668089669874823 -0.3096828588426698 0 54 | 32 0.7168089669863247 0.5596828588419789 0 55 | 33 0.5918089669860006 0.4346828588416549 0 56 | 34 0.46680896698636 0.3096828588420143 0 57 | 35 0.6750642049898978 0.1846828588425858 0 58 | 36 0.5372565784155949 1.695170897300548e-13 0 59 | 37 0.3290013404120571 0.124999999999598 0 60 | 38 0.5020327727009775 0.1548414294210919 0 61 | 39 0.3290013404128719 -0.1250000000006283 0 62 | 40 0.6750642049902054 -0.1846828588418719 0 63 | 41 0.5020327727015387 -0.1548414294212501 0 64 | 42 0.8418089669869617 -0.4346828588414556 0 65 | 43 0.8332552380032436 1.653658113220935e-12 0 66 | 44 0.8375321024951027 -0.217341429419901 0 67 | 45 0.8418089669866542 0.4346828588430021 0 68 | 46 0.8375321024949489 0.2173414294223278 0 69 | 47 0.2270006702063237 -4.264297248646187e-13 0 70 | 48 0.8584044834931623 0.6548414294212376 0 71 | 49 0.8584044834935325 -0.6548414294207794 0 72 | $EndNodes 73 | $Elements 74 | 8 71 75 | 1 0 15 1 76 | 1 1 77 | 2 0 15 1 78 | 2 2 79 | 3 0 15 1 80 | 3 3 81 | 1 1 1 8 82 | 50 1 17 83 | 51 17 4 84 | 52 4 18 85 | 53 18 5 86 | 54 5 19 87 | 55 19 6 88 | 56 6 20 89 | 57 20 2 90 | 2 1 1 8 91 | 58 2 21 92 | 59 21 7 93 | 60 7 22 94 | 61 22 8 95 | 62 8 23 96 | 63 23 9 97 | 64 9 24 98 | 65 24 3 99 | 3 1 1 8 100 | 66 3 25 101 | 67 25 10 102 | 68 10 26 103 | 69 26 11 104 | 70 11 27 105 | 71 27 12 106 | 72 12 28 107 | 73 28 1 108 | 1 2 2 16 109 | 74 15 29 30 110 | 75 29 26 30 111 | 76 29 10 26 112 | 77 30 26 11 113 | 78 11 27 30 114 | 79 27 31 30 115 | 80 27 12 31 116 | 81 30 31 15 117 | 82 5 19 33 118 | 83 19 32 33 119 | 84 19 6 32 120 | 85 33 32 14 121 | 86 14 34 33 122 | 87 34 18 33 123 | 88 34 4 18 124 | 89 33 18 5 125 | 1 2 3 28 126 | 90 14 35 38 34 127 | 91 35 13 36 38 128 | 92 38 36 16 37 129 | 93 34 38 37 4 130 | 94 15 31 41 40 131 | 95 31 12 39 41 132 | 96 41 39 16 36 133 | 97 40 41 36 13 134 | 98 9 42 44 23 135 | 99 42 15 40 44 136 | 100 44 40 13 43 137 | 101 23 44 43 8 138 | 102 7 22 46 45 139 | 103 22 8 43 46 140 | 104 46 43 13 35 141 | 105 45 46 35 14 142 | 106 12 28 47 39 143 | 107 28 1 17 47 144 | 108 47 17 4 37 145 | 109 39 47 37 16 146 | 110 14 32 48 45 147 | 111 32 6 20 48 148 | 112 48 20 2 21 149 | 113 45 48 21 7 150 | 114 15 42 49 29 151 | 115 42 9 24 49 152 | 116 49 24 3 25 153 | 117 29 49 25 10 154 | $EndElements 155 | -------------------------------------------------------------------------------- /tests/msh/triangle-tri14.msh: -------------------------------------------------------------------------------- 1 | $MeshFormat 2 | 4 0 8 3 | $EndMeshFormat 4 | $Entities 5 | 3 3 1 0 6 | 1 0 0 0 0 0 0 0 7 | 2 1 1 0 1 1 0 0 8 | 3 1 -1 0 1 -1 0 0 9 | 1 0 0 0 1 1 0 0 2 1 -2 10 | 2 1 -1 0 1 1 0 0 2 2 -3 11 | 3 0 -1 0 1 0 0 0 2 3 -1 12 | 1 0 -1 0 1 1 0 0 3 1 2 3 13 | $EndEntities 14 | $Nodes 15 | 7 13 16 | 1 0 0 1 17 | 1 0 0 0 18 | 2 0 0 1 19 | 2 1 1 0 20 | 3 0 0 1 21 | 3 1 -1 0 22 | 1 1 0 2 23 | 4 0.3333333333325019 0.3333333333325019 0 24 | 5 0.6666666666657879 0.6666666666657879 0 25 | 2 1 0 3 26 | 6 1 0.5000000000013871 0 27 | 7 1 2.752797989558076e-12 0 28 | 8 1 -0.4999999999986129 0 29 | 3 1 0 2 30 | 9 0.6666666666675922 -0.6666666666675922 0 31 | 10 0.3333333333347215 -0.3333333333347215 0 32 | 1 2 0 3 33 | 11 0.6944444444449998 0.3055555555532902 0 34 | 12 0.6944444444440594 -0.3055555555582546 0 35 | 13 0.5092592592593803 -7.385296078391926e-13 0 36 | $EndNodes 37 | $Elements 38 | 7 27 39 | 1 0 15 1 40 | 1 1 41 | 2 0 15 1 42 | 2 2 43 | 3 0 15 1 44 | 3 3 45 | 1 1 1 3 46 | 4 1 4 47 | 5 4 5 48 | 6 5 2 49 | 2 1 1 4 50 | 7 2 6 51 | 8 6 7 52 | 9 7 8 53 | 10 8 3 54 | 3 1 1 3 55 | 11 3 9 56 | 12 9 10 57 | 13 10 1 58 | 1 2 2 14 59 | 14 8 3 9 60 | 15 2 6 5 61 | 16 7 8 12 62 | 17 6 7 11 63 | 18 10 1 13 64 | 19 1 4 13 65 | 20 7 12 13 66 | 21 11 7 13 67 | 22 4 5 11 68 | 23 9 10 12 69 | 24 5 6 11 70 | 25 8 9 12 71 | 26 4 11 13 72 | 27 12 10 13 73 | $EndElements 74 | -------------------------------------------------------------------------------- /tests/msh/triangle-tri56-ref.msh: -------------------------------------------------------------------------------- 1 | $MeshFormat 2 | 2.2 0 8 3 | $EndMeshFormat 4 | $Nodes 5 | 39 6 | 1 0.000000e+00 0.000000e+00 0.000000 7 | 2 1.000000e+00 1.000000e+00 0.000000 8 | 3 1.000000e+00 -1.000000e+00 0.000000 9 | 4 1.666667e-01 1.666667e-01 0.000000 10 | 5 3.333333e-01 3.333333e-01 0.000000 11 | 6 5.000000e-01 5.000000e-01 0.000000 12 | 7 6.666667e-01 6.666667e-01 0.000000 13 | 8 8.333333e-01 8.333333e-01 0.000000 14 | 9 1.000000e+00 7.500000e-01 0.000000 15 | 10 1.000000e+00 5.000000e-01 0.000000 16 | 11 1.000000e+00 2.500000e-01 0.000000 17 | 12 1.000000e+00 2.752798e-12 0.000000 18 | 13 1.000000e+00 -2.500000e-01 0.000000 19 | 14 1.000000e+00 -5.000000e-01 0.000000 20 | 15 1.000000e+00 -7.500000e-01 0.000000 21 | 16 8.333333e-01 -8.333333e-01 0.000000 22 | 17 6.666667e-01 -6.666667e-01 0.000000 23 | 18 5.000000e-01 -5.000000e-01 0.000000 24 | 19 3.333333e-01 -3.333333e-01 0.000000 25 | 20 1.666667e-01 -1.666667e-01 0.000000 26 | 21 6.944444e-01 3.055556e-01 0.000000 27 | 22 6.944444e-01 -3.055556e-01 0.000000 28 | 23 5.092593e-01 -7.385296e-13 0.000000 29 | 24 8.333333e-01 -5.833333e-01 0.000000 30 | 25 8.333333e-01 5.833333e-01 0.000000 31 | 26 8.472222e-01 -4.027778e-01 0.000000 32 | 27 8.472222e-01 -1.527778e-01 0.000000 33 | 28 8.472222e-01 1.527778e-01 0.000000 34 | 29 8.472222e-01 4.027778e-01 0.000000 35 | 30 2.546296e-01 -3.692648e-13 0.000000 36 | 31 4.212963e-01 -1.666667e-01 0.000000 37 | 32 4.212963e-01 1.666667e-01 0.000000 38 | 33 6.018519e-01 -1.527778e-01 0.000000 39 | 34 7.546296e-01 1.007134e-12 0.000000 40 | 35 6.018519e-01 1.527778e-01 0.000000 41 | 36 6.805556e-01 4.861111e-01 0.000000 42 | 37 5.138889e-01 3.194444e-01 0.000000 43 | 38 5.138889e-01 -3.194444e-01 0.000000 44 | 39 6.805556e-01 -4.861111e-01 0.000000 45 | $EndNodes 46 | $Elements 47 | 56 48 | 1 2 2 1 1 14 15 24 49 | 2 2 2 1 1 15 16 24 50 | 3 2 2 1 1 15 3 16 51 | 4 2 2 1 1 24 16 17 52 | 5 2 2 1 1 2 9 8 53 | 6 2 2 1 1 9 25 8 54 | 7 2 2 1 1 9 10 25 55 | 8 2 2 1 1 8 25 7 56 | 9 2 2 1 1 12 13 27 57 | 10 2 2 1 1 13 26 27 58 | 11 2 2 1 1 13 14 26 59 | 12 2 2 1 1 27 26 22 60 | 13 2 2 1 1 10 11 29 61 | 14 2 2 1 1 11 28 29 62 | 15 2 2 1 1 11 12 28 63 | 16 2 2 1 1 29 28 21 64 | 17 2 2 1 1 19 20 31 65 | 18 2 2 1 1 20 30 31 66 | 19 2 2 1 1 20 1 30 67 | 20 2 2 1 1 31 30 23 68 | 21 2 2 1 1 1 4 30 69 | 22 2 2 1 1 4 32 30 70 | 23 2 2 1 1 4 5 32 71 | 24 2 2 1 1 30 32 23 72 | 25 2 2 1 1 12 27 34 73 | 26 2 2 1 1 27 33 34 74 | 27 2 2 1 1 27 22 33 75 | 28 2 2 1 1 34 33 23 76 | 29 2 2 1 1 21 28 35 77 | 30 2 2 1 1 28 34 35 78 | 31 2 2 1 1 28 12 34 79 | 32 2 2 1 1 35 34 23 80 | 33 2 2 1 1 5 6 37 81 | 34 2 2 1 1 6 36 37 82 | 35 2 2 1 1 6 7 36 83 | 36 2 2 1 1 37 36 21 84 | 37 2 2 1 1 17 18 39 85 | 38 2 2 1 1 18 38 39 86 | 39 2 2 1 1 18 19 38 87 | 40 2 2 1 1 39 38 22 88 | 41 2 2 1 1 7 25 36 89 | 42 2 2 1 1 25 29 36 90 | 43 2 2 1 1 25 10 29 91 | 44 2 2 1 1 36 29 21 92 | 45 2 2 1 1 14 24 26 93 | 46 2 2 1 1 24 39 26 94 | 47 2 2 1 1 24 17 39 95 | 48 2 2 1 1 26 39 22 96 | 49 2 2 1 1 5 37 32 97 | 50 2 2 1 1 37 35 32 98 | 51 2 2 1 1 37 21 35 99 | 52 2 2 1 1 32 35 23 100 | 53 2 2 1 1 22 38 33 101 | 54 2 2 1 1 38 31 33 102 | 55 2 2 1 1 38 19 31 103 | 56 2 2 1 1 33 31 23 104 | $EndElements 105 | $NodeData 106 | 1 107 | "ref displacement" 108 | 1 109 | 0.000000 110 | 3 111 | 0 112 | 3 113 | 39 114 | 1 0.000000e+00 0.000000e+00 0.000000e+00 115 | 2 1.000000e+00 1.000000e+00 0.000000e+00 116 | 3 -1.000000e+00 -1.000000e+00 0.000000e+00 117 | 4 2.777778e-02 2.777778e-02 0.000000e+00 118 | 5 1.111111e-01 1.111111e-01 0.000000e+00 119 | 6 2.500000e-01 2.500000e-01 0.000000e+00 120 | 7 4.444444e-01 4.444444e-01 0.000000e+00 121 | 8 6.944444e-01 6.944444e-01 0.000000e+00 122 | 9 7.500000e-01 7.500000e-01 0.000000e+00 123 | 10 5.000000e-01 5.000000e-01 0.000000e+00 124 | 11 2.500000e-01 2.500000e-01 0.000000e+00 125 | 12 2.752798e-12 2.752798e-12 0.000000e+00 126 | 13 -2.500000e-01 -2.500000e-01 0.000000e+00 127 | 14 -5.000000e-01 -5.000000e-01 0.000000e+00 128 | 15 -7.500000e-01 -7.500000e-01 0.000000e+00 129 | 16 -6.944444e-01 -6.944444e-01 0.000000e+00 130 | 17 -4.444444e-01 -4.444444e-01 0.000000e+00 131 | 18 -2.500000e-01 -2.500000e-01 0.000000e+00 132 | 19 -1.111111e-01 -1.111111e-01 0.000000e+00 133 | 20 -2.777778e-02 -2.777778e-02 0.000000e+00 134 | 21 2.121914e-01 2.121914e-01 0.000000e+00 135 | 22 -2.121914e-01 -2.121914e-01 0.000000e+00 136 | 23 -3.761030e-13 -3.761030e-13 0.000000e+00 137 | 24 -4.861111e-01 -4.861111e-01 0.000000e+00 138 | 25 4.861111e-01 4.861111e-01 0.000000e+00 139 | 26 -3.412423e-01 -3.412423e-01 0.000000e+00 140 | 27 -1.294367e-01 -1.294367e-01 0.000000e+00 141 | 28 1.294367e-01 1.294367e-01 0.000000e+00 142 | 29 3.412423e-01 3.412423e-01 0.000000e+00 143 | 30 -9.402576e-14 -9.402576e-14 0.000000e+00 144 | 31 -7.021605e-02 -7.021605e-02 0.000000e+00 145 | 32 7.021605e-02 7.021605e-02 0.000000e+00 146 | 33 -9.194959e-02 -9.194959e-02 0.000000e+00 147 | 34 7.600133e-13 7.600133e-13 0.000000e+00 148 | 35 9.194959e-02 9.194959e-02 0.000000e+00 149 | 36 3.308256e-01 3.308256e-01 0.000000e+00 150 | 37 1.641590e-01 1.641590e-01 0.000000e+00 151 | 38 -1.641590e-01 -1.641590e-01 0.000000e+00 152 | 39 -3.308256e-01 -3.308256e-01 0.000000e+00 153 | $EndNodeData 154 | $NodeData 155 | 1 156 | "ref residual" 157 | 1 158 | 0.000000 159 | 3 160 | 0 161 | 3 162 | 39 163 | 1 7.973311e+05 -3.180264e+04 0.000000e+00 164 | 2 -6.922992e+05 -1.826707e+06 0.000000e+00 165 | 3 2.475086e+05 7.580497e+05 0.000000e+00 166 | 4 1.828621e+06 -1.199026e+06 0.000000e+00 167 | 5 2.784957e+06 -2.530739e+06 0.000000e+00 168 | 6 3.638929e+06 -3.531632e+06 0.000000e+00 169 | 7 4.392404e+06 -4.357017e+06 0.000000e+00 170 | 8 5.081231e+06 -5.056851e+06 0.000000e+00 171 | 9 -6.571201e+06 1.899324e+06 0.000000e+00 172 | 10 -6.258410e+06 2.078558e+06 0.000000e+00 173 | 11 -5.827735e+06 2.200838e+06 0.000000e+00 174 | 12 -5.193627e+06 2.248687e+06 0.000000e+00 175 | 13 -4.328574e+06 2.162634e+06 0.000000e+00 176 | 14 -3.078390e+06 1.856724e+06 0.000000e+00 177 | 15 -4.622986e+05 1.030277e+06 0.000000e+00 178 | 16 6.454822e+05 5.464217e+05 0.000000e+00 179 | 17 7.894539e+05 5.273394e+05 0.000000e+00 180 | 18 3.408754e+05 5.747126e+05 0.000000e+00 181 | 19 6.861895e+05 6.490571e+05 0.000000e+00 182 | 20 6.029714e+05 6.098376e+05 0.000000e+00 183 | 21 1.528302e+05 8.395251e+04 0.000000e+00 184 | 22 5.614450e+05 -1.881717e+04 0.000000e+00 185 | 23 4.174129e+05 1.379436e+05 0.000000e+00 186 | 24 1.534694e+06 -2.676915e+05 0.000000e+00 187 | 25 5.036843e+04 3.162158e+04 0.000000e+00 188 | 26 8.149823e+05 -8.563016e+04 0.000000e+00 189 | 27 4.870491e+05 1.896679e+01 0.000000e+00 190 | 28 2.131363e+05 3.510684e+04 0.000000e+00 191 | 29 8.707594e+04 3.859008e+04 0.000000e+00 192 | 30 9.259442e+05 5.241297e+05 0.000000e+00 193 | 31 1.000712e+06 2.643661e+05 0.000000e+00 194 | 32 3.802650e+05 2.331360e+05 0.000000e+00 195 | 33 6.322824e+05 8.240977e+04 0.000000e+00 196 | 34 3.819596e+05 5.370143e+04 0.000000e+00 197 | 35 2.658149e+05 1.047660e+05 0.000000e+00 198 | 36 8.402608e+04 6.070012e+04 0.000000e+00 199 | 37 1.653743e+05 1.140931e+05 0.000000e+00 200 | 38 1.131253e+06 7.626179e+04 0.000000e+00 201 | 39 1.289954e+06 -7.734190e+04 0.000000e+00 202 | $EndNodeData 203 | $ElementData 204 | 1 205 | "ref deformation gradient" 206 | 1 207 | 0.000000 208 | 3 209 | 0 210 | 9 211 | 56 212 | 1 4.166667e-01 1.000000e+00 0.000000e+00 -5.833333e-01 2.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 213 | 2 2.500000e-01 8.333333e-01 0.000000e+00 -7.500000e-01 1.833333e+00 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 214 | 3 1.666667e-01 1.000000e+00 0.000000e+00 -8.333333e-01 2.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 215 | 4 3.333333e-01 8.333333e-01 0.000000e+00 -6.666667e-01 1.833333e+00 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 216 | 5 1.833333e+00 1.000000e+00 0.000000e+00 8.333333e-01 2.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 217 | 6 1.750000e+00 8.333333e-01 0.000000e+00 7.500000e-01 1.833333e+00 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 218 | 7 1.583333e+00 1.000000e+00 0.000000e+00 5.833333e-01 2.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 219 | 8 1.666667e+00 8.333333e-01 0.000000e+00 6.666667e-01 1.833333e+00 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 220 | 9 8.472222e-01 1.000000e+00 0.000000e+00 -1.527778e-01 2.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 221 | 10 7.500000e-01 8.472222e-01 0.000000e+00 -2.500000e-01 1.847222e+00 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 222 | 11 5.972222e-01 1.000000e+00 0.000000e+00 -4.027778e-01 2.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 223 | 12 6.944444e-01 8.472222e-01 0.000000e+00 -3.055556e-01 1.847222e+00 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 224 | 13 1.402778e+00 1.000000e+00 0.000000e+00 4.027778e-01 2.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 225 | 14 1.250000e+00 8.472222e-01 0.000000e+00 2.500000e-01 1.847222e+00 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 226 | 15 1.152778e+00 1.000000e+00 0.000000e+00 1.527778e-01 2.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 227 | 16 1.305556e+00 8.472222e-01 0.000000e+00 3.055556e-01 1.847222e+00 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 228 | 17 8.333333e-01 3.333333e-01 0.000000e+00 -1.666667e-01 1.333333e+00 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 229 | 18 8.333333e-01 2.546296e-01 0.000000e+00 -1.666667e-01 1.254630e+00 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 230 | 19 1.000000e+00 1.666667e-01 0.000000e+00 -1.275569e-13 1.166667e+00 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 231 | 20 1.000000e+00 4.212963e-01 0.000000e+00 -4.968418e-13 1.421296e+00 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 232 | 21 1.000000e+00 1.666667e-01 0.000000e+00 -1.275607e-13 1.166667e+00 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 233 | 22 1.166667e+00 2.546296e-01 0.000000e+00 1.666667e-01 1.254630e+00 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 234 | 23 1.166667e+00 3.333333e-01 0.000000e+00 1.666667e-01 1.333333e+00 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 235 | 24 1.000000e+00 4.212963e-01 0.000000e+00 -4.968290e-13 1.421296e+00 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 236 | 25 1.000000e+00 8.472222e-01 0.000000e+00 2.094057e-12 1.847222e+00 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 237 | 26 8.472222e-01 7.546296e-01 0.000000e+00 -1.527778e-01 1.754630e+00 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 238 | 27 8.472222e-01 6.944444e-01 0.000000e+00 -1.527778e-01 1.694444e+00 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 239 | 28 1.000000e+00 6.018519e-01 0.000000e+00 3.483931e-13 1.601852e+00 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 240 | 29 1.152778e+00 6.944444e-01 0.000000e+00 1.527778e-01 1.694444e+00 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 241 | 30 1.152778e+00 7.546296e-01 0.000000e+00 1.527778e-01 1.754630e+00 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 242 | 31 1.000000e+00 8.472222e-01 0.000000e+00 2.094032e-12 1.847222e+00 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 243 | 32 1.000000e+00 6.018519e-01 0.000000e+00 3.483756e-13 1.601852e+00 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 244 | 33 1.332341e+00 5.009921e-01 0.000000e+00 3.323413e-01 1.500992e+00 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 245 | 34 1.487103e+00 5.128968e-01 0.000000e+00 4.871032e-01 1.512897e+00 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 246 | 35 1.499008e+00 6.676587e-01 0.000000e+00 4.990079e-01 1.667659e+00 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 247 | 36 1.318452e+00 6.815476e-01 0.000000e+00 3.184524e-01 1.681548e+00 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 248 | 37 5.009921e-01 6.676587e-01 0.000000e+00 -4.990079e-01 1.667659e+00 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 249 | 38 5.128968e-01 5.128968e-01 0.000000e+00 -4.871032e-01 1.512897e+00 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 250 | 39 6.676587e-01 5.009921e-01 0.000000e+00 -3.323413e-01 1.500992e+00 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 251 | 40 6.815476e-01 6.815476e-01 0.000000e+00 -3.184524e-01 1.681548e+00 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 252 | 41 1.587222e+00 6.744444e-01 0.000000e+00 5.872222e-01 1.674444e+00 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 253 | 42 1.482222e+00 8.394444e-01 0.000000e+00 4.822222e-01 1.839444e+00 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 254 | 43 1.503889e+00 8.411111e-01 0.000000e+00 5.038889e-01 1.841111e+00 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 255 | 44 1.406667e+00 6.883333e-01 0.000000e+00 4.066667e-01 1.688333e+00 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 256 | 45 4.961111e-01 8.411111e-01 0.000000e+00 -5.038889e-01 1.841111e+00 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 257 | 46 5.177778e-01 8.394444e-01 0.000000e+00 -4.822222e-01 1.839444e+00 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 258 | 47 4.127778e-01 6.744444e-01 0.000000e+00 -5.872222e-01 1.674444e+00 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 259 | 48 5.933333e-01 6.883333e-01 0.000000e+00 -4.066667e-01 1.688333e+00 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 260 | 49 1.325909e+00 4.173781e-01 0.000000e+00 3.259094e-01 1.417378e+00 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 261 | 50 1.160202e+00 5.178071e-01 0.000000e+00 1.602017e-01 1.517807e+00 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 262 | 51 1.312021e+00 5.979337e-01 0.000000e+00 3.120205e-01 1.597934e+00 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 263 | 52 1.159243e+00 5.053411e-01 0.000000e+00 1.592428e-01 1.505341e+00 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 264 | 53 6.879795e-01 5.979337e-01 0.000000e+00 -3.120205e-01 1.597934e+00 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 265 | 54 8.397983e-01 5.178071e-01 0.000000e+00 -1.602017e-01 1.517807e+00 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 266 | 55 6.740906e-01 4.173781e-01 0.000000e+00 -3.259094e-01 1.417378e+00 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 267 | 56 8.407572e-01 5.053411e-01 0.000000e+00 -1.592428e-01 1.505341e+00 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 268 | $EndElementData 269 | $ElementData 270 | 1 271 | "ref engineering stress" 272 | 1 273 | 0.000000 274 | 3 275 | 0 276 | 9 277 | 56 278 | 1 1.182912e+07 6.479376e+06 0.000000e+00 -7.207665e+06 9.061623e+06 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 279 | 2 -7.696403e+05 2.206046e+06 0.000000e+00 -1.844521e+06 6.099333e+06 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 280 | 3 2.864503e+06 4.402355e+06 0.000000e+00 -4.018458e+06 7.087368e+06 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 281 | 4 3.248399e+06 3.636827e+06 0.000000e+00 -3.252930e+06 6.703471e+06 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 282 | 5 2.670257e+07 -5.043697e+06 0.000000e+00 -7.316804e+06 2.557889e+07 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 283 | 6 2.449032e+07 -4.676551e+06 0.000000e+00 -5.802809e+06 2.393877e+07 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 284 | 7 2.559341e+07 -2.424035e+06 0.000000e+00 -8.055324e+06 2.283568e+07 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 285 | 8 2.407190e+07 -3.789992e+06 0.000000e+00 -6.030594e+06 2.298073e+07 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 286 | 9 1.980850e+07 4.738258e+06 0.000000e+00 -8.970341e+06 1.405009e+07 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 287 | 10 1.540523e+07 4.656361e+06 0.000000e+00 -6.741470e+06 1.157445e+07 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 288 | 11 1.593863e+07 6.243401e+06 0.000000e+00 -8.328510e+06 1.104105e+07 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 289 | 12 1.435917e+07 4.900552e+06 0.000000e+00 -6.541132e+06 1.086768e+07 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 290 | 13 2.461206e+07 -5.341688e+05 0.000000e+00 -8.498560e+06 2.076645e+07 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 291 | 14 2.151780e+07 5.926269e+05 0.000000e+00 -7.030074e+06 1.801388e+07 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 292 | 15 2.287876e+07 2.004246e+06 0.000000e+00 -8.925012e+06 1.779241e+07 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 293 | 16 2.196155e+07 3.339628e+04 0.000000e+00 -6.954162e+06 1.870962e+07 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 294 | 17 4.400090e+06 1.340241e+06 0.000000e+00 -9.563443e+05 5.551780e+06 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 295 | 18 1.914283e+06 7.506011e+05 0.000000e+00 -3.800247e+05 3.689149e+06 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 296 | 19 4.783987e+06 5.747126e+05 0.000000e+00 -1.908158e+05 5.167883e+06 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 297 | 20 1.091077e+07 1.452746e+06 0.000000e+00 -2.212010e+06 1.015151e+07 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 298 | 21 4.783987e+06 5.747126e+05 0.000000e+00 -1.908158e+05 5.167883e+06 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 299 | 22 1.061040e+07 2.952153e+03 0.000000e+00 -7.622167e+05 1.045188e+07 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 300 | 23 1.214310e+07 1.344115e+05 0.000000e+00 -1.455315e+06 1.170280e+07 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 301 | 24 1.091077e+07 1.452746e+06 0.000000e+00 -2.212010e+06 1.015151e+07 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 302 | 25 1.904533e+07 2.921456e+06 0.000000e+00 -7.153538e+06 1.481325e+07 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 303 | 26 1.516112e+07 3.667894e+06 0.000000e+00 -5.790845e+06 1.196036e+07 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 304 | 27 1.389644e+07 3.384184e+06 0.000000e+00 -5.024765e+06 1.133040e+07 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 305 | 28 1.462222e+07 2.075351e+06 0.000000e+00 -4.198302e+06 1.249927e+07 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 306 | 29 1.828217e+07 1.104654e+06 0.000000e+00 -5.336736e+06 1.557641e+07 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 307 | 30 1.923820e+07 1.273194e+06 0.000000e+00 -6.037524e+06 1.607819e+07 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 308 | 31 1.904533e+07 2.921456e+06 0.000000e+00 -7.153538e+06 1.481325e+07 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 309 | 32 1.462222e+07 2.075351e+06 0.000000e+00 -4.198302e+06 1.249927e+07 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 310 | 33 1.717219e+07 -1.057371e+06 0.000000e+00 -3.052173e+06 1.634049e+07 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 311 | 34 1.879181e+07 -2.630708e+06 0.000000e+00 -2.952610e+06 1.864780e+07 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 312 | 35 2.098400e+07 -2.429999e+06 0.000000e+00 -4.610929e+06 1.996617e+07 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 313 | 36 1.973344e+07 -5.259685e+05 0.000000e+00 -5.057350e+06 1.770617e+07 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 314 | 37 3.708864e+06 2.895131e+06 0.000000e+00 -2.513946e+06 6.345764e+06 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 315 | 38 -2.151456e+06 5.064772e+05 0.000000e+00 -3.506997e+05 3.887919e+06 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 316 | 39 4.085564e+06 2.122405e+06 0.000000e+00 -1.741221e+06 5.969064e+06 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 317 | 40 9.955341e+06 3.790437e+06 0.000000e+00 -4.180564e+06 8.880892e+06 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 318 | 41 2.167151e+07 -3.355030e+06 0.000000e+00 -4.499571e+06 2.112850e+07 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 319 | 42 2.308956e+07 -1.818530e+06 0.000000e+00 -6.541766e+06 2.082992e+07 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 320 | 43 2.324517e+07 -2.042232e+06 0.000000e+00 -6.512859e+06 2.110021e+07 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 321 | 44 2.056810e+07 -1.412297e+06 0.000000e+00 -5.005735e+06 1.891719e+07 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 322 | 45 9.379842e+06 4.999323e+06 0.000000e+00 -5.241180e+06 8.415200e+06 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 323 | 46 9.959125e+06 5.037420e+06 0.000000e+00 -5.392958e+06 8.643689e+06 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 324 | 47 1.096781e+05 1.864962e+06 0.000000e+00 -1.495766e+06 5.450100e+06 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 325 | 48 7.648805e+06 3.723109e+06 0.000000e+00 -3.686571e+06 7.790849e+06 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 326 | 49 1.579205e+07 -1.140660e+06 0.000000e+00 -2.180135e+06 1.538339e+07 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 327 | 50 1.541170e+07 5.811315e+05 0.000000e+00 -3.340499e+06 1.395631e+07 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 328 | 51 1.844037e+07 -6.554981e+05 0.000000e+00 -4.131379e+06 1.693630e+07 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 329 | 52 1.518051e+07 5.595475e+05 0.000000e+00 -3.205045e+06 1.380280e+07 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 330 | 53 7.785227e+06 3.118787e+06 0.000000e+00 -3.101390e+06 7.840596e+06 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 331 | 54 9.648216e+06 2.498240e+06 0.000000e+00 -2.856019e+06 8.969879e+06 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 332 | 55 1.373868e+06 1.220660e+06 0.000000e+00 -8.439058e+05 4.435424e+06 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 333 | 56 9.357892e+06 2.425793e+06 0.000000e+00 -2.717300e+06 8.798136e+06 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 334 | $EndElementData 335 | -------------------------------------------------------------------------------- /tests/msh/triangle-tri56.msh: -------------------------------------------------------------------------------- 1 | $MeshFormat 2 | 4 0 8 3 | $EndMeshFormat 4 | $Entities 5 | 3 3 1 0 6 | 1 0 0 0 0 0 0 0 7 | 2 1 1 0 1 1 0 0 8 | 3 1 -1 0 1 -1 0 0 9 | 1 0 0 0 1 1 0 0 2 1 -2 10 | 2 1 -1 0 1 1 0 0 2 2 -3 11 | 3 0 -1 0 1 0 0 0 2 3 -1 12 | 1 0 -1 0 1 1 0 0 3 1 2 3 13 | $EndEntities 14 | $Nodes 15 | 7 39 16 | 1 0 0 1 17 | 1 0 0 0 18 | 2 0 0 1 19 | 2 1 1 0 20 | 3 0 0 1 21 | 3 1 -1 0 22 | 1 1 0 5 23 | 14 0.1666666666663272 0.1666666666663272 0 24 | 4 0.3333333333325019 0.3333333333325019 0 25 | 15 0.4999999999986823 0.4999999999986823 0 26 | 5 0.6666666666657879 0.6666666666657879 0 27 | 16 0.8333333333328939 0.8333333333328939 0 28 | 2 1 0 7 29 | 17 1 0.7500000000004964 0 30 | 6 1 0.5000000000013871 0 31 | 18 1 0.2500000000020699 0 32 | 7 1 2.752797989558076e-12 0 33 | 19 1 -0.2499999999979301 0 34 | 8 1 -0.4999999999986129 0 35 | 20 1 -0.7499999999993063 0 36 | 3 1 0 5 37 | 21 0.8333333333335833 -0.8333333333335833 0 38 | 9 0.6666666666675922 -0.6666666666675922 0 39 | 22 0.500000000001773 -0.500000000001773 0 40 | 10 0.3333333333347215 -0.3333333333347215 0 41 | 23 0.1666666666673607 -0.1666666666673607 0 42 | 1 2 0 19 43 | 11 0.6944444444449998 0.3055555555532902 0 44 | 12 0.6944444444440594 -0.3055555555582546 0 45 | 13 0.5092592592593803 -7.385296078391926e-13 0 46 | 24 0.8333333333337961 -0.5833333333331026 0 47 | 25 0.8333333333328939 0.5833333333335875 0 48 | 26 0.8472222222220297 -0.4027777777784338 0 49 | 27 0.8472222222220297 -0.1527777777777509 0 50 | 28 0.8472222222224999 0.1527777777780215 0 51 | 29 0.8472222222224999 0.4027777777773386 0 52 | 30 0.2546296296296902 -3.692648039195963e-13 0 53 | 31 0.4212962962970509 -0.16666666666773 0 54 | 32 0.4212962962959411 0.1666666666658817 0 55 | 33 0.6018518518517199 -0.1527777777794966 0 56 | 34 0.7546296296296902 1.007134190859441e-12 0 57 | 35 0.60185185185219 0.1527777777762758 0 58 | 36 0.6805555555553938 0.486111111109539 0 59 | 37 0.5138888888887508 0.319444444442896 0 60 | 38 0.5138888888893904 -0.3194444444464881 0 61 | 39 0.6805555555558258 -0.4861111111129234 0 62 | $EndNodes 63 | $Elements 64 | 7 79 65 | 1 0 15 1 66 | 1 1 67 | 2 0 15 1 68 | 2 2 69 | 3 0 15 1 70 | 3 3 71 | 1 1 1 6 72 | 52 1 14 73 | 53 14 4 74 | 54 4 15 75 | 55 15 5 76 | 56 5 16 77 | 57 16 2 78 | 2 1 1 8 79 | 58 2 17 80 | 59 17 6 81 | 60 6 18 82 | 61 18 7 83 | 62 7 19 84 | 63 19 8 85 | 64 8 20 86 | 65 20 3 87 | 3 1 1 6 88 | 66 3 21 89 | 67 21 9 90 | 68 9 22 91 | 69 22 10 92 | 70 10 23 93 | 71 23 1 94 | 1 2 2 56 95 | 72 8 20 24 96 | 73 20 21 24 97 | 74 20 3 21 98 | 75 24 21 9 99 | 76 2 17 16 100 | 77 17 25 16 101 | 78 17 6 25 102 | 79 16 25 5 103 | 80 7 19 27 104 | 81 19 26 27 105 | 82 19 8 26 106 | 83 27 26 12 107 | 84 6 18 29 108 | 85 18 28 29 109 | 86 18 7 28 110 | 87 29 28 11 111 | 88 10 23 31 112 | 89 23 30 31 113 | 90 23 1 30 114 | 91 31 30 13 115 | 92 1 14 30 116 | 93 14 32 30 117 | 94 14 4 32 118 | 95 30 32 13 119 | 96 7 27 34 120 | 97 27 33 34 121 | 98 27 12 33 122 | 99 34 33 13 123 | 100 11 28 35 124 | 101 28 34 35 125 | 102 28 7 34 126 | 103 35 34 13 127 | 104 4 15 37 128 | 105 15 36 37 129 | 106 15 5 36 130 | 107 37 36 11 131 | 108 9 22 39 132 | 109 22 38 39 133 | 110 22 10 38 134 | 111 39 38 12 135 | 112 5 25 36 136 | 113 25 29 36 137 | 114 25 6 29 138 | 115 36 29 11 139 | 116 8 24 26 140 | 117 24 39 26 141 | 118 24 9 39 142 | 119 26 39 12 143 | 120 4 37 32 144 | 121 37 35 32 145 | 122 37 11 35 146 | 123 32 35 13 147 | 124 12 38 33 148 | 125 38 31 33 149 | 126 38 10 31 150 | 127 33 31 13 151 | $EndElements 152 | -------------------------------------------------------------------------------- /tests/readme.md: -------------------------------------------------------------------------------- 1 | # Tests 2 | 3 | In this folder there are the files used test the main code. 4 | With them, it's easier to test the code and debug if something happens. 5 | 6 | 7 | ### Files 8 | 9 | There are two different files that we have to give attention: 10 | 11 | * ```test_unit.py``` contains the basic class ```TU```(Test Unit) that the others test classes inherit from. 12 | * ```test_all.py``` contains all the tests, it's used if we want to test all the tests at the same time, instead running each test file separately. 13 | 14 | The others files are to test a specific part/module: 15 | 16 | 1. The file ```test_tensor.py``` tests the file ```src/tensor.py```. 17 | 2. The file ```test_mesh.py``` tests the file ```src/mesh.py``` 18 | 3. The file ```test_geometry.py``` test the file ```src/geometry.py``` 19 | 4. The file ```test_plot.py``` test the file ```src/plot.py``` 20 | 5. The file ```test_fem.py``` tests the file ```src/fem.py``` that uses the ```src/geometry.py```. For example, create the finite element and integrate in the geometry. 21 | 6. The files ```test_elasticity.py``` tests the computation of piola's tensor using the hyperelastic materials in the ```src/elasticity.py``` 22 | 7. The file ```test_residual.py``` tests the part of calculating the internal forces in the file ```src/fem.py```. 23 | 24 | 25 | 26 | [stvenantkirchhoff]: https://en.wikipedia.org/w/index.php?title=Hyperelastic_material&oldid=993354665 27 | [neohookean]: https://en.wikipedia.org/w/index.php?title=Neo-Hookean_solid&oldid=980304435 28 | [gmsh_website]: https://gmsh.info/ 29 | -------------------------------------------------------------------------------- /tests/test_elasticity.py: -------------------------------------------------------------------------------- 1 | # , -*- coding: utf-8, -*- 2 | """ 3 | """ 4 | 5 | import numpy as np 6 | import pytest 7 | 8 | from hyper import elasticity, tensor 9 | 10 | 11 | def test_StVenantKirchhoffValues(): 12 | E = 210 13 | nu = 0.3 14 | G = 1050 / 13 15 | mu = 1050 / 13 16 | lamda = 1575 / 13 17 | material = elasticity.StVenantKirchhoffElasticity(E, nu) 18 | assert material.E == pytest.approx(E) 19 | assert material.nu == pytest.approx(nu) 20 | assert material.G == pytest.approx(G) 21 | assert material.LAME1 == pytest.approx(lamda) 22 | assert material.LAME2 == pytest.approx(mu) 23 | 24 | E = 26 25 | nu = 0.3 26 | G = 10 27 | mu = 10 28 | lamda = 15 29 | material = elasticity.StVenantKirchhoffElasticity(E, nu) 30 | assert material.E == pytest.approx(E) 31 | assert material.nu == pytest.approx(nu) 32 | assert material.G == pytest.approx(G) 33 | assert material.LAME1 == pytest.approx(lamda) 34 | assert material.LAME2 == pytest.approx(mu) 35 | 36 | E = 42 37 | nu = 0.4 38 | G = 15 39 | mu = 15 40 | lamda = 60 41 | material = elasticity.StVenantKirchhoffElasticity(E, nu) 42 | assert material.E == pytest.approx(E) 43 | assert material.nu == pytest.approx(nu) 44 | assert material.G == pytest.approx(G) 45 | assert material.LAME1 == pytest.approx(lamda) 46 | assert material.LAME2 == pytest.approx(mu) 47 | 48 | 49 | def test_StVenantKirchhoffPotential(): 50 | E = 52 51 | nu = 0.3 52 | material = elasticity.StVenantKirchhoffElasticity(E, nu) 53 | 54 | C = np.eye(2) # No deformation at all 55 | phitest = material.potential(C) 56 | assert phitest == 0 57 | 58 | C = np.eye(3) # No deformation at all 59 | phitest = material.potential(C) 60 | assert phitest == 0 61 | 62 | C = np.ones((2, 2)) 63 | phitest = material.potential(C) 64 | assert phitest == 10 65 | 66 | C = 2 * np.eye(2) + 1 67 | phitest = material.potential(C) 68 | assert phitest == 110 69 | 70 | C = np.eye(2) + 1 71 | phitest = material.potential(C) 72 | assert phitest == 35 73 | 74 | 75 | def test_StVenantKirchhoffStress(): 76 | E = 26 77 | nu = 0.3 78 | material = elasticity.StVenantKirchhoffElasticity(E, nu) 79 | 80 | C = np.eye(2) # No deformation at all 81 | PK2test = material.stress(C) 82 | assert PK2test.ndim == 2 83 | assert PK2test.shape == (2, 2) 84 | np.testing.assert_almost_equal(PK2test, np.zeros((2, 2))) 85 | 86 | C = np.eye(3) # No deformation at all 87 | PK2test = material.stress(C) 88 | assert PK2test.ndim == 2 89 | assert PK2test.shape == (3, 3) 90 | np.testing.assert_almost_equal(PK2test, np.zeros((3, 3))) 91 | 92 | C = np.ones((2, 2)) 93 | PK2test = material.stress(C) 94 | PK2good = 10 * np.array([[0, 1], [1, 0]]) 95 | assert PK2test.ndim == 2 96 | assert PK2test.shape == (2, 2) 97 | np.testing.assert_almost_equal(PK2test, PK2good) 98 | 99 | C = 2 * np.eye(2) + 1 100 | PK2test = material.stress(C) 101 | PK2good = 10 * np.array([[5, 1], [1, 5]]) 102 | assert PK2test.ndim == 2 103 | assert PK2test.shape == (2, 2) 104 | np.testing.assert_almost_equal(PK2test, PK2good) 105 | 106 | C = np.eye(2) + 1 107 | PK2test = material.stress(C) 108 | PK2good = 5 * np.array([[5, 2], [2, 5]]) 109 | assert PK2test.ndim == 2 110 | assert PK2test.shape == (2, 2) 111 | np.testing.assert_almost_equal(PK2test, PK2good) 112 | 113 | 114 | def test_StVenantKirchhoffStiffness(): 115 | E = 26 116 | nu = 0.3 117 | material = elasticity.StVenantKirchhoffElasticity(E, nu) 118 | 119 | Mgood = [ 120 | [[[7, 0], [0, 3]], [[0, 2], [2, 0]]], 121 | [[[0, 2], [2, 0]], [[3, 0], [0, 7]]], 122 | ] 123 | Mgood = 5 * np.array(Mgood) 124 | 125 | C = np.eye(2) # No deformation at all 126 | Mtest = material.stiffness(C) 127 | assert Mtest.ndim == 4 128 | assert Mtest.shape == (2, 2, 2, 2) 129 | np.testing.assert_almost_equal(Mtest, Mgood) 130 | 131 | C = np.ones((2, 2)) 132 | Mtest = material.stiffness(C) 133 | assert Mtest.ndim == 4 134 | assert Mtest.shape == (2, 2, 2, 2) 135 | np.testing.assert_almost_equal(Mtest, Mgood) 136 | 137 | C = 2 * np.eye(2) + 1 138 | Mtest = material.stiffness(C) 139 | assert Mtest.ndim == 4 140 | assert Mtest.shape == (2, 2, 2, 2) 141 | np.testing.assert_almost_equal(Mtest, Mgood) 142 | 143 | C = np.eye(2) + 1 144 | Mtest = material.stiffness(C) 145 | assert Mtest.ndim == 4 146 | assert Mtest.shape == (2, 2, 2, 2) 147 | np.testing.assert_almost_equal(Mtest, Mgood) 148 | 149 | C = np.eye(3) # No deformation at all 150 | Mgood = [ 151 | [ 152 | [[7, 0, 0], [0, 3, 0], [0, 0, 3]], 153 | [[0, 2, 0], [2, 0, 0], [0, 0, 0]], 154 | [[0, 0, 2], [0, 0, 0], [2, 0, 0]], 155 | ], 156 | [ 157 | [[0, 2, 0], [2, 0, 0], [0, 0, 0]], 158 | [[3, 0, 0], [0, 7, 0], [0, 0, 3]], 159 | [[0, 0, 0], [0, 0, 2], [0, 2, 0]], 160 | ], 161 | [ 162 | [[0, 0, 2], [0, 0, 0], [2, 0, 0]], 163 | [[0, 0, 0], [0, 0, 2], [0, 2, 0]], 164 | [[3, 0, 0], [0, 3, 0], [0, 0, 7]], 165 | ], 166 | ] 167 | Mgood = 5 * np.array(Mgood) 168 | Mtest = material.stiffness(C) 169 | assert Mtest.ndim == 4 170 | assert Mtest.shape == (3, 3, 3, 3) 171 | np.testing.assert_almost_equal(Mtest, Mgood) 172 | 173 | 174 | def test_NeoHookeanValues(): 175 | E = 210 176 | nu = 0.3 177 | G = 1050 / 13 178 | mu = 1050 / 13 179 | lamda = 1575 / 13 180 | material = elasticity.NeoHookeanElasticity(E, nu) 181 | assert material.E == pytest.approx(E) 182 | assert material.nu == pytest.approx(nu) 183 | assert material.G == pytest.approx(G) 184 | assert material.LAME1 == pytest.approx(lamda) 185 | assert material.LAME2 == pytest.approx(mu) 186 | 187 | E = 26 188 | nu = 0.3 189 | G = 10 190 | mu = 10 191 | lamda = 15 192 | material = elasticity.NeoHookeanElasticity(E, nu) 193 | assert material.E == pytest.approx(E) 194 | assert material.nu == pytest.approx(nu) 195 | assert material.G == pytest.approx(G) 196 | assert material.LAME1 == pytest.approx(lamda) 197 | assert material.LAME2 == pytest.approx(mu) 198 | 199 | E = 42 200 | nu = 0.4 201 | G = 15 202 | mu = 15 203 | lamda = 60 204 | material = elasticity.NeoHookeanElasticity(E, nu) 205 | assert material.E == pytest.approx(E) 206 | assert material.nu == pytest.approx(nu) 207 | assert material.G == pytest.approx(G) 208 | assert material.LAME1 == pytest.approx(lamda) 209 | assert material.LAME2 == pytest.approx(mu) 210 | 211 | 212 | def test_NeoHookeanPotential(): 213 | E = 52 214 | nu = 0.3 215 | material = elasticity.NeoHookeanElasticity(E, nu) 216 | 217 | C = np.eye(3) # No deformation at all 218 | phitest = material.potential(C) 219 | assert phitest == pytest.approx(0) 220 | 221 | C = np.eye(3) # No deformation at all 222 | phitest = material.potential(C) 223 | assert phitest == pytest.approx(0) 224 | 225 | C = 2 * np.eye(3) + 1 226 | phitest = material.potential(C) 227 | assert phitest == pytest.approx(63.6967217) 228 | 229 | C = np.eye(3) + 1 230 | phitest = material.potential(C) 231 | assert phitest == pytest.approx(23.3438516) 232 | 233 | 234 | def test_NeoHookeanStress(): 235 | E = 26 236 | nu = 0.3 237 | material = elasticity.NeoHookeanElasticity(E, nu) 238 | 239 | C = np.eye(2) # No deformation at all 240 | PK2test = material.stress(C) 241 | PK2good = np.zeros((2, 2)) 242 | assert PK2test.ndim == 2 243 | assert PK2test.shape == (2, 2) 244 | np.testing.assert_almost_equal(PK2test, PK2good) 245 | 246 | C = np.eye(3) # No deformation at all 247 | PK2test = material.stress(C) 248 | PK2good = np.zeros((3, 3)) 249 | assert PK2test.ndim == 2 250 | assert PK2test.shape == (3, 3) 251 | np.testing.assert_almost_equal(PK2test, PK2good) 252 | 253 | C = 0.1 * np.eye(2) + 1 254 | PK2test = material.stress(C) 255 | PK2good = [[-103.692, 103.356], [103.356, -103.692]] 256 | assert PK2test.ndim == 2 257 | assert PK2test.shape == (2, 2) 258 | np.testing.assert_almost_equal(PK2test, PK2good, decimal=3) 259 | 260 | C = 2 * np.eye(2) + 1 261 | PK2test = material.stress(C) 262 | PK2good = [[12.098, -0.699], [-0.699, 12.098]] 263 | assert PK2test.ndim == 2 264 | assert PK2test.shape == (2, 2) 265 | np.testing.assert_almost_equal(PK2test, PK2good, decimal=3) 266 | 267 | C = np.eye(2) + 1 268 | PK2test = material.stress(C) 269 | PK2good = [[8.826, 0.586], [0.586, 8.826]] 270 | assert PK2test.ndim == 2 271 | assert PK2test.shape == (2, 2) 272 | np.testing.assert_almost_equal(PK2test, PK2good, decimal=3) 273 | 274 | 275 | def test_NeoHookeanStiffness(): 276 | E = 26 277 | nu = 0.3 278 | material = elasticity.NeoHookeanElasticity(E, nu) 279 | 280 | C = np.eye(2) # No deformation at all 281 | Mgood = [ 282 | [[[7, 0], [0, 3]], [[0, 2], [2, 0]]], 283 | [[[0, 2], [2, 0]], [[3, 0], [0, 7]]], 284 | ] 285 | Mgood = 5 * np.array(Mgood) 286 | Mtest = material.stiffness(C) 287 | assert Mtest.ndim == 4 288 | assert Mtest.shape == (2, 2, 2, 2) 289 | np.testing.assert_almost_equal(Mtest, Mgood) 290 | 291 | C = 0.1 * np.eye(2) + 1 292 | Mgood = [ 293 | [ 294 | [[1602.624, -1456.93], [-1456.93, 1395.911]], 295 | [[-1456.93, 1427.839], [1427.839, -1456.93]], 296 | ], 297 | [ 298 | [[-1456.93, 1427.839], [1427.839, -1456.93]], 299 | [[1395.911, -1456.93], [-1456.93, 1602.624]], 300 | ], 301 | ] 302 | Mtest = material.stiffness(C) 303 | assert Mtest.ndim == 4 304 | assert Mtest.shape == (2, 2, 2, 2) 305 | np.testing.assert_almost_equal(Mtest, Mgood, decimal=2) 306 | 307 | C = 2 * np.eye(2) + 1 308 | Mgood = [ 309 | [ 310 | [[0.535, -0.178], [-0.178, 1.934]], 311 | [[-0.178, -0.639], [-0.639, -0.178]], 312 | ], 313 | [ 314 | [[-0.178, -0.639], [-0.639, -0.178]], 315 | [[1.934, -0.178], [-0.178, 0.535]], 316 | ], 317 | ] 318 | Mtest = material.stiffness(C) 319 | assert Mtest.ndim == 4 320 | assert Mtest.shape == (2, 2, 2, 2) 321 | np.testing.assert_almost_equal(Mtest, Mgood, decimal=3) 322 | 323 | C = np.eye(2) + 1 324 | Mgood = [ 325 | [ 326 | [[8.231, -4.115], [-4.115, 7.057]], 327 | [[-4.115, 2.644], [2.644, -4.115]], 328 | ], 329 | [ 330 | [[-4.115, 2.644], [2.644, -4.115]], 331 | [[7.057, -4.115], [-4.115, 8.231]], 332 | ], 333 | ] 334 | Mtest = material.stiffness(C) 335 | assert Mtest.ndim == 4 336 | assert Mtest.shape == (2, 2, 2, 2) 337 | np.testing.assert_almost_equal(Mtest, Mgood, decimal=3) 338 | 339 | C = np.eye(3) # No deformation at all 340 | Mgood = [ 341 | [ 342 | [[7, 0, 0], [0, 3, 0], [0, 0, 3]], 343 | [[0, 2, 0], [2, 0, 0], [0, 0, 0]], 344 | [[0, 0, 2], [0, 0, 0], [2, 0, 0]], 345 | ], 346 | [ 347 | [[0, 2, 0], [2, 0, 0], [0, 0, 0]], 348 | [[3, 0, 0], [0, 7, 0], [0, 0, 3]], 349 | [[0, 0, 0], [0, 0, 2], [0, 2, 0]], 350 | ], 351 | [ 352 | [[0, 0, 2], [0, 0, 0], [2, 0, 0]], 353 | [[0, 0, 0], [0, 0, 2], [0, 2, 0]], 354 | [[3, 0, 0], [0, 3, 0], [0, 0, 7]], 355 | ], 356 | ] 357 | Mgood = 5 * np.array(Mgood) 358 | Mtest = material.stiffness(C) 359 | assert Mtest.ndim == 4 360 | assert Mtest.shape == (3, 3, 3, 3) 361 | np.testing.assert_almost_equal(Mtest, Mgood) 362 | 363 | C = 2 * np.eye(3) + 0.5 364 | Mgood = [ 365 | [ 366 | [[-0.84, 0.14, 0.14], [0.14, 2.65, -0.55], [0.14, -0.55, 2.65]], 367 | [[0.14, -1.77, 0.33], [-1.77, 0.14, 0.33], [0.33, 0.33, -0.56]], 368 | [[0.14, 0.33, -1.77], [0.33, -0.56, 0.33], [-1.77, 0.33, 0.14]], 369 | ], 370 | [ 371 | [[0.14, -1.77, 0.33], [-1.77, 0.14, 0.33], [0.33, 0.33, -0.56]], 372 | [[2.66, 0.14, -0.56], [0.14, -0.84, 0.14], [-0.56, 0.14, 2.66]], 373 | [[-0.56, 0.33, 0.33], [0.33, 0.14, -1.77], [0.33, -1.77, 0.14]], 374 | ], 375 | [ 376 | [[0.14, 0.33, -1.77], [0.33, -0.56, 0.33], [-1.77, 0.33, 0.14]], 377 | [[-0.56, 0.33, 0.33], [0.33, 0.14, -1.77], [0.33, -1.77, 0.14]], 378 | [[2.66, -0.56, 0.14], [-0.56, 2.66, 0.14], [0.14, 0.14, -0.84]], 379 | ], 380 | ] 381 | Mtest = material.stiffness(C) 382 | assert Mtest.ndim == 4 383 | assert Mtest.shape == (3, 3, 3, 3) 384 | np.testing.assert_almost_equal(Mtest, Mgood, decimal=2) 385 | -------------------------------------------------------------------------------- /tests/test_fem.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # 3 | # Script to test kinematics of fem module 4 | # 5 | """ 6 | MNMNL Homework 7 | Module 3: kinematic tensor field on a mesh 8 | complete code below where indicated by 9 | # ============ 10 | # TODO: 11 | # ... 12 | # ============ 13 | 14 | Test your implementation of the fem.py module which uses tensor.py for the problem 15 | given in the exercise. 16 | You will test two types of meshes (with two refinements): 17 | - triangle-tri(14,56).msh with 14 and 56 triangular elements respectively 18 | - meshfile-quad(11,44).msh with 11 and 44 quadrangular elements respectively 19 | Compare your nodal and element fields with the anaylitical solution you have 20 | found in the exercise. 21 | """ 22 | 23 | import numpy as np 24 | 25 | from hyper import fem 26 | from hyper import gmsh2 as gmsh 27 | 28 | 29 | def vector_fct(x): 30 | """ 31 | Function that translates the position X into the vector U displacement 32 | Field: 33 | U(X1,X2) = X1*X2(a*e1 + b*e2) 34 | # for a=b=1 (Second and Third part of the exercise) 35 | """ 36 | a = b = 1 37 | f0 = a * x[0] * x[1] 38 | f1 = b * x[0] * x[1] 39 | return [f0, f1] 40 | 41 | 42 | def test_Tri14(): 43 | inputfilename = "tests/msh/triangle-tri14.msh" 44 | with open(inputfilename, "r") as meshfile: 45 | mesh = gmsh.gmshInput_mesh(meshfile) 46 | nNodes = mesh.nNodes() 47 | Nu = mesh.getDim() # Number of unknows by for each point 48 | U = np.zeros((nNodes, Nu)) # initializes array of zeros, 49 | for i in range(mesh.nNodes()): 50 | Nodei = mesh.getNode(i) 51 | Xi = Nodei.getX() 52 | U[i] = vector_fct(Xi) 53 | 54 | # Create FE model 55 | FE_model = fem.FEModel(mesh) 56 | 57 | # Compute deformation gradient and langrangian strain tensor fields 58 | FE_model.computeStrain(U) # compute gradient and strain 59 | F = [] # list of deformation gradient by element 60 | E = [] # list of lagrangian strain by element 61 | nElements = FE_model.nElements() 62 | for n in range(nElements): 63 | F.append(FE_model.getDeformationGradient(n).flatten()) 64 | E.append(FE_model.getStrainGreenLagrange(n).flatten()) 65 | 66 | outputfilename = inputfilename.replace(".msh", "-val.msh") 67 | with open(outputfilename, "w") as outputfile: 68 | gmsh.gmshOutput_mesh(outputfile, mesh) 69 | 70 | fieldname = "U: displacement field" 71 | gmsh.gmshOutput_nodal(outputfile, fieldname, U, it=0, t=0) 72 | 73 | fieldname = "F: Deformation Gradient" 74 | gmsh.gmshOutput_element(outputfile, fieldname, F, it=0, t=0) 75 | 76 | fieldname = "E: Strain Green Lagrange" 77 | gmsh.gmshOutput_element(outputfile, fieldname, E, it=0, t=0) 78 | 79 | 80 | def test_Tri56(): 81 | inputfilename = "tests/msh/triangle-tri56.msh" 82 | with open(inputfilename, "r") as meshfile: 83 | mesh = gmsh.gmshInput_mesh(meshfile) 84 | nNodes = mesh.nNodes() 85 | Nu = mesh.getDim() # Number of unknows by for each point 86 | U = np.zeros((nNodes, Nu)) # initializes array of zeros, 87 | for i in range(mesh.nNodes()): 88 | Nodei = mesh.getNode(i) 89 | Xi = Nodei.getX() 90 | U[i] = vector_fct(Xi) 91 | 92 | # Create FE model 93 | FE_model = fem.FEModel(mesh) 94 | 95 | # Compute deformation gradient and langrangian strain tensor fields 96 | FE_model.computeStrain(U) # compute gradient and strain 97 | F = [] # list of deformation gradient by element 98 | E = [] # list of lagrangian strain by element 99 | nElements = FE_model.nElements() 100 | for n in range(nElements): 101 | F.append(FE_model.getDeformationGradient(n).flatten()) 102 | E.append(FE_model.getStrainGreenLagrange(n).flatten()) 103 | 104 | outputfilename = inputfilename.replace(".msh", "-val.msh") 105 | with open(outputfilename, "w") as outputfile: 106 | gmsh.gmshOutput_mesh(outputfile, mesh) 107 | 108 | fieldname = "U: displacement field" 109 | gmsh.gmshOutput_nodal(outputfile, fieldname, U, it=0, t=0) 110 | 111 | fieldname = "F: Deformation Gradient" 112 | gmsh.gmshOutput_element(outputfile, fieldname, F, it=0, t=0) 113 | 114 | fieldname = "E: Strain Green Lagrange" 115 | gmsh.gmshOutput_element(outputfile, fieldname, E, it=0, t=0) 116 | 117 | 118 | def test_Quad11(): 119 | inputfilename = "tests/msh/triangle-quad11.msh" 120 | with open(inputfilename, "r") as meshfile: 121 | mesh = gmsh.gmshInput_mesh(meshfile) 122 | nNodes = mesh.nNodes() 123 | Nu = mesh.getDim() # Number of unknows by for each point 124 | U = np.zeros((nNodes, Nu)) # initializes array of zeros, 125 | for i in range(mesh.nNodes()): 126 | Nodei = mesh.getNode(i) 127 | Xi = Nodei.getX() 128 | U[i] = vector_fct(Xi) 129 | 130 | # Create FE model 131 | FE_model = fem.FEModel(mesh) 132 | 133 | # Compute deformation gradient and langrangian strain tensor fields 134 | FE_model.computeStrain(U) # compute gradient and strain 135 | F = [] # list of deformation gradient by element 136 | E = [] # list of lagrangian strain by element 137 | nElements = FE_model.nElements() 138 | for n in range(nElements): 139 | F.append(FE_model.getDeformationGradient(n).flatten()) 140 | E.append(FE_model.getStrainGreenLagrange(n).flatten()) 141 | 142 | outputfilename = inputfilename.replace(".msh", "-val.msh") 143 | with open(outputfilename, "w") as outputfile: 144 | gmsh.gmshOutput_mesh(outputfile, mesh) 145 | 146 | fieldname = "U: displacement field" 147 | gmsh.gmshOutput_nodal(outputfile, fieldname, U, it=0, t=0) 148 | 149 | fieldname = "F: Deformation Gradient" 150 | gmsh.gmshOutput_element(outputfile, fieldname, F, it=0, t=0) 151 | 152 | fieldname = "E: Strain Green Lagrange" 153 | gmsh.gmshOutput_element(outputfile, fieldname, E, it=0, t=0) 154 | 155 | 156 | def test_Quad44(): 157 | inputfilename = "tests/msh/triangle-quad44.msh" 158 | with open(inputfilename, "r") as meshfile: 159 | mesh = gmsh.gmshInput_mesh(meshfile) 160 | nNodes = mesh.nNodes() 161 | Nu = mesh.getDim() # Number of unknows by for each point 162 | U = np.zeros((nNodes, Nu)) # initializes array of zeros, 163 | for i in range(mesh.nNodes()): 164 | Nodei = mesh.getNode(i) 165 | Xi = Nodei.getX() 166 | U[i] = vector_fct(Xi) 167 | 168 | # Create FE model 169 | FE_model = fem.FEModel(mesh) 170 | 171 | # Compute deformation gradient and langrangian strain tensor fields 172 | FE_model.computeStrain(U) # compute gradient and strain 173 | F = [] # list of deformation gradient by element 174 | E = [] # list of lagrangian strain by element 175 | nElements = FE_model.nElements() 176 | for n in range(nElements): 177 | F.append(FE_model.getDeformationGradient(n).flatten()) 178 | E.append(FE_model.getStrainGreenLagrange(n).flatten()) 179 | 180 | outputfilename = inputfilename.replace(".msh", "-val.msh") 181 | with open(outputfilename, "w") as outputfile: 182 | gmsh.gmshOutput_mesh(outputfile, mesh) 183 | 184 | fieldname = "U: displacement field" 185 | gmsh.gmshOutput_nodal(outputfile, fieldname, U, it=0, t=0) 186 | 187 | fieldname = "F: Deformation Gradient" 188 | gmsh.gmshOutput_element(outputfile, fieldname, F, it=0, t=0) 189 | 190 | fieldname = "E: Strain Green Lagrange" 191 | gmsh.gmshOutput_element(outputfile, fieldname, E, it=0, t=0) 192 | -------------------------------------------------------------------------------- /tests/test_geometry.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | import numpy as np 4 | import pytest 5 | 6 | from hyper import geometry 7 | 8 | 9 | def getRandomPointTriangle(): 10 | # We want points (x, y) that satisfy 11 | # 0 <= x <= 1, 0 <= y <= 1 and (x+y) <= 1 12 | x = np.random.rand(1) 13 | y = np.random.rand(1) * (1 - x) 14 | return (x, y) 15 | 16 | 17 | def getRandomPointSquare(): 18 | # We want points (x, y) that satisfy 19 | # -1 <= x <= 1, -1 <= y <= 1 20 | x = 2 * np.random.rand(1) - 1 21 | y = 2 * np.random.rand(1) - 1 22 | return (x, y) 23 | 24 | 25 | def test_SumValuesSFT3(): 26 | Ntests = 100 27 | for i in range(Ntests): 28 | point = getRandomPointTriangle() 29 | Np = geometry.SFT3.N(point) 30 | assert np.sum(Np) == pytest.approx(1) 31 | 32 | 33 | def test_SumValuesSFT6(): 34 | Ntests = 100 35 | for i in range(Ntests): 36 | point = getRandomPointTriangle() 37 | Np = geometry.SFT6.N(point) 38 | assert np.sum(Np) == pytest.approx(1) 39 | 40 | 41 | def test_SumValuesSFQ4(): 42 | Ntests = 100 43 | for i in range(Ntests): 44 | point = getRandomPointTriangle() 45 | Np = geometry.SFQ4.N(point) 46 | assert np.sum(Np) == pytest.approx(1) 47 | 48 | 49 | def test_SumValuesSFQ8(): 50 | Ntests = 100 51 | for i in range(Ntests): 52 | point = getRandomPointTriangle() 53 | Np = geometry.SFQ8.N(point) 54 | assert np.sum(Np) == pytest.approx(1) 55 | 56 | 57 | def test_InterpolationSFT3(): 58 | Ps = geometry.SFT3.P() # Element's point 59 | n = len(Ps) # Number of points 60 | for i, Pi in enumerate(Ps): 61 | V = geometry.SFT3.N(Pi) 62 | for j in range(n): 63 | if i == j: 64 | assert V[j] == 1 65 | else: 66 | assert V[j] == 0 67 | 68 | 69 | def test_InterpolationSFT6(): 70 | Ps = geometry.SFT6.P() # Element's point 71 | n = len(Ps) # Number of points 72 | for i, Pi in enumerate(Ps): 73 | V = geometry.SFT6.N(Pi) 74 | for j in range(n): 75 | if i == j: 76 | assert V[j] == 1 77 | else: 78 | assert V[j] == 0 79 | 80 | 81 | def test_InterpolationSFQ4(): 82 | Ps = geometry.SFQ4.P() # Element's point 83 | n = len(Ps) # Number of points 84 | for i, Pi in enumerate(Ps): 85 | V = geometry.SFQ4.N(Pi) 86 | for j in range(n): 87 | if i == j: 88 | assert V[j] == 1 89 | else: 90 | assert V[j] == 0 91 | 92 | 93 | def test_InterpolationSFQ8(): 94 | Ps = geometry.SFQ8.P() # Element's point 95 | n = len(Ps) # Number of points 96 | for i, Pi in enumerate(Ps): 97 | V = geometry.SFQ8.N(Pi) 98 | for j in range(n): 99 | if i == j: 100 | assert V[j] == 1 101 | else: 102 | assert V[j] == 0 103 | 104 | 105 | def test_derivativeSFT3(): 106 | # For this function we have constant fields 107 | # So, doesn't matter the points, it's always the same 108 | # We test if it changes depending of the point 109 | Ntests = 100 110 | dNgood = [[-1, -1], [1, 0], [0, 1]] 111 | for i in range(Ntests): 112 | point = getRandomPointTriangle() 113 | dNtest = geometry.SFT3.dN(point) 114 | assert dNtest == dNgood 115 | 116 | 117 | def test_derivativeSFT6(): 118 | P = (0, 0) 119 | dNgood = [[-3, -3], [4, 0], [-1, 0], [0, 0], [0, -1], [0, 4]] 120 | dNtest = geometry.SFT6.dN(P) 121 | assert dNtest == dNgood 122 | 123 | P = (0.5, 0) 124 | dNgood = [[-1.0, -1.0], [0.0, -2.0], [1.0, 0], [0, 2.0], [0, -1], [0, 2.0]] 125 | dNtest = geometry.SFT6.dN(P) 126 | assert dNtest == dNgood 127 | 128 | P = (1, 0) 129 | dNgood = [[1, 1], [-4, -4], [3, 0], [0, 4], [0, -1], [0, 0]] 130 | dNtest = geometry.SFT6.dN(P) 131 | assert dNtest == dNgood 132 | 133 | P = (0, 0.5) 134 | dNgood = [[-1.0, -1.0], [2.0, 0], [-1, 0], [2.0, 0], [0, 1.0], [-2.0, 0.0]] 135 | dNtest = geometry.SFT6.dN(P) 136 | assert dNtest == dNgood 137 | 138 | P = (0.5, 0.5) 139 | dNgood = [ 140 | [1.0, 1.0], 141 | [-2.0, -2.0], 142 | [1.0, 0], 143 | [2.0, 2.0], 144 | [0, 1.0], 145 | [-2.0, -2.0], 146 | ] 147 | dNtest = geometry.SFT6.dN(P) 148 | assert dNtest == dNgood 149 | 150 | P = (0, 1) 151 | dNgood = [[1, 1], [0, 0], [-1, 0], [4, 0], [0, 3], [-4, -4]] 152 | dNtest = geometry.SFT6.dN(P) 153 | assert dNtest == dNgood 154 | 155 | P = (1 / 3, 1 / 3) 156 | dNgood = [ 157 | [-1 / 3, -1 / 3], 158 | [0, -4 / 3], 159 | [1 / 3, 0], 160 | [4 / 3, 4 / 3], 161 | [0, 1 / 3], 162 | [-4 / 3, 0], 163 | ] 164 | dNtest = geometry.SFT6.dN(P) 165 | np.testing.assert_almost_equal(dNtest, dNgood) 166 | 167 | 168 | def test_derivativeSFQ4(): 169 | P = (-1, -1) 170 | dNgood = [[-0.5, -0.5], [0.5, 0], [0, 0], [0, 0.5]] 171 | dNtest = geometry.SFQ4.dN(P) 172 | assert dNtest == dNgood 173 | 174 | P = (0, -1) 175 | dNgood = [[-0.5, -0.25], [0.5, -0.25], [0, 0.25], [0, 0.25]] 176 | dNtest = geometry.SFQ4.dN(P) 177 | assert dNtest == dNgood 178 | 179 | P = (1, -1) 180 | dNgood = [[-0.5, 0], [0.5, -0.5], [0, 0.5], [0, 0]] 181 | dNtest = geometry.SFQ4.dN(P) 182 | assert dNtest == dNgood 183 | 184 | P = (-1, 0) 185 | dNgood = [[-0.25, -0.5], [0.25, 0], [0.25, 0], [-0.25, 0.5]] 186 | dNtest = geometry.SFQ4.dN(P) 187 | assert dNtest == dNgood 188 | 189 | P = (0, 0) 190 | dNgood = [[-0.25, -0.25], [0.25, -0.25], [0.25, 0.25], [-0.25, 0.25]] 191 | dNtest = geometry.SFQ4.dN(P) 192 | assert dNtest == dNgood 193 | 194 | P = (1, 0) 195 | dNgood = [[-0.25, 0], [0.25, -0.5], [0.25, 0.5], [-0.25, 0]] 196 | dNtest = geometry.SFQ4.dN(P) 197 | assert dNtest == dNgood 198 | 199 | P = (-1, 1) 200 | dNgood = [[0, -0.5], [0, 0], [0.5, 0], [-0.5, 0.5]] 201 | dNtest = geometry.SFQ4.dN(P) 202 | assert dNtest == dNgood 203 | 204 | P = (0, 1) 205 | dNgood = [[0, -0.25], [0, -0.25], [0.5, 0.25], [-0.5, 0.25]] 206 | dNtest = geometry.SFQ4.dN(P) 207 | assert dNtest == dNgood 208 | 209 | P = (1, 1) 210 | dNgood = [[0, 0], [0, -0.5], [0.5, 0.5], [-0.5, 0]] 211 | dNtest = geometry.SFQ4.dN(P) 212 | assert dNtest == dNgood 213 | 214 | 215 | def test_derivativeSFQ8(): 216 | P = (-1, -1) 217 | dNtest = geometry.SFQ8.dN(P) 218 | dNgood = [ 219 | [-1.5, -1.5], 220 | [2, 0], 221 | [-0.5, 0], 222 | [0, 0], 223 | [0, 0], 224 | [0, 0], 225 | [0, -0.5], 226 | [0, 2], 227 | ] 228 | assert dNtest == dNgood 229 | 230 | P = (0, -1) 231 | dNtest = geometry.SFQ8.dN(P) 232 | dNgood = [ 233 | [-0.5, -0.5], 234 | [0, -0.5], 235 | [0.5, -0.5], 236 | [0, 1], 237 | [0, -0.5], 238 | [0, 0.5], 239 | [0, -0.5], 240 | [0, 1], 241 | ] 242 | assert dNtest == dNgood 243 | 244 | P = (1, -1) 245 | dNtest = geometry.SFQ8.dN(P) 246 | dNgood = [ 247 | [0.5, 0], 248 | [-2, 0], 249 | [1.5, -1.5], 250 | [0, 2], 251 | [0, -0.5], 252 | [0, 0], 253 | [0, 0], 254 | [0, 0], 255 | ] 256 | assert dNtest == dNgood 257 | 258 | P = (-1, 0) 259 | dNtest = geometry.SFQ8.dN(P) 260 | dNgood = [ 261 | [-0.5, -0.5], 262 | [1, 0], 263 | [-0.5, 0], 264 | [0.5, 0], 265 | [-0.5, 0], 266 | [1, 0], 267 | [-0.5, 0.5], 268 | [-0.5, 0], 269 | ] 270 | assert dNtest == dNgood 271 | 272 | P = (0, 0) 273 | dNtest = geometry.SFQ8.dN(P) 274 | dNgood = [ 275 | [0, 0], 276 | [0, -0.5], 277 | [0, 0], 278 | [0.5, 0], 279 | [0, 0], 280 | [0, 0.5], 281 | [0, 0], 282 | [-0.5, 0], 283 | ] 284 | assert dNtest == dNgood 285 | 286 | P = (1, 0) 287 | dNtest = geometry.SFQ8.dN(P) 288 | dNgood = [ 289 | [0.5, 0], 290 | [-1, 0], 291 | [0.5, -0.5], 292 | [0.5, 0], 293 | [0.5, 0.5], 294 | [-1, 0], 295 | [0.5, 0], 296 | [-0.5, 0], 297 | ] 298 | assert dNtest == dNgood 299 | 300 | P = (-1, 1) 301 | dNtest = geometry.SFQ8.dN(P) 302 | dNgood = [ 303 | [0, 0.5], 304 | [0, 0], 305 | [0, 0], 306 | [0, 0], 307 | [-0.5, 0], 308 | [2, 0], 309 | [-1.5, 1.5], 310 | [0, -2], 311 | ] 312 | assert dNtest == dNgood 313 | 314 | P = (0, 1) 315 | dNtest = geometry.SFQ8.dN(P) 316 | dNgood = [ 317 | [0, 0.5], 318 | [0, -0.5], 319 | [0, 0.5], 320 | [0, -1], 321 | [0.5, 0.5], 322 | [0, 0.5], 323 | [-0.5, 0.5], 324 | [0, -1], 325 | ] 326 | assert dNtest == dNgood 327 | 328 | P = (1, 1) 329 | dNtest = geometry.SFQ8.dN(P) 330 | dNgood = [ 331 | [0, 0], 332 | [0, 0], 333 | [0, 0.5], 334 | [0, -2], 335 | [1.5, 1.5], 336 | [-2, 0], 337 | [0.5, 0], 338 | [0, 0], 339 | ] 340 | assert dNtest == dNgood 341 | -------------------------------------------------------------------------------- /tests/test_mesh.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # 3 | # Script to test my_mesh module 4 | # 5 | """ 6 | MNMNL Homework 7 | Module 2: nodal field on a my_mesh complete code below where indicated by 8 | Carlos Adir ELY MURUSSI LEITE 9 | Clément FUCHS 10 | # ============ 11 | Test your implementation of the my_mesh.py module on two different meshes: 12 | - meshfile-tri8.msh with 8 triangular elements 13 | - meshfile-quad8.msh with 8 quadrangular elements 14 | Compare your nodal fields with the solution given in the my_mesh files: 15 | - meshfile-tri8-ref.msh with 8 triangular elements 16 | - meshfile-quad8-ref.msh with 8 quadrangular elements 17 | compare_meshfile.geo script, that must be opened with Gmsh. 18 | """ 19 | 20 | import numpy as np 21 | 22 | import hyper.gmsh2 as gmsh 23 | 24 | 25 | def scalar_fct(x): 26 | f = x[0] ** 2 + x[1] ** 2 27 | return f 28 | 29 | 30 | def vector_fct(x): 31 | fx = 2 * x[0] 32 | fy = -0.2 * x[1] 33 | return np.array((fx, fy)) 34 | 35 | 36 | def test_ReadTri8(): 37 | # Reading the mesh 38 | inputfilename = "tests/msh/meshfile-tri8.msh" 39 | with open(inputfilename, "r") as meshfile: 40 | mesh = gmsh.gmshInput_mesh(meshfile) 41 | 42 | # Testing the number of points and dimension 43 | assert mesh.nNodes() == 8 44 | assert mesh.getDim() == 2 45 | assert mesh.getNElements() == 8 46 | 47 | 48 | def test_ReadTri14(): 49 | # Reading the mesh 50 | inputfilename = "tests/msh/triangle-tri14.msh" 51 | with open(inputfilename, "r") as meshfile: 52 | mesh = gmsh.gmshInput_mesh(meshfile) 53 | 54 | # Testing the number of points and dimension 55 | assert mesh.nNodes() == 13 56 | assert mesh.getDim() == 2 57 | assert mesh.getNElements() == 14 58 | 59 | 60 | def test_ReadTri56(): 61 | # Reading the mesh 62 | inputfilename = "tests/msh/triangle-tri56.msh" 63 | with open(inputfilename, "r") as meshfile: 64 | mesh = gmsh.gmshInput_mesh(meshfile) 65 | 66 | assert mesh.nNodes() == 39 67 | assert mesh.getDim() == 2 68 | assert mesh.getNElements() == 56 69 | 70 | 71 | def test_ReadQuad8(): 72 | # Reading the mesh 73 | inputfilename = "tests/msh/meshfile-quad8.msh" 74 | with open(inputfilename, "r") as meshfile: 75 | mesh = gmsh.gmshInput_mesh(meshfile) 76 | 77 | # Testing the number of points and dimension 78 | assert mesh.nNodes() == 15 79 | assert mesh.getDim() == 2 80 | assert mesh.getNElements() == 8 81 | 82 | 83 | def test_ReadQuad11(): 84 | # Reading the mesh 85 | inputfilename = "tests/msh/triangle-quad11.msh" 86 | with open(inputfilename, "r") as meshfile: 87 | mesh = gmsh.gmshInput_mesh(meshfile) 88 | 89 | # Testing the number of points and dimension 90 | assert mesh.nNodes() == 16 91 | assert mesh.getDim() == 2 92 | assert mesh.getNElements() == 11 93 | 94 | 95 | def test_ReadQuad44(): 96 | # Reading the mesh 97 | inputfilename = "tests/msh/triangle-quad44.msh" 98 | with open(inputfilename, "r") as meshfile: 99 | mesh = gmsh.gmshInput_mesh(meshfile) 100 | 101 | # Testing the number of points and dimension 102 | assert mesh.nNodes() == 49 103 | assert mesh.getDim() == 2 104 | assert mesh.getNElements() == 44 105 | 106 | 107 | ############################################################ 108 | # TESTING THE POSITION OF NODES 109 | ################################################# 110 | 111 | 112 | def test_PositionNodesTri8(): 113 | # Reading the mesh 114 | inputfilename = "tests/msh/meshfile-tri8.msh" 115 | with open(inputfilename, "r") as meshfile: 116 | mesh = gmsh.gmshInput_mesh(meshfile) 117 | 118 | # Testing the position of the node 119 | nNodes = mesh.nNodes() 120 | dim = mesh.getDim() 121 | X = np.zeros((nNodes, dim)) 122 | for i in range(nNodes): 123 | Node_i = mesh.getNode(i) 124 | X[i] = Node_i.getX() 125 | Xgood = [ 126 | [0, 1, 1, 0, 0.5, 0.5, 0.25, 0.75], 127 | [0, 0, 0.3, 0.3, 0, 0.3, 0.15, 0.15], 128 | ] 129 | Xgood = np.array(Xgood).T 130 | np.testing.assert_almost_equal(X, Xgood) 131 | 132 | 133 | def test_PositionNodesQuad8(): 134 | inputfilename = "tests/msh/meshfile-quad8.msh" 135 | with open(inputfilename, "r") as meshfile: 136 | mesh = gmsh.gmshInput_mesh(meshfile) 137 | 138 | # Testing the position of the node 139 | nNodes = mesh.nNodes() 140 | dim = mesh.getDim() 141 | X = np.zeros((nNodes, dim)) 142 | for i in range(nNodes): 143 | Node_i = mesh.getNode(i) 144 | X[i] = Node_i.getX() 145 | Xgood = [ 146 | [0, 20, 20, 0, 5, 10, 15, 20, 15, 10, 5, 0, 10, 5, 15], 147 | [0, 0, 6, 6, 0, 0, 0, 3, 6, 6, 6, 3, 3, 3, 3], 148 | ] 149 | Xgood = np.array(Xgood).T / 20 150 | np.testing.assert_almost_equal(X, Xgood) 151 | 152 | 153 | # ################################################ 154 | # # TESTING FIELDS 155 | # ################################################ 156 | 157 | 158 | def test_FieldsTri8(): 159 | inputfilename = "tests/msh/meshfile-tri8.msh" 160 | with open(inputfilename, "r") as meshfile: 161 | mesh = gmsh.gmshInput_mesh(meshfile) 162 | nNodes = mesh.nNodes() 163 | dim = mesh.getDim() 164 | 165 | # Testing the scalar field 166 | V = np.zeros((nNodes, 1)) 167 | for i in range(nNodes): 168 | Node_i = mesh.getNode(i) 169 | X_i = Node_i.getX() 170 | V[i] = scalar_fct(X_i) 171 | 172 | # Testing the vectorial field 173 | U = np.zeros((nNodes, dim)) 174 | for i in range(nNodes): 175 | Node_i = mesh.getNode(i) 176 | X_i = Node_i.getX() 177 | U[i] = vector_fct(X_i) 178 | 179 | # Writting the results in a mesh 180 | outputfilename = inputfilename.replace(".msh", "-val.msh") 181 | with open(outputfilename, "w") as outputfile: 182 | # Write the base mesh 183 | gmsh.gmshOutput_mesh(outputfile, mesh) 184 | 185 | # Write scalar field 186 | gmsh.gmshOutput_nodal( 187 | outputfile, "scalar field", V, it=0, t=0.0 188 | ) # write nodal field 'V' 189 | 190 | # Write vectorial field 191 | gmsh.gmshOutput_nodal(outputfile, "VectorField", U, it=0, t=0) 192 | 193 | 194 | def test_FieldsQuad8(): 195 | inputfilename = "tests/msh/meshfile-quad8.msh" 196 | with open(inputfilename, "r") as meshfile: 197 | mesh = gmsh.gmshInput_mesh(meshfile) 198 | nNodes = mesh.nNodes() 199 | dim = mesh.getDim() 200 | 201 | # Testing the scalar field 202 | V = np.zeros((nNodes, 1)) 203 | for i in range(nNodes): 204 | Node_i = mesh.getNode(i) 205 | X_i = Node_i.getX() 206 | V[i] = scalar_fct(X_i) 207 | 208 | # Testing the vectorial field 209 | U = np.zeros((nNodes, dim)) 210 | for i in range(nNodes): 211 | Node_i = mesh.getNode(i) 212 | X_i = Node_i.getX() 213 | U[i] = vector_fct(X_i) 214 | 215 | # Writting the results in a mesh 216 | outputfilename = inputfilename.replace(".msh", "-val.msh") 217 | with open(outputfilename, "w") as outputfile: 218 | # Write the base mesh 219 | gmsh.gmshOutput_mesh(outputfile, mesh) 220 | 221 | # Write scalar field 222 | gmsh.gmshOutput_nodal( 223 | outputfile, "scalar field", V, it=0, t=0.0 224 | ) # write nodal field 'V' 225 | 226 | # Write vectorial field 227 | gmsh.gmshOutput_nodal(outputfile, "VectorField", U, it=0, t=0) 228 | -------------------------------------------------------------------------------- /tests/test_residual.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | """ 4 | 5 | 6 | import numpy as np 7 | 8 | from hyper import elasticity, fem 9 | from hyper import gmsh2 as gmsh 10 | 11 | 12 | def vector_fct(x): 13 | fx = x[0] * x[1] 14 | fy = x[0] * x[1] 15 | return [fx, fy] 16 | 17 | 18 | def applyFunctionToMeshNodes(mesh, function): 19 | nNodes = mesh.getNNodes() 20 | dim = mesh.getDim() 21 | U = np.zeros((nNodes, dim)) 22 | for i in range(nNodes): 23 | Nodei = mesh.getNode(i) 24 | Xi = Nodei.getX() 25 | U[i] = vector_fct(Xi) 26 | return U 27 | 28 | 29 | def computeTestValues(FEmodel, U): 30 | FEmodel.computeStress(U) 31 | F = [] 32 | P = [] 33 | nElements = FEmodel.getNElements() 34 | for n in range(nElements): 35 | new_P = FEmodel.getStressPK1(n) 36 | new_F = FEmodel.getDeformationGradient(n) 37 | F.append(new_F.flatten()) 38 | P.append(new_P.flatten()) 39 | R = FEmodel.computeResidual(U) 40 | return R, F, P 41 | 42 | 43 | def writeFieldsOnGmshFile(fields, mesh, filename): 44 | with open(filename, "w") as file: 45 | gmsh.gmshOutput_mesh(file, mesh) 46 | 47 | for fieldname, field in fields["nodal"]: 48 | gmsh.gmshOutput_nodal(file, fieldname, field, 0, 0.0) 49 | 50 | for fieldname, field in fields["element"]: 51 | gmsh.gmshOutput_element(file, fieldname, field, 0, 0.0) 52 | 53 | 54 | def test_Tri56StVenantKirchhoff(): 55 | inputfilename = "tests/msh/triangle-tri56.msh" 56 | outputfilename = "tests/msh/triangle-tri56-StVenant-val.msh" 57 | E = 210.0e9 58 | nu = 0.3 59 | material = elasticity.StVenantKirchhoffElasticity(E, nu) 60 | 61 | with open(inputfilename, "r") as meshfile: 62 | mesh = gmsh.gmshInput_mesh(meshfile) 63 | 64 | FEmodel = fem.FEModel(mesh, material) 65 | U = applyFunctionToMeshNodes(mesh, vector_fct) 66 | 67 | R, F, P = computeTestValues(FEmodel, U) 68 | 69 | fields = { 70 | "nodal": [("U: Displacement", U), ("R: Residual", R)], 71 | "element": [ 72 | ("F: Deformation Gradient", F), 73 | ("P: Engineering stress", P), 74 | ], 75 | } 76 | writeFieldsOnGmshFile(fields, mesh, outputfilename) 77 | 78 | 79 | def test_Quad44StVenantKirchhoff(): 80 | inputfilename = "tests/msh/triangle-quad44.msh" 81 | outputfilename = "tests/msh/triangle-quad44-StVenant-val.msh" 82 | E = 210.0e9 83 | nu = 0.3 84 | material = elasticity.StVenantKirchhoffElasticity(E, nu) 85 | 86 | with open(inputfilename, "r") as meshfile: 87 | mesh = gmsh.gmshInput_mesh(meshfile) 88 | 89 | FEmodel = fem.FEModel(mesh, material) 90 | U = applyFunctionToMeshNodes(mesh, vector_fct) 91 | 92 | R, F, P = computeTestValues(FEmodel, U) 93 | 94 | fields = { 95 | "nodal": [("U: Displacement", U), ("R: Residual", R)], 96 | "element": [ 97 | ("F: Deformation Gradient", F), 98 | ("P: Engineering stress", P), 99 | ], 100 | } 101 | writeFieldsOnGmshFile(fields, mesh, outputfilename) 102 | 103 | 104 | def test_Tri56NeoHookean(): 105 | inputfilename = "tests/msh/triangle-tri56.msh" 106 | outputfilename = "tests/msh/triangle-tri56-NeoHookean-val.msh" 107 | E = 10.0e6 108 | nu = 0.45 109 | material = elasticity.StVenantKirchhoffElasticity(E, nu) 110 | 111 | with open(inputfilename, "r") as meshfile: 112 | mesh = gmsh.gmshInput_mesh(meshfile) 113 | 114 | FEmodel = fem.FEModel(mesh, material) 115 | U = applyFunctionToMeshNodes(mesh, vector_fct) 116 | 117 | R, F, P = computeTestValues(FEmodel, U) 118 | 119 | fields = { 120 | "nodal": [("U: Displacement", U), ("R: Residual", R)], 121 | "element": [ 122 | ("F: Deformation Gradient", F), 123 | ("P: Engineering stress", P), 124 | ], 125 | } 126 | writeFieldsOnGmshFile(fields, mesh, outputfilename) 127 | 128 | 129 | def test_Quad44NeoHookean(): 130 | inputfilename = "tests/msh/triangle-tri56.msh" 131 | outputfilename = "tests/msh/triangle-tri56-NeoHookean-val.msh" 132 | E = 10.0e6 133 | nu = 0.45 134 | material = elasticity.StVenantKirchhoffElasticity(E, nu) 135 | 136 | with open(inputfilename, "r") as meshfile: 137 | mesh = gmsh.gmshInput_mesh(meshfile) 138 | 139 | FEmodel = fem.FEModel(mesh, material) 140 | U = applyFunctionToMeshNodes(mesh, vector_fct) 141 | 142 | R, F, P = computeTestValues(FEmodel, U) 143 | 144 | fields = { 145 | "nodal": [("U: Displacement", U), ("R: Residual", R)], 146 | "element": [ 147 | ("F: Deformation Gradient", F), 148 | ("P: Engineering stress", P), 149 | ], 150 | } 151 | writeFieldsOnGmshFile(fields, mesh, outputfilename) 152 | 153 | 154 | # def compare_results(self): 155 | # """ 156 | # Not completed, but it should make the comparation between the calculated results (put inside output file) and the reference results (inside reference file). 157 | # For the instant, we don't have a way to comparate the mesh. 158 | # """ 159 | # output_filename = self.filename.replace(".msh", "") + '-val.msh' 160 | # reference_filename = self.filename.replace(".msh", "") + '-ref.msh' 161 | 162 | # reference_file = open(reference_filename, 'r') 163 | # self.reference_mesh = gmsh.gmshInput_mesh(reference_file) 164 | # reference_file.close() 165 | 166 | # output_file = open(output_filename, 'r') 167 | # self.output_mesh = gmsh.gmshInput_mesh(output_file) 168 | # output_file.close() 169 | 170 | 171 | # Mesh libraries 172 | # open3d, plyfile, pymesh, pygmsh, meshio 173 | # https://newbedev.com/python-plyfile-vs-pymesh 174 | -------------------------------------------------------------------------------- /tests/test_tangent.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | # Script to test implementation of the internal tangent matrix in fem.py module 4 | 5 | """ 6 | 7 | import numpy as np 8 | 9 | from hyper import elasticity, fem 10 | from hyper import gmsh2 as gmsh 11 | 12 | 13 | def vector_fct(x): 14 | fx = x[0] * x[1] 15 | fy = x[0] * x[1] 16 | return [fx, fy] 17 | 18 | 19 | def applyFunctionToMeshNodes(mesh, function): 20 | nNodes = mesh.getNNodes() 21 | dim = mesh.getDim() 22 | U = np.zeros((nNodes, dim)) 23 | for i in range(nNodes): 24 | Nodei = mesh.getNode(i) 25 | Xi = Nodei.getX() 26 | U[i] = vector_fct(Xi) 27 | return U 28 | 29 | 30 | def computeKnum(FEmodel, U, DU=1e-5): 31 | nNodes, dim = U.shape 32 | Knum = np.zeros((nNodes, dim, nNodes, dim)) 33 | Ud = np.copy(U) 34 | 35 | for i in range(nNodes): 36 | for j in range(dim): 37 | Ud[i, j] += DU / 2.0 38 | # R(U_nj + DU/2), residual "plus" 39 | Rp = FEmodel.computeResidual(Ud) 40 | 41 | Ud[i, j] -= DU 42 | # R(U_nj - DU/2), residual "minus" 43 | Rm = FEmodel.computeResidual(Ud) 44 | 45 | # come back to before perturbation for next iterations 46 | Ud[i, j] += DU / 2 47 | Knum[i, j] = (Rp - Rm) / DU 48 | return Knum 49 | 50 | 51 | def test_Quad11StVenantKirchhoff(): 52 | inputfilename = "tests/msh/triangle-quad11.msh" 53 | E = 210.0e9 54 | nu = 0.3 55 | material = elasticity.StVenantKirchhoffElasticity(E, nu) 56 | 57 | with open(inputfilename, "r") as meshfile: 58 | mesh = gmsh.gmshInput_mesh(meshfile) 59 | 60 | FEmodel = fem.FEModel(mesh, material) 61 | U = applyFunctionToMeshNodes(mesh, vector_fct) 62 | K = FEmodel.computeTangent(U) 63 | Knum = computeKnum(FEmodel, U) 64 | 65 | np.testing.assert_allclose(K, Knum) 66 | 67 | 68 | def test_Quad44StVenantKirchhoff(): 69 | inputfilename = "tests/msh/triangle-quad44.msh" 70 | E = 210.0e9 71 | nu = 0.3 72 | material = elasticity.StVenantKirchhoffElasticity(E, nu) 73 | 74 | with open(inputfilename, "r") as meshfile: 75 | mesh = gmsh.gmshInput_mesh(meshfile) 76 | 77 | FEmodel = fem.FEModel(mesh, material) 78 | U = applyFunctionToMeshNodes(mesh, vector_fct) 79 | K = FEmodel.computeTangent(U) 80 | Knum = computeKnum(FEmodel, U) 81 | 82 | np.testing.assert_allclose(K, Knum) 83 | 84 | 85 | def test_Quad11NeoHookean(): 86 | inputfilename = "tests/msh/triangle-quad11.msh" 87 | E = 210.0e9 88 | nu = 0.3 89 | material = elasticity.StVenantKirchhoffElasticity(E, nu) 90 | 91 | with open(inputfilename, "r") as meshfile: 92 | mesh = gmsh.gmshInput_mesh(meshfile) 93 | 94 | FEmodel = fem.FEModel(mesh, material) 95 | U = applyFunctionToMeshNodes(mesh, vector_fct) 96 | K = FEmodel.computeTangent(U) 97 | Knum = computeKnum(FEmodel, U) 98 | 99 | np.testing.assert_allclose(K, Knum) 100 | 101 | 102 | def test_Quad44NeoHookean(): 103 | inputfilename = "tests/msh/triangle-quad44.msh" 104 | E = 210.0e9 105 | nu = 0.3 106 | material = elasticity.StVenantKirchhoffElasticity(E, nu) 107 | 108 | with open(inputfilename, "r") as meshfile: 109 | mesh = gmsh.gmshInput_mesh(meshfile) 110 | 111 | FEmodel = fem.FEModel(mesh, material) 112 | U = applyFunctionToMeshNodes(mesh, vector_fct) 113 | K = FEmodel.computeTangent(U) 114 | Knum = computeKnum(FEmodel, U) 115 | 116 | np.testing.assert_allclose(K, Knum) 117 | -------------------------------------------------------------------------------- /tests/test_tensor.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | import numpy as np 3 | 4 | from hyper import tensor 5 | 6 | 7 | def test_vector(): 8 | # Testing creation 9 | vectest = tensor.vector() 10 | assert type(vectest) is np.ndarray 11 | 12 | # Testing attribution of individual values 13 | vectest[0] = 1.0 14 | vectest[1] = 2.0 15 | assert type(vectest) is np.ndarray 16 | assert vectest.ndim == 1 17 | assert vectest.shape == (2,) 18 | np.testing.assert_array_equal(vectest, [1, 2]) 19 | 20 | # Testing attribution of array values 21 | vectest[:] = [3, 4] 22 | assert type(vectest) is np.ndarray 23 | assert vectest.ndim == 1 24 | assert vectest.shape == (2,) 25 | np.testing.assert_array_equal(vectest, [3, 4]) 26 | 27 | # Testing dim = 3 array 28 | vectest = tensor.vector(3) 29 | vectest[:] = [-1, 2, 1] 30 | assert type(vectest) is np.ndarray 31 | assert vectest.ndim == 1 32 | assert vectest.shape == (3,) 33 | np.testing.assert_array_equal(vectest, [-1, 2, 1]) 34 | 35 | 36 | def test_tensor(): 37 | # Testing tensor with dim = 2 38 | Mtest = tensor.tensor() 39 | assert type(Mtest) is np.ndarray 40 | assert Mtest.ndim == 2 41 | assert Mtest.shape == (2, 2) 42 | 43 | # Testing tensor with dim = 3 44 | Mtest = tensor.tensor(3) 45 | assert type(Mtest) is np.ndarray 46 | assert Mtest.ndim == 2 47 | np.testing.assert_array_equal(Mtest.shape, (3, 3)) 48 | 49 | 50 | def test_I(): 51 | Itest = tensor.I() 52 | Igood = [[1, 0], [0, 1]] 53 | assert type(Itest) is np.ndarray 54 | assert Itest.shape == (2, 2) 55 | np.testing.assert_array_equal(Itest, Igood) 56 | 57 | Itest = tensor.I(3) 58 | Igood = [[1, 0, 0], [0, 1, 0], [0, 0, 1]] 59 | assert type(Itest) is np.ndarray 60 | assert Itest.shape == (3, 3) 61 | np.testing.assert_array_equal(Itest, Igood) 62 | 63 | 64 | def test_outerProd(): 65 | v = [1, 2] 66 | Mgood = [[1, 2], [2, 4]] 67 | Mtest = tensor.outerProd(v, v) 68 | assert Mtest.ndim == 2 69 | assert Mtest.shape == (2, 2) 70 | np.testing.assert_array_equal(Mtest, Mgood) 71 | 72 | 73 | def test_det(): 74 | M = [[1, 2], [2, 4]] 75 | detgood = 0 76 | dettest = tensor.det(M) 77 | assert dettest == detgood 78 | 79 | M = [[1, 2], [2, 5]] 80 | detgood = 1 81 | dettest = tensor.det(M) 82 | assert dettest == detgood 83 | 84 | 85 | def test_trace(): 86 | M = [[1, 2], [2, 4]] 87 | trgood = 5 88 | trtest = tensor.trace(M) 89 | assert trtest == trgood 90 | 91 | M = [[1, 2], [2, 5]] 92 | trgood = 6 93 | trtest = tensor.trace(M) 94 | assert trtest == trgood 95 | 96 | 97 | def test_inv(): 98 | M = [[1, 0], [0, 1]] 99 | Vgood = [[1, 0], [0, 1]] 100 | Vtest = tensor.inv(M) 101 | assert Vtest.ndim == 2 102 | assert Vtest.shape == (2, 2) 103 | np.testing.assert_array_equal(Vtest, Vgood) 104 | 105 | M = [[2, 3], [2, 5]] 106 | Vgood = [[1.25, -0.75], [-0.5, 0.5]] 107 | Vtest = tensor.inv(M) 108 | assert Vtest.ndim == 2 109 | assert Vtest.shape == (2, 2) 110 | np.testing.assert_array_equal(Vtest, Vgood) 111 | 112 | 113 | def test_rightCauchyGreen(): 114 | F = [[2, 3], [2, 5]] 115 | Cgood = [[8, 16], [16, 34]] 116 | Ctest = tensor.rightCauchyGreen(F) 117 | assert Ctest.ndim == 2 118 | assert Ctest.shape == (2, 2) 119 | np.testing.assert_array_equal(Ctest, Cgood) 120 | 121 | 122 | def test_leftCauchyGreen(): 123 | F = [[2, 3], [2, 5]] 124 | Bgood = [[13, 19], [19, 29]] 125 | Btest = tensor.leftCauchyGreen(F) 126 | assert Btest.ndim == 2 127 | assert Btest.shape == (2, 2) 128 | np.testing.assert_array_equal(Btest, Bgood) 129 | 130 | 131 | def test_tensor4(): 132 | Mtest = tensor.tensor4() 133 | assert Mtest.ndim == 4 134 | assert Mtest.shape == (2, 2, 2, 2) 135 | assert np.sum(Mtest) == 0 136 | 137 | Mtest = tensor.tensor4(3) 138 | assert Mtest.ndim == 4 139 | assert Mtest.shape == (3, 3, 3, 3) 140 | assert np.sum(Mtest) == 0 141 | 142 | 143 | def test_II(): 144 | IIgood = [ 145 | [[[1, 0], [0, 0]], [[0, 1], [0, 0]]], 146 | [[[0, 0], [1, 0]], [[0, 0], [0, 1]]], 147 | ] 148 | IItest = tensor.II() 149 | assert IItest.ndim == 4 150 | assert IItest.shape == (2, 2, 2, 2) 151 | np.testing.assert_array_equal(IItest, IIgood) 152 | 153 | 154 | def test_IISym(): 155 | IItest = tensor.IISym() 156 | IIgood = [ 157 | [[[1, 0], [0, 0]], [[0, 0.5], [0.5, 0]]], 158 | [[[0, 0.5], [0.5, 0]], [[0, 0], [0, 1]]], 159 | ] 160 | assert IItest.ndim == 4 161 | assert IItest.shape == (2, 2, 2, 2) 162 | np.testing.assert_array_equal(IItest, IIgood) 163 | 164 | 165 | def test_KK(): 166 | KKtest = tensor.KK() 167 | KKgood = [ 168 | [[[1, 0], [0, 1]], [[0, 0], [0, 0]]], 169 | [[[0, 0], [0, 0]], [[1, 0], [0, 1]]], 170 | ] 171 | assert KKtest.ndim == 4 172 | assert KKtest.shape == (2, 2, 2, 2) 173 | np.testing.assert_array_equal(KKtest, KKgood) 174 | 175 | 176 | def test_outerProd4(): 177 | C = [[8, 16], [16, 34]] 178 | Mgood = [ 179 | [[[64, 128], [128, 272]], [[128, 256], [256, 544]]], 180 | [[[128, 256], [256, 544]], [[272, 544], [544, 1156]]], 181 | ] 182 | Mtest = tensor.outerProd4(C, C) 183 | assert Mtest.ndim == 4 184 | assert Mtest.shape == (2, 2, 2, 2) 185 | np.testing.assert_array_equal(Mtest, Mgood) 186 | -------------------------------------------------------------------------------- /tox.ini: -------------------------------------------------------------------------------- 1 | [tox] 2 | isolated_build = True 3 | envlist = 4 | python3.9, 5 | python3.10, 6 | 7 | [testenv] 8 | deps = 9 | numpy 10 | scipy 11 | gmsh 12 | pytest 13 | commands = 14 | pytest . 15 | 16 | [gh-actions] 17 | python = 18 | 3.9: py39 19 | 3.10: py310 20 | 21 | [testenv:format] 22 | deps = 23 | numpy 24 | scipy 25 | gmsh 26 | black 27 | isort 28 | commands = 29 | isort --check src/hyper 30 | black --check src/hyper 31 | --------------------------------------------------------------------------------