mirror of
https://github.com/JuliaFEM/JuliaFEM.jl.git
synced 2026-09-23 02:59:52 +00:00
777 lines
19 KiB
Plaintext
777 lines
19 KiB
Plaintext
{
|
|
"cells": [
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"# Developing JuliaFEM\n",
|
|
"\n",
|
|
"Author(s): Jukka Aho\n",
|
|
"\n",
|
|
"**Abstract**: General developer notes."
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 1,
|
|
"metadata": {
|
|
"collapsed": false
|
|
},
|
|
"outputs": [
|
|
{
|
|
"data": {
|
|
"text/plain": [
|
|
"Logger(root,DEBUG,PipeEndpoint(open, 0 bytes waiting),root)"
|
|
]
|
|
},
|
|
"execution_count": 1,
|
|
"metadata": {},
|
|
"output_type": "execute_result"
|
|
}
|
|
],
|
|
"source": [
|
|
"using Logging\n",
|
|
"using FactCheck\n",
|
|
"Logging.configure(level=DEBUG)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"## Developing own element\n",
|
|
"\n",
|
|
"Finite element definition, from [FEniCS-book](https://bitbucket.org/fenics-project/fenics-book/src/7d3a80e7dda0fc279c7964dc6000d57942f11eb3/fenicsbook.cls?at=master) [Ciarlet, 2002]:\n",
|
|
"\n",
|
|
"- the domain $T$ is a bounded, closed subset of $\\mathbb{R}^d$ (for $d = 1, 2, 3, \\dots$) with nonempty interior and piecewise smooth boundary;\n",
|
|
"- the space $\\mathcal{V} = \\mathcal{V}(T)$ is a finite dimensional function space on $T$ of dimension $n$;\n",
|
|
"- the set of degrees of freedom (nodes) $\\mathcal{L} = \\{\\ell_1, \\ell_2,\\ldots, \\ell_{n}\\}$ is a basis for the dual space $\\mathcal{V}'$; that is, the space of bounded linear functionals on $\\mathcal{V}$.\n",
|
|
"\n",
|
|
"We extend this definition so that domain $T$ can also be empty.\n",
|
|
"\n",
|
|
"Minimum requirements for element:\n",
|
|
"- subclass from Element, if not wanting to implement everything by youself\n",
|
|
"- define basis and partial derivatives of it, because we need to interpolate over it\n",
|
|
"- give connectivity information, how this element is connected to other elements\n",
|
|
"- create proper constructor (see example).\n",
|
|
"\n",
|
|
"Test the element using ``test_element`` function. It it passes, then element implementation should be fine. As an example, we define 4 node quadrilateral element using linear Lagrange basis. We really don't care much how element is implemented as long it's interface is constructed with some rules. The interface is tested using `test_element` and it also gives information how to fix element if something is missing."
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 2,
|
|
"metadata": {
|
|
"collapsed": false
|
|
},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"Creating element Point1: 1 node point element\n",
|
|
"Creating element Seg2: 2 node linear line element\n",
|
|
"Creating Lagrange basis for element Seg2. Number of basis functions: 2. Element dimension: 1\n",
|
|
"Calculating inverse of A\n"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"using JuliaFEM: Element"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"Here's one basic implementation. The actual element:"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 3,
|
|
"metadata": {
|
|
"collapsed": false
|
|
},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"Element JuliaFEM.Seg2 created.\n",
|
|
"Creating element Seg3: 3 node quadratic line element\n",
|
|
"Creating Lagrange basis for element Seg3. Number of basis functions: 3. Element dimension: 1\n",
|
|
"Calculating inverse of A\n",
|
|
"Element JuliaFEM.Seg3 created.\n",
|
|
"Creating element Quad4: 4 node bilinear quadrangle element\n",
|
|
"Creating Lagrange basis for element Quad4. Number of basis functions: 4. Element dimension: 2\n",
|
|
"Calculating inverse of A\n",
|
|
"Element JuliaFEM.Quad4 created.\n",
|
|
"Creating element Tet10: 10 node quadratic tetrahedron\n",
|
|
"Creating Lagrange basis for element Tet10. Number of basis functions: 10. Element dimension: 3\n",
|
|
"Calculating inverse of A\n",
|
|
"Element JuliaFEM.Tet10 created.\n"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"type MyQuad4 <: Element\n",
|
|
" connectivity :: Array{Int, 1}\n",
|
|
" fields :: Dict{Any, Any}\n",
|
|
"end"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"Default constructor, providing connectivity data needed in assembly"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 4,
|
|
"metadata": {
|
|
"collapsed": false
|
|
},
|
|
"outputs": [
|
|
{
|
|
"data": {
|
|
"text/plain": [
|
|
"MyQuad4"
|
|
]
|
|
},
|
|
"execution_count": 4,
|
|
"metadata": {},
|
|
"output_type": "execute_result"
|
|
}
|
|
],
|
|
"source": [
|
|
"MyQuad4(connectivity) = MyQuad4(connectivity, Dict{Any, Any}())"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"Some basic charasteristics like number of basis funcitons and dimension:"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 5,
|
|
"metadata": {
|
|
"collapsed": false
|
|
},
|
|
"outputs": [
|
|
{
|
|
"data": {
|
|
"text/plain": [
|
|
"get_element_dimension (generic function with 6 methods)"
|
|
]
|
|
},
|
|
"execution_count": 5,
|
|
"metadata": {},
|
|
"output_type": "execute_result"
|
|
}
|
|
],
|
|
"source": [
|
|
"JuliaFEM.get_number_of_basis_functions(el::Type{MyQuad4}) = 4\n",
|
|
"JuliaFEM.get_element_dimension(el::MyQuad4) = 2"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"The most important, it's basis (we probably want to interpolate something with this element):"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 6,
|
|
"metadata": {
|
|
"collapsed": false
|
|
},
|
|
"outputs": [
|
|
{
|
|
"data": {
|
|
"text/plain": [
|
|
"get_dbasisdxi (generic function with 6 methods)"
|
|
]
|
|
},
|
|
"execution_count": 6,
|
|
"metadata": {},
|
|
"output_type": "execute_result"
|
|
}
|
|
],
|
|
"source": [
|
|
"function JuliaFEM.get_basis(el::MyQuad4, xi)\n",
|
|
" [(1-xi[1])*(1-xi[2])/4\n",
|
|
" (1+xi[1])*(1-xi[2])/4\n",
|
|
" (1+xi[1])*(1+xi[2])/4\n",
|
|
" (1-xi[1])*(1+xi[2])/4]\n",
|
|
"end\n",
|
|
"\n",
|
|
"function JuliaFEM.get_dbasisdxi(el::MyQuad4, xi)\n",
|
|
" [-(1-xi[2])/4.0 -(1-xi[1])/4.0\n",
|
|
" (1-xi[2])/4.0 -(1+xi[1])/4.0\n",
|
|
" (1+xi[2])/4.0 (1+xi[1])/4.0\n",
|
|
" -(1+xi[2])/4.0 (1-xi[1])/4.0]\n",
|
|
"end"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"Next we check that everything is well defined:"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 7,
|
|
"metadata": {
|
|
"collapsed": false
|
|
},
|
|
"outputs": [
|
|
{
|
|
"name": "stderr",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"10-Sep 20:16:49:INFO:root:Testing element MyQuad4\n",
|
|
"10-Sep 20:16:49:INFO:root:number of basis functions in this element: 4\n",
|
|
"10-Sep 20:16:49:INFO:root:Initializing element\n",
|
|
"10-Sep 20:16:49:INFO:root:Element dimension: 2\n",
|
|
"10-Sep 20:16:49:INFO:root:Setting scalar field [1 2 3 4] to element.\n",
|
|
"10-Sep 20:16:50:INFO:root:Interpolating scalar field at [0.0,0.0]\n"
|
|
]
|
|
},
|
|
{
|
|
"data": {
|
|
"text/plain": [
|
|
"PipeEndpoint(open, 0 bytes waiting)"
|
|
]
|
|
},
|
|
"execution_count": 7,
|
|
"metadata": {},
|
|
"output_type": "execute_result"
|
|
},
|
|
{
|
|
"name": "stderr",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"10-Sep 20:16:50:INFO:root:Value: [2.5]\n",
|
|
"10-Sep 20:16:50:INFO:root:Element MyQuad4 passed tests.\n"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"using JuliaFEM: test_element\n",
|
|
"test_element(MyQuad4)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"If `test_element` passes, element should be well defined. At least in the sense that it has all necessary things defined ready to be used in JuliaFEM. After building element, one can interpolate things in it. Couple examples:"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 8,
|
|
"metadata": {
|
|
"collapsed": false
|
|
},
|
|
"outputs": [],
|
|
"source": [
|
|
"using JuliaFEM: set_field, interpolate\n",
|
|
"el1 = MyQuad4([1, 2, 3, 4])\n",
|
|
"set_field(el1, :temperature, [1 2 3 4])\n",
|
|
"set_field(el1, :geometry, [0.0 0.0 0.0; 10.0 0.0 0.0; 10.0 1.0 0.0; 0.0 1.0 0.0]');\n",
|
|
"set_field(el1, :\"heat coefficient\", 1);"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 9,
|
|
"metadata": {
|
|
"collapsed": false
|
|
},
|
|
"outputs": [
|
|
{
|
|
"data": {
|
|
"text/plain": [
|
|
"2.5"
|
|
]
|
|
},
|
|
"execution_count": 9,
|
|
"metadata": {},
|
|
"output_type": "execute_result"
|
|
}
|
|
],
|
|
"source": [
|
|
"# temperature at the middle poinf of the element, 1/4*(1+2+3+4)\n",
|
|
"interpolate(el1, :temperature, [0.0, 0.0])"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 10,
|
|
"metadata": {
|
|
"collapsed": false
|
|
},
|
|
"outputs": [
|
|
{
|
|
"data": {
|
|
"text/plain": [
|
|
"3-element Array{Float64,1}:\n",
|
|
" 5.0\n",
|
|
" 0.5\n",
|
|
" 0.0"
|
|
]
|
|
},
|
|
"execution_count": 10,
|
|
"metadata": {},
|
|
"output_type": "execute_result"
|
|
}
|
|
],
|
|
"source": [
|
|
"# geometry midpoint of element\n",
|
|
"interpolate(el1, :geometry, [0.0, 0.0])"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 12,
|
|
"metadata": {
|
|
"collapsed": false
|
|
},
|
|
"outputs": [
|
|
{
|
|
"data": {
|
|
"text/plain": [
|
|
"1"
|
|
]
|
|
},
|
|
"execution_count": 12,
|
|
"metadata": {},
|
|
"output_type": "execute_result"
|
|
}
|
|
],
|
|
"source": [
|
|
"# interpolating scalar -> scalar.\n",
|
|
"interpolate(el1, :\"heat coefficient\", [0.0, 0.0])"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"## Developing own formulation\n",
|
|
"\n",
|
|
"Let's consider Poisson equation\n",
|
|
"\\begin{align}\n",
|
|
"\\Delta{u} &= 0 && \\text{on } \\Omega \\\\\n",
|
|
"u &= u_0 && \\text{on } \\Gamma_{\\mathrm{D}} \\\\\n",
|
|
"\\frac{\\partial u}{\\partial n} &= g && \\text{on } \\Gamma_{\\mathrm{N}}\n",
|
|
"\\end{align}\n",
|
|
"\n",
|
|
"Weak form is, find $u\\in\\mathcal{U}$ such that\n",
|
|
"\\begin{equation}\n",
|
|
" \\int_{\\Omega}\\nabla u\\cdot\\nabla v\\,\\mathrm{d}x = \\int_{\\Gamma_{\\mathrm{N}}}g v\\,\\mathrm{d}s \\quad \\forall v\\in\\mathcal{V}.\n",
|
|
"\\end{equation}\n",
|
|
"\n",
|
|
"Minimum requirements for equation: \n",
|
|
"- subclass from Equation, if not want to implement from scratch\n",
|
|
"- it needs to have lhs and rhs functions\n",
|
|
"- default constructor takes the element as input argument\n",
|
|
"\n",
|
|
"Now we have function `test_equation`, which we can use to test that everything is working as expected. \n",
|
|
"\n",
|
|
"Again thanks to multiple dispatch, you are free to code your weak form however you want as long as it returns lhs and rhs sides for element dofs. This kind of freedom gives good opportunities to wrap e.g. Fortran code from some other projects. And again we have some suggestions ad following these ideas you get a lot of stuff for free. First we look the left hand side of the equation, that is,\n",
|
|
"\\begin{equation}\n",
|
|
" \\int_{\\Omega}\\nabla u\\cdot\\nabla v\\,\\mathrm{d}x\n",
|
|
"\\end{equation}"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 15,
|
|
"metadata": {
|
|
"collapsed": false
|
|
},
|
|
"outputs": [],
|
|
"source": [
|
|
"using JuliaFEM: Equation, IntegrationPoint, Quad4\n",
|
|
"\n",
|
|
"abstract Heat <: Equation"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"Our basic data type often looks something like this:"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 16,
|
|
"metadata": {
|
|
"collapsed": false
|
|
},
|
|
"outputs": [],
|
|
"source": [
|
|
"\"\"\"\n",
|
|
"Diffusive heat transfer for 4-node bilinear element.\n",
|
|
"\"\"\"\n",
|
|
"type DC2D4 <: Heat\n",
|
|
" element :: Quad4\n",
|
|
" integration_points :: Array{IntegrationPoint, 1}\n",
|
|
" global_dofs :: Array{Int64, 1}\n",
|
|
"end"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"We must provide default constructor which takes element as input argument:"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 17,
|
|
"metadata": {
|
|
"collapsed": false
|
|
},
|
|
"outputs": [
|
|
{
|
|
"data": {
|
|
"text/plain": [
|
|
"DC2D4"
|
|
]
|
|
},
|
|
"execution_count": 17,
|
|
"metadata": {},
|
|
"output_type": "execute_result"
|
|
}
|
|
],
|
|
"source": [
|
|
"function DC2D4(el::Quad4)\n",
|
|
" integration_points = [\n",
|
|
" IntegrationPoint(1.0/sqrt(3.0)*[-1, -1], 1.0),\n",
|
|
" IntegrationPoint(1.0/sqrt(3.0)*[ 1, -1], 1.0),\n",
|
|
" IntegrationPoint(1.0/sqrt(3.0)*[ 1, 1], 1.0),\n",
|
|
" IntegrationPoint(1.0/sqrt(3.0)*[-1, 1], 1.0)]\n",
|
|
" set_field(el, :temperature, zeros(2, 4))\n",
|
|
" DC2D4(el, integration_points, [])\n",
|
|
"end"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"Now the actual implementation for $\\int_{\\Omega}\\nabla u\\cdot\\nabla v\\,\\mathrm{d}x$:"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 18,
|
|
"metadata": {
|
|
"collapsed": false
|
|
},
|
|
"outputs": [
|
|
{
|
|
"data": {
|
|
"text/plain": [
|
|
"has_lhs (generic function with 2 methods)"
|
|
]
|
|
},
|
|
"execution_count": 18,
|
|
"metadata": {},
|
|
"output_type": "execute_result"
|
|
}
|
|
],
|
|
"source": [
|
|
"using JuliaFEM: get_element, get_dbasisdX\n",
|
|
"\n",
|
|
"\"\"\"\n",
|
|
"Left hand side defined in integration point\n",
|
|
"\"\"\"\n",
|
|
"function JuliaFEM.get_lhs(eq::DC2D4, ip)\n",
|
|
" el = get_element(eq)\n",
|
|
" dNdX = get_dbasisdX(el, ip.xi)\n",
|
|
" hc = interpolate(el, :\"temperature thermal conductivity\", ip.xi)\n",
|
|
" return dNdX*hc*dNdX'\n",
|
|
"end\n",
|
|
"JuliaFEM.has_lhs(eq::DC2D4) = true"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"And that's it. If we want to play with this formulation, we must create element and assign this equation for it:"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 19,
|
|
"metadata": {
|
|
"collapsed": false
|
|
},
|
|
"outputs": [
|
|
{
|
|
"data": {
|
|
"text/plain": [
|
|
"4x4 Array{Float64,2}:\n",
|
|
" 4.0 -1.0 -2.0 -1.0\n",
|
|
" -1.0 4.0 -1.0 -2.0\n",
|
|
" -2.0 -1.0 4.0 -1.0\n",
|
|
" -1.0 -2.0 -1.0 4.0"
|
|
]
|
|
},
|
|
"execution_count": 19,
|
|
"metadata": {},
|
|
"output_type": "execute_result"
|
|
}
|
|
],
|
|
"source": [
|
|
"using JuliaFEM: integrate, integrate_lhs, integrate_rhs\n",
|
|
"el = Quad4([1, 2, 3, 4])\n",
|
|
"set_field(el, :geometry, [0 0; 1 0; 1 1; 0 1]')\n",
|
|
"set_field(el, :\"temperature thermal conductivity\", 6)\n",
|
|
"eq = DC2D4(el)\n",
|
|
"integrate_lhs(eq)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"If rhs or lhs is not defined, integration returns nothing."
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 20,
|
|
"metadata": {
|
|
"collapsed": false
|
|
},
|
|
"outputs": [
|
|
{
|
|
"data": {
|
|
"text/plain": [
|
|
"true"
|
|
]
|
|
},
|
|
"execution_count": 20,
|
|
"metadata": {},
|
|
"output_type": "execute_result"
|
|
}
|
|
],
|
|
"source": [
|
|
"isa(integrate_rhs(eq), Void)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"Next heat flux on boundary:"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 21,
|
|
"metadata": {
|
|
"collapsed": false
|
|
},
|
|
"outputs": [
|
|
{
|
|
"data": {
|
|
"text/plain": [
|
|
"has_rhs (generic function with 2 methods)"
|
|
]
|
|
},
|
|
"execution_count": 21,
|
|
"metadata": {},
|
|
"output_type": "execute_result"
|
|
}
|
|
],
|
|
"source": [
|
|
"using JuliaFEM: get_basis, Seg2\n",
|
|
"\n",
|
|
"\"\"\"\n",
|
|
"Diffusive heat transfer for 2-node linear segment.\n",
|
|
"\"\"\"\n",
|
|
"type DC2D2 <: Heat\n",
|
|
" element :: Seg2\n",
|
|
" integration_points :: Array{IntegrationPoint, 1}\n",
|
|
" global_dofs :: Array{Int64, 1}\n",
|
|
"end\n",
|
|
"\n",
|
|
"function DC2D2(el::Seg2)\n",
|
|
" integration_points = [\n",
|
|
" IntegrationPoint([0], 2.0)]\n",
|
|
" set_field(el, :temperature, zeros(2, 1))\n",
|
|
" DC2D2(el, integration_points, [])\n",
|
|
"end\n",
|
|
"\n",
|
|
"\"\"\"\n",
|
|
"Right hand side defined in integration point\n",
|
|
"\"\"\"\n",
|
|
"function JuliaFEM.get_rhs(eq::DC2D2, ip)\n",
|
|
" el = get_element(eq)\n",
|
|
" N = get_basis(el, ip.xi)\n",
|
|
" f = interpolate(el, :\"temperature flux\", ip.xi)\n",
|
|
" return f*N\n",
|
|
"end\n",
|
|
"JuliaFEM.has_rhs(eq::DC2D2) = true"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 22,
|
|
"metadata": {
|
|
"collapsed": false
|
|
},
|
|
"outputs": [
|
|
{
|
|
"data": {
|
|
"text/plain": [
|
|
"2-element Array{Float64,1}:\n",
|
|
" 50.0\n",
|
|
" 50.0"
|
|
]
|
|
},
|
|
"execution_count": 22,
|
|
"metadata": {},
|
|
"output_type": "execute_result"
|
|
}
|
|
],
|
|
"source": [
|
|
"el = Seg2([1, 2])\n",
|
|
"set_field(el, :geometry, [0.0 0.0; 0.0 1.0]')\n",
|
|
"set_field(el, :\"temperature flux\", 100.0)\n",
|
|
"eq = DC2D2(el)\n",
|
|
"integrate_rhs(eq)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"## Defining own problem\n",
|
|
"\n",
|
|
"- takes a set of elements and maps corresponding equations for them\n",
|
|
"- boundary conditions\n",
|
|
"- solve!(problem) updates fields"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {
|
|
"collapsed": true
|
|
},
|
|
"outputs": [],
|
|
"source": [
|
|
"abstract Problem\n",
|
|
"\n",
|
|
"type HeatProblem <: Problem\n",
|
|
" elements: Array{Any, 1}\n",
|
|
" equations: Array{Any, 1}\n",
|
|
" boundary_conditions: Array{Any, 1}\n",
|
|
"end"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"Developing boundary conditions"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {
|
|
"collapsed": true
|
|
},
|
|
"outputs": [],
|
|
"source": [
|
|
"abstract BC\n",
|
|
"\n",
|
|
"type DefaultBC <: BC\n",
|
|
" \n",
|
|
"end"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {
|
|
"collapsed": true
|
|
},
|
|
"outputs": [],
|
|
"source": [
|
|
"bc = NodalBC()\n",
|
|
"bc[:displacement, [1, 2, 3], 1:2] = 3.0"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {
|
|
"collapsed": true
|
|
},
|
|
"outputs": [],
|
|
"source": [
|
|
"bc = WeakBC()\n",
|
|
"bc[:displacement, [el1, el2, el3]] = (X) -> X[0] + X[1] - 2"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {
|
|
"collapsed": true
|
|
},
|
|
"outputs": [],
|
|
"source": [
|
|
"bc = MPCBC()\n",
|
|
"bc[:displacement, "
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {
|
|
"collapsed": true
|
|
},
|
|
"outputs": [],
|
|
"source": [
|
|
"bc = MortarBC()\n"
|
|
]
|
|
}
|
|
],
|
|
"metadata": {
|
|
"kernelspec": {
|
|
"display_name": "Julia 0.5.0-dev",
|
|
"language": "julia",
|
|
"name": "julia-0.5"
|
|
},
|
|
"language_info": {
|
|
"name": "julia",
|
|
"version": "0.5.0"
|
|
}
|
|
},
|
|
"nbformat": 4,
|
|
"nbformat_minor": 0
|
|
}
|