-
Notifications
You must be signed in to change notification settings - Fork 11
Commit
- Loading branch information
There are no files selected for viewing
Large diffs are not rendered by default.
Large diffs are not rendered by default.
Large diffs are not rendered by default.
Large diffs are not rendered by default.
Large diffs are not rendered by default.
Large diffs are not rendered by default.
Large diffs are not rendered by default.
Large diffs are not rendered by default.
Large diffs are not rendered by default.
Large diffs are not rendered by default.
Large diffs are not rendered by default.
Large diffs are not rendered by default.
Large diffs are not rendered by default.
Large diffs are not rendered by default.
Large diffs are not rendered by default.
Large diffs are not rendered by default.
Large diffs are not rendered by default.
Large diffs are not rendered by default.
Large diffs are not rendered by default.
Large diffs are not rendered by default.
Large diffs are not rendered by default.
Large diffs are not rendered by default.
Large diffs are not rendered by default.
Large diffs are not rendered by default.
Large diffs are not rendered by default.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,271 @@ | ||
{ | ||
"cells": [ | ||
{ | ||
"cell_type": "markdown", | ||
"id": "5dc5bf2d", | ||
"metadata": {}, | ||
"source": [ | ||
"# Implementation of Finite Elements\n", | ||
"\n", | ||
"This lecture shows how to implement our own finite elements in C++,\n", | ||
"and how to use them within the NGSolve language. We implement first order and second order triangular finite elements.\n", | ||
"\n", | ||
"The finite element is implemented in small package on github: \n", | ||
"[https://github.com/TUWien-ASC/NGS-myfe](https://github.com/TUWien-ASC/NGS-myfe)\n", | ||
"\n", | ||
"* basis functions are implemented in myelement.cpp/hpp\n", | ||
"* the transformation from reference-element to physical elements in in mydiffop.hpp\n", | ||
"* the connectivity is implemented in the `FESpace` in myfespace.cpp/hpp\n", | ||
"* the Python-bindings are in mymodule.cpp" | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": 1, | ||
"id": "fb29e374", | ||
"metadata": {}, | ||
"outputs": [ | ||
{ | ||
"name": "stdout", | ||
"output_type": "stream", | ||
"text": [ | ||
"Loading libmyfe library\n" | ||
] | ||
} | ||
], | ||
"source": [ | ||
"from ngsolve import *\n", | ||
"from ngsolve.webgui import Draw\n", | ||
"from libmyfe import *\n", | ||
"mesh = Mesh(unit_square.GenerateMesh(maxh=0.2, quad_dominated=False))" | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"id": "74066dcd", | ||
"metadata": {}, | ||
"source": [ | ||
"We can now create an instance of our own finite element space:" | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": 3, | ||
"id": "122e9720", | ||
"metadata": {}, | ||
"outputs": [ | ||
{ | ||
"name": "stdout", | ||
"output_type": "stream", | ||
"text": [ | ||
"Constructor of MyFESpace\n", | ||
"Flags = secondorder = 1\n", | ||
"secondorder\n", | ||
"dirichlet = 0: 1\n", | ||
"1: 3\n", | ||
"2: 4\n", | ||
"\n", | ||
"\n", | ||
"You have chosen second order elements\n", | ||
"Update MyFESpace, #vert = 39, #edge = 94\n" | ||
] | ||
} | ||
], | ||
"source": [ | ||
"fes = MyFESpace(mesh, secondorder=True, dirichlet=\"left|bottom|top\")" | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"id": "23837763", | ||
"metadata": {}, | ||
"source": [ | ||
"and use it within NGSolve such as the builtin finite element spaces:" | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": 4, | ||
"id": "627a9cfb", | ||
"metadata": {}, | ||
"outputs": [ | ||
{ | ||
"name": "stdout", | ||
"output_type": "stream", | ||
"text": [ | ||
"ndof = 133\n" | ||
] | ||
} | ||
], | ||
"source": [ | ||
"print (\"ndof = \", fes.ndof)" | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": 5, | ||
"id": "ae0deee7", | ||
"metadata": {}, | ||
"outputs": [ | ||
{ | ||
"data": { | ||
"application/vnd.jupyter.widget-view+json": { | ||
"model_id": "caf94b64283e48149e05292ef58c4bc0", | ||
"version_major": 2, | ||
"version_minor": 0 | ||
}, | ||
"text/plain": [ | ||
"WebGuiWidget(layout=Layout(height='50vh', width='100%'), value={'gui_settings': {}, 'ngsolve_version': '6.2.24…" | ||
] | ||
}, | ||
"metadata": {}, | ||
"output_type": "display_data" | ||
}, | ||
{ | ||
"data": { | ||
"application/vnd.jupyter.widget-view+json": { | ||
"model_id": "13271b2614e74350ab92e97d0976bfc0", | ||
"version_major": 2, | ||
"version_minor": 0 | ||
}, | ||
"text/plain": [ | ||
"WebGuiWidget(layout=Layout(height='50vh', width='100%'), value={'gui_settings': {}, 'ngsolve_version': '6.2.24…" | ||
] | ||
}, | ||
"metadata": {}, | ||
"output_type": "display_data" | ||
} | ||
], | ||
"source": [ | ||
"gfu = GridFunction(fes)\n", | ||
"gfu.Set(x*y)\n", | ||
"\n", | ||
"Draw (gfu)\n", | ||
"Draw (grad(gfu)[0], mesh);" | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"id": "b93211e8", | ||
"metadata": {}, | ||
"source": [ | ||
"and solve the standard problem:" | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": 6, | ||
"id": "5402e517", | ||
"metadata": { | ||
"scrolled": true | ||
}, | ||
"outputs": [ | ||
{ | ||
"data": { | ||
"application/vnd.jupyter.widget-view+json": { | ||
"model_id": "d0797c3ccb57429fa5790d8da899ecee", | ||
"version_major": 2, | ||
"version_minor": 0 | ||
}, | ||
"text/plain": [ | ||
"WebGuiWidget(layout=Layout(height='50vh', width='100%'), value={'gui_settings': {}, 'ngsolve_version': '6.2.24…" | ||
] | ||
}, | ||
"metadata": {}, | ||
"output_type": "display_data" | ||
} | ||
], | ||
"source": [ | ||
"u,v = fes.TnT()\n", | ||
"a = BilinearForm(grad(u)*grad(v)*dx).Assemble()\n", | ||
"f = LinearForm(1*v*dx).Assemble()\n", | ||
"gfu.vec.data = a.mat.Inverse(fes.FreeDofs())*f.vec\n", | ||
"Draw (gfu);" | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"id": "bfc19b37", | ||
"metadata": {}, | ||
"source": [ | ||
"Draw basis functions:" | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": null, | ||
"id": "a735336a", | ||
"metadata": {}, | ||
"outputs": [], | ||
"source": [ | ||
"gfu.vec[:] = 0\n", | ||
"gfu.vec[mesh.nv-3] = 1\n", | ||
"gfu.vec[fes.ndof-1] = 1\n", | ||
"Draw (gfu, order=2);" | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"id": "8edb5e20", | ||
"metadata": {}, | ||
"source": [ | ||
"Documentation provided in the DocInfo structure is available in Python - help. Look for 'secondorder'." | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": null, | ||
"id": "89d8a842", | ||
"metadata": {}, | ||
"outputs": [], | ||
"source": [ | ||
"help (m.MyFESpace)" | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"id": "ad3d3978", | ||
"metadata": {}, | ||
"source": [ | ||
"**Exercises:**\n", | ||
"\n", | ||
"Extend MyFESpace by the following 1st and 2nd order elements:\n", | ||
"\n", | ||
"- 1D finite elements (ET_SEGM), as needed for boundary conditions\n", | ||
"- quadrilateral elements (ET_QUAD), use geom.GenerateMesh(quad_dominated=True)\n", | ||
"- tetrahedral elements (ET_TET), test it for 3D domains\n", | ||
"\n", | ||
"Next, implement 3rd order elements" | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": null, | ||
"id": "7c1edee8", | ||
"metadata": {}, | ||
"outputs": [], | ||
"source": [] | ||
} | ||
], | ||
"metadata": { | ||
"kernelspec": { | ||
"display_name": "Python 3 (ipykernel)", | ||
"language": "python", | ||
"name": "python3" | ||
}, | ||
"language_info": { | ||
"codemirror_mode": { | ||
"name": "ipython", | ||
"version": 3 | ||
}, | ||
"file_extension": ".py", | ||
"mimetype": "text/x-python", | ||
"name": "python", | ||
"nbconvert_exporter": "python", | ||
"pygments_lexer": "ipython3", | ||
"version": "3.12.2" | ||
} | ||
}, | ||
"nbformat": 4, | ||
"nbformat_minor": 5 | ||
} |