-
Notifications
You must be signed in to change notification settings - Fork 92
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
WIP: New vector interpolations and mappings #798
Draft
KnutAM
wants to merge
182
commits into
master
Choose a base branch
from
kam/FunctionValuesGeneralization
base: master
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Draft
Changes from all commits
Commits
Show all changes
182 commits
Select commit
Hold shift + click to select a range
c44c02d
Introduce FunctionValues and GeometryValues
KnutAM 1d1f7c6
Add benchmark and temporarily support renamed old types
KnutAM 92b9779
Fix inline annotation for julia 1.6 ?
KnutAM 8fef34d
Move callsite inline to function definitions
KnutAM 506a6f7
Fix shell example, used internals of cellvalues
KnutAM d2eda0f
Use FunctionValues in FaceValues too
KnutAM 744ba44
Use get_x_values for facevalues
KnutAM 5cb7052
Initial work - some ex works, not all tests
KnutAM bb47cdb
Fix construction of FaceValues
KnutAM 7ae714e
Trying out to get RT working
KnutAM 7f484eb
Add definition of positive faces and edges
KnutAM ec6e21a
Finish merge
KnutAM 6daaf65
Fix show to old values
KnutAM 2a6aee0
Seemingly working triangle and nedelec
KnutAM ac04724
Add notes for new iterator
KnutAM 4994e6e
Generalize and support 2nd order Nedelec on triangle
KnutAM f62961c
Add citation from master
KnutAM eeb1245
Empty cell_values.jl
KnutAM d89b268
Merge master
KnutAM 6f7f988
Use mapping requirement info in GeometryValues
KnutAM f1020f3
Add test for gradient and continuity of Nedelec
KnutAM 02051ee
Basic RaviartThomas implementation, gradient mapping seems to have an…
KnutAM df83ae8
Fix error in ContravariantPiolaMapping gradient calculation
KnutAM c4e1d63
Reenable tests, setup tmp ci, add mapping desc to devdocs
KnutAM 562041a
bijective to diffeomorphic in theory section
KnutAM cf44f6c
Work on maxwell eigenproblem, but doesn't give correct results
KnutAM bafd9ce
Remove unintended comments
KnutAM eed2740
Create mixed formulation, RaviartThomas example
KnutAM 026c753
Update docs manifest
KnutAM 25ddd17
Merge master
KnutAM 4df280e
Instantiate new Manifest
KnutAM 2557b3e
Correct Manifest update oopsi
KnutAM 27a22cc
Update examples to calculate flux
KnutAM 3facc07
Change parameterization and fix test tolerances
KnutAM a6e4505
Relax type-constraints in GeometryValues and FunctionValues
KnutAM 85bf3f7
Create extra titles for heat eq modifications
KnutAM 06a097d
Use RequiresHessian in CellValues, and comment out unused future func…
KnutAM bcb25d3
Fix copy for CellValues and FaceValues
KnutAM 5c33c5b
Fix show of values
KnutAM 8b16b97
Fix test on julia 1.6
KnutAM ab28d25
Relax tolerance for gradient check a bit
KnutAM d5f7191
Move to old files
KnutAM 7f17ffe
Rename files
KnutAM fbed8e5
Move includes to top level
KnutAM 7bbc5e4
Remove unused example files and notes
KnutAM d322caf
Rename back and re-add docstrings
KnutAM 8384d01
Remove CairoMakie from docs
KnutAM 97eebbe
Add better error message if sdim don't match during reinit
KnutAM 0cee936
Docfixes
KnutAM 90ccab1
Show check for triangle mesh for the heat equation
KnutAM 3f6cd9b
Remove benchmark script
KnutAM 3aad963
Generalize example to try with 2nd order Lagrange
KnutAM 0668d46
Rename GeometryValues -> GeometryMapping
KnutAM cf5d398
Correct i to alpha in mapping documentation
KnutAM 2c67048
Add white background to make visible in dark mode
KnutAM 6141453
Add error if cell===nothing for non-identity mappings
KnutAM 35e8790
Move mapping docs to topics and add walkthrough of SimpleCellValues
KnutAM c76c0af
Add performance annotations and rename checkface to boundscheck_face
KnutAM b5e4121
Improve PointValues constructor from CellValues
KnutAM 089c42a
Use internal functions for geometric ip when testing cellvalues
KnutAM 07e3851
Add devdocs, other docfixes, and fallback for shape value and gradien…
KnutAM f3e6564
Fix so that API docs for FEValues is ok again
KnutAM f5c662c
Rename xx_values.jl to XxValues.jl
KnutAM f9e9aa5
Rename at include too
KnutAM c418594
Merge docs/Manifest from master
KnutAM d47ae33
Minor formatting fixes according to review
KnutAM b508556
Forgot rename of type param
KnutAM 3805c6c
Merge master
KnutAM 4451fac
Use new functions
KnutAM 72e4404
Update docs manifest
KnutAM 3049dc4
Move svg to gh-pages
KnutAM 24591b5
Use shape_x_x_and_x instead of precompute_values
KnutAM 9dfceeb
Reintroduce precompute_values
KnutAM ea7e33e
Fix test of show
KnutAM 1a7e9c9
Remove unused internal methods
KnutAM 41ae092
Test error paths
KnutAM 9b020da
Remove unused test-code
KnutAM 00e2e4f
Test show(::PointValues)
KnutAM 09cf607
Fix test of show(::PointValues)
KnutAM 43970f3
Remove unused methods
KnutAM 005659a
Grammar and stylistic fixes
KnutAM 69b50b4
Add further devdoc explanations
KnutAM f829e88
Describe FEValues interface
KnutAM d4c36c2
Delete checkquadpoint method that causes illegal (at)inbounds
KnutAM 2550a75
Fix typo in devdocs
KnutAM acefcde
Add type specification to shape_value and shape_gradient docstring spec
KnutAM 94c174f
Testing it out
KnutAM c36ffda
Passing tests
KnutAM 4ab9ba2
Fix performance annotations to come on par with master
KnutAM cc0c806
Move utils to common_values
KnutAM e109c9b
Remove PointValuesInternal
KnutAM 34beb70
Fix test
KnutAM 05fab53
Add custom values instructions to devdocs
KnutAM be6daf8
Add test that check instructions in devdocs for custom FEValues
KnutAM 66bf56d
Address Dennis' comments on SimpleCellValues
KnutAM b31e821
Address Dennis' comments on common values
KnutAM 0bbc09d
Simplifications
KnutAM ae80cfb
Fix PointValues usage in PointEvalHandler
KnutAM 810e5d8
Merge master
KnutAM 1d5b9f1
Fix tests after merge
KnutAM 7ea7fbf
Merge branch 'kam/dev/FVG' into kam/FunctionValuesGeneralization
KnutAM 76a9312
Fix missing double-comment for literate
KnutAM 679a4ac
Improved naming/interfaces
KnutAM a913c9b
Fix formatting of SimpleCellValues example
KnutAM 8b6c097
Simplify text in SimpleCellValues example
KnutAM 96a9766
Consistent code formatting and minimize diff
KnutAM a807738
Removed wrong whitespace
KnutAM 9833fe8
Use sprint(show, ...) instead of helper fun for testing
KnutAM c76b57f
Use (at)eval instead of eval(quote
KnutAM 6fe3fc6
Include missed code from master merge
KnutAM 7d497d0
Change order or args for reinit
KnutAM 86655d9
Fix errors due to changed order
KnutAM 8f16066
Update docstrings to new order in reinit
KnutAM 08a67af
Change input kwargs
KnutAM be5d910
Simplify code for FunctionValues construction
KnutAM 41c92c4
Fix order of args
KnutAM 36c018e
More logic if in FunctionValues
KnutAM c7d7a0e
Remove use of (at)eval and be explicit instead
KnutAM 65e916e
Remove credit from SimpleCellValues literate
KnutAM 8faecd4
Parse the generated file and return the MD string to show it
KnutAM 5c75770
Apply review suggestions
KnutAM b3ce313
Fix type instability in point eval
KnutAM 2cbd2b9
Include cell in interface reinits
KnutAM 8df8d52
Merge branch 'master' into kam/FunctionValuesGeneralization
KnutAM 3da6bf0
Add 2nd order RT ip on triangle
KnutAM 7170f49
Merge master
KnutAM 2710cbb
Use old naming
KnutAM 988f916
Add files forgotten to save
KnutAM 3a62893
merge
KnutAM ec7b92c
Merge branch 'dev' into kam/FunctionValuesGeneralization
KnutAM 3e57f37
Merge branch 'master' into kam/FunctionValuesGeneralization
KnutAM 94d50f7
Merge master
KnutAM 7e54d45
Merge branch 'master' into kam/FunctionValuesGeneralization
KnutAM 3f5721e
Fix after merge
KnutAM 89fe1ee
Merge branch 'master' into kam/FunctionValuesGeneralization
KnutAM 90dbf68
Make CellCache reinit work
KnutAM 10b2dfd
Nonworking Nedelec on Hexahedron
KnutAM fc38951
Fix Nedelec{3,RefHexahedron}
KnutAM d356a42
Add temporary visualization script and project
KnutAM 876bea9
Disable JET testing on nightly
KnutAM a281994
Reenable JET, doesn't help anyways
KnutAM 230864a
Add grid pertubations to interpolation tests
KnutAM f2278e0
Add tests for basic properties and fullfill them
KnutAM 714d67c
Merge branch 'master' into kam/FunctionValuesGeneralization
KnutAM 1bfec52
Merge master
KnutAM 4567f0c
Fix merge errors
KnutAM c054b8e
Merge master
KnutAM bb1eea5
Merge branch 'master' into kam/FunctionValuesGeneralization
KnutAM d2a9699
Add some refs
KnutAM d26c168
Merge master
KnutAM 35529ec
Fix formatting using pre-commit
KnutAM fa2a317
Started adding BrezziDouglasMarini
KnutAM a696fe0
Fix BrezziDouglasMarini
KnutAM 80f5b25
Work through tutorial
KnutAM 1ccbb56
Merge branch 'master' into kam/FunctionValuesGeneralization
KnutAM c60e530
Clean and run runic
KnutAM c26cad6
Fix link and imports
KnutAM e0935dd
Add nonworking maxwell eigenvalues example
KnutAM f0a8d1b
Reduce elements in hdiv example
KnutAM 5140c98
Disable failing Maxwell eigenvalue solve
KnutAM 7911cbd
Add test for correct BC indices, non-homogeneous not yet working
KnutAM e810a69
Merge branch 'kam/FunctionValuesGeneralization' of github.com:Ferrite…
KnutAM 01a8306
Reenable tests
KnutAM 508eec7
Improve tutorial formatting
KnutAM 5ebcccf
Add link to potential test case to check for maxwell problem
KnutAM 5c18450
WIP
KnutAM 35eec64
Make Dirichlet for single shape fun per edge work
KnutAM f5f3f97
Working DBC for Nedelec/RT/BDM (triangles)
KnutAM 0f8bf8e
Add some notes
KnutAM e528efb
Start thinking about BoundaryDofValues
KnutAM 3e0ffb2
Simplify tests, export BrezziDoublasMarini
KnutAM dbbc223
Improve testing of hdiv and hcurl
KnutAM ac0d5ad
Try using K[fdofs,fdofs] for maxwell eigenvalue, but didn't work...
KnutAM f866a41
Fix link
KnutAM 92b6039
Added new tutorial attempt for nedelec, WIP and docs will fail due to…
KnutAM 61e4c70
Introduce EdgeValues
KnutAM 4573dd3
Merge branch 'master' into kam/FunctionValuesGeneralization
KnutAM 368e277
Work on maxwell example, theoretical progress
KnutAM ac1d277
Merge master
KnutAM 6cf5a92
Fix some typos in variable names
KnutAM 24c7c09
Start IntegrateableDirichlet and try fixing doc build temporarily
KnutAM 2fe350d
Try fix test failures
KnutAM File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
|
@@ -49,3 +49,24 @@ dofs defined on a specific entity. Hence, not overloading of the dof functions w | |||||
element with zero dofs. Also, it should always be double checked that everything is consistent as | ||||||
specified in the docstring of the corresponding function, as inconsistent implementations can | ||||||
lead to bugs which are really difficult to track down. | ||||||
|
||||||
## Vector interpolation properties | ||||||
### Hdiv interpolations | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
|
||||||
On a facet, ``\Gamma``, with normal, ``\boldsymbol{n}``, | ||||||
the set of ``H(\mathrm{div})`` interpolation functions, | ||||||
``\boldsymbol{N}_i(\boldsymbol{\xi})``, should fullfill | ||||||
```math | ||||||
\begin{align*} | ||||||
\sum_{i = 1}^N \int_\Gamma \boldsymbol{N}_i(\boldsymbol{\xi}) \cdot \boldsymbol{n} &= 1 \\ | ||||||
\sum_{i = 1}^N \int_\Gamma f_i(\boldsymbol{\xi}) \boldsymbol{N}_i(\boldsymbol{\xi}) \cdot \boldsymbol{n} &= 1 \\ | ||||||
\int_\Gamma f_i(\boldsymbol{\xi}) \boldsymbol{N}_j(\boldsymbol{\xi}) \cdot \boldsymbol{n} &= 0, \quad i \neq j | ||||||
``` | ||||||
The moment-weighting functions ``f_i(\boldsymbol{\xi})`` depend on how many base functions there are per | ||||||
facet and the reference shape of the facet (`RefLine`, `RefTriangle`, or `RefQuadrilateral`). | ||||||
|
||||||
These integral quantities apply to arbitrarily sized cell facets, and hence the actual value of the base functions | ||||||
will scale depending on the size (smaller facet ``\rightarrow`` higher values). Consequently, when applying BCs, | ||||||
we need to consider the actual facet size to be able to prescribe the average flux. | ||||||
Consider making a new generalized `BCValues`: `BoundaryDofValues` object that stores the required info. | ||||||
Develop as separate first, could possible replace the current `BCValues`... |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,257 @@ | ||
# # [Heat equation - Mixed H(div) conforming formulation)](@id tutorial-heat-equation-hdiv) | ||
# As an alternative to the standard formulation for solving the heat equation used in | ||
# the [heat equation tutorial](@ref tutorial-heat-equation), we can used a mixed formulation | ||
# where both the temperature, $u(\mathbf{x})$, and the heat flux, $\boldsymbol{q}(\boldsymbol{x})$, | ||
# are primary variables. From a theoretical standpoint, there are many details on e.g. which combinations | ||
# of interpolations that are stable. See e.g. [Gatica2014](@cite) and [Boffi2013](@cite) for further reading. | ||
# This tutorial is based on the theory in | ||
# [FEniCSx' mixed poisson example](https://docs.fenicsproject.org/dolfinx/v0.9.0/python/demos/demo_mixed-poisson.html). | ||
# | ||
# ![Temperature solution](https://raw.githubusercontent.com/Ferrite-FEM/Ferrite.jl/refs/heads/gh-pages/assets/heat_equation_hdiv.png) | ||
# **Figure:** Temperature distribution considering a central part with lower heat conductivity. | ||
# | ||
# The advantage with the mixed formulation is that the heat flux is approximated better. However, the | ||
# temperature becomes discontinuous where the conductivity is discontinuous. | ||
# | ||
# ## Theory | ||
# We start with the strong form of the heat equation: Find the temperature, $u(\boldsymbol{x})$, and heat flux, $\boldsymbol{q}(x)$, | ||
# such that | ||
# ```math | ||
# \begin{align*} | ||
# \boldsymbol{\nabla}\cdot \boldsymbol{q} &= h(\boldsymbol{x}), \quad \text{in } \Omega \\ | ||
# \boldsymbol{q}(\boldsymbol{x}) &= - k\ \boldsymbol{\nabla} u(\boldsymbol{x}), \quad \text{in } \Omega \\ | ||
# \boldsymbol{q}(\boldsymbol{x})\cdot \boldsymbol{n}(\boldsymbol{x}) &= q_n, \quad \text{on } \Gamma_\mathrm{N}\\ | ||
# u(\boldsymbol{x}) &= u_\mathrm{D}, \quad \text{on } \Gamma_\mathrm{D} | ||
# \end{align*} | ||
# ``` | ||
# | ||
# From this strong form, we can formulate the weak form as a mixed formulation. | ||
# Find $u \in \mathbb{U}$ and $\boldsymbol{q}\in\mathbb{Q}$ such that | ||
# ```math | ||
# \begin{align*} | ||
# \int_{\Omega} \delta u [\boldsymbol{\nabla} \cdot \boldsymbol{q}]\ \mathrm{d}\Omega &= \int_\Omega \delta u h\ \mathrm{d}\Omega, \quad \forall\ \delta u \in \delta\mathbb{U} \\ | ||
# % \int_{\Omega} \boldsymbol{\delta q} \cdot \boldsymbol{q}\ \mathrm{d}\Omega &= -\int_\Omega \boldsymbol{\delta q} \cdot [k\ \boldsymbol{\nabla} u]\ \mathrm{d}\Omega \\ | ||
# \int_{\Omega} \boldsymbol{\delta q} \cdot \boldsymbol{q}\ \mathrm{d}\Omega - \int_{\Omega} [\boldsymbol{\nabla} \cdot \boldsymbol{\delta q}] k u \ \mathrm{d}\Omega &= | ||
# -\int_\Gamma \boldsymbol{\delta q} \cdot \boldsymbol{n} k\ u\ \mathrm{d}\Gamma, \quad \forall\ \boldsymbol{\delta q} \in \delta\mathbb{Q} | ||
# \end{align*} | ||
# ``` | ||
# where we have the function spaces, | ||
# ```math | ||
# \begin{align*} | ||
# \mathbb{U} &= \delta\mathbb{U} = L^2 \\ | ||
# \mathbb{Q} &= \lbrace \boldsymbol{q} \in H(\mathrm{div}) \text{ such that } \boldsymbol{q}\cdot\boldsymbol{n} = q_\mathrm{n} \text{ on } \Gamma_\mathrm{D}\rbrace \\ | ||
# \delta\mathbb{Q} &= \lbrace \boldsymbol{q} \in H(\mathrm{div}) \text{ such that } \boldsymbol{q}\cdot\boldsymbol{n} = 0 \text{ on } \Gamma_\mathrm{D}\rbrace | ||
# \end{align*} | ||
# ``` | ||
# A stable choice of finite element spaces for this problem on grid with triangles is using | ||
# * `DiscontinuousLagrange{RefTriangle, k-1}` for approximating $L^2$ | ||
# * `BrezziDouglasMarini{RefTriangle, k}` for approximating $H(\mathrm{div})$ | ||
#= | ||
# Dirichlet BC theory for hdiv interpolations. | ||
For a field representing a flux, we in general set the boundary condition on the normal component of this | ||
flux. Consider the field $\boldsymbol{q}(\boldsymbol{x})$, then we want to prescribe | ||
$q_\mathrm{n}(\boldsymbol{x}) = \boldsymbol{q}(\boldsymbol{x}) \cdot \boldsymbol{n}$, which we can calculate as | ||
```math | ||
q_\mathrm{n}(\boldsymbol{x}) = [\boldsymbol{N}_i(\boldsymbol{x}) \cdot \boldsymbol{n}] a_i | ||
``` | ||
However, for $H(\mathrm{div})$ interpolations, we don't have distinct algebraic nodal coordinates, | ||
$\boldsymbol{x}_j$, fulfilling $\vert\boldsymbol{N}_i(\boldsymbol{x}_j)\vert = \delta_{ij}$. Instead, | ||
we have | ||
```math | ||
\begin{align*} | ||
\int_0^1 s (4-6s) \mathrm{d}s = [2s^2 - 2 s^3] = 0\\ | ||
\int_0^1 (1-s) (4-6s) \mathrm{d}s = \int_0^1 4 - 10s + 6s^2 \mathrm{d}s = [4s - 5s^2 + 2s^3] = 1 | ||
\end{align*} | ||
``` | ||
=# | ||
# | ||
# | ||
# ## Commented Program | ||
# | ||
# Now we solve the problem in Ferrite. What follows is a program spliced with comments. | ||
# | ||
# First we load Ferrite, | ||
using Ferrite | ||
# And define our grid, representing a channel with a central part having a lower | ||
# conductivity, $k$, than the surrounding. | ||
function create_grid(ny::Int) | ||
width = 10.0 | ||
length = 40.0 | ||
center_width = 5.0 | ||
center_length = 20.0 | ||
upper_right = Vec((length / 2, width / 2)) | ||
grid = generate_grid(Triangle, (round(Int, ny * length / width), ny), -upper_right, upper_right) | ||
addcellset!(grid, "center", x -> abs(x[1]) < center_length / 2 && abs(x[2]) < center_width / 2) | ||
addcellset!(grid, "around", setdiff(1:getncells(grid), getcellset(grid, "center"))) | ||
return grid | ||
end | ||
|
||
grid = create_grid(10) | ||
#md nothing # hide | ||
|
||
# ### Setup | ||
# We define one `CellValues` for each field which share the same quadrature rule. | ||
ip_geo = geometric_interpolation(getcelltype(grid)) | ||
ipu = DiscontinuousLagrange{RefTriangle, 0}() | ||
ipq = BrezziDouglasMarini{2, RefTriangle, 1}() | ||
qr = QuadratureRule{RefTriangle}(2) | ||
cellvalues = (u = CellValues(qr, ipu, ip_geo), q = CellValues(qr, ipq, ip_geo)) | ||
#md nothing # hide | ||
|
||
# Distribute the degrees of freedom | ||
dh = DofHandler(grid) | ||
add!(dh, :u, ipu) | ||
add!(dh, :q, ipq) | ||
close!(dh) | ||
#md nothing # hide | ||
|
||
# In this problem, we have a zero temperature on the boundary, Γ, which is enforced | ||
# via zero Neumann boundary conditions. Hence, we don't need a `Constrainthandler`. | ||
Γ = union((getfacetset(grid, name) for name in ("left", "right", "bottom", "top"))...) | ||
#md nothing # hide | ||
|
||
# ### Element implementation | ||
|
||
function assemble_element!(Ke::Matrix, fe::Vector, cv::NamedTuple, dr::NamedTuple, k::Number) | ||
cvu = cv[:u] | ||
cvq = cv[:q] | ||
dru = dr[:u] | ||
drq = dr[:q] | ||
h = 1.0 # Heat source | ||
## Loop over quadrature points | ||
for q_point in 1:getnquadpoints(cvu) | ||
## Get the quadrature weight | ||
dΩ = getdetJdV(cvu, q_point) | ||
## Loop over test shape functions | ||
for (iu, Iu) in pairs(dru) | ||
δNu = shape_value(cvu, q_point, iu) | ||
## Add contribution to fe | ||
fe[Iu] += δNu * h * dΩ | ||
## Loop over trial shape functions | ||
for (jq, Jq) in pairs(drq) | ||
div_Nq = shape_divergence(cvq, q_point, jq) | ||
## Add contribution to Ke | ||
Ke[Iu, Jq] += (δNu * div_Nq) * dΩ | ||
end | ||
end | ||
for (iq, Iq) in pairs(drq) | ||
δNq = shape_value(cvq, q_point, iq) | ||
div_δNq = shape_divergence(cvq, q_point, iq) | ||
for (ju, Ju) in pairs(dru) | ||
Nu = shape_value(cvu, q_point, ju) | ||
Ke[Iq, Ju] -= div_δNq * k * Nu * dΩ | ||
end | ||
for (jq, Jq) in pairs(drq) | ||
Nq = shape_value(cvq, q_point, jq) | ||
Ke[Iq, Jq] += (δNq ⋅ Nq) * dΩ | ||
end | ||
end | ||
end | ||
return Ke, fe | ||
end | ||
#md nothing # hide | ||
|
||
# ### Global assembly | ||
function assemble_global(cellvalues, dh::DofHandler) | ||
grid = dh.grid | ||
## Allocate the element stiffness matrix and element force vector | ||
dofranges = (u = dof_range(dh, :u), q = dof_range(dh, :q)) | ||
ncelldofs = ndofs_per_cell(dh) | ||
Ke = zeros(ncelldofs, ncelldofs) | ||
fe = zeros(ncelldofs) | ||
## Allocate global system matrix and vector | ||
K = allocate_matrix(dh) | ||
f = zeros(ndofs(dh)) | ||
## Create an assembler | ||
assembler = start_assemble(K, f) | ||
x = copy(getcoordinates(grid, 1)) | ||
dofs = copy(celldofs(dh, 1)) | ||
## Loop over all cells | ||
for (cells, k) in ( | ||
(getcellset(grid, "center"), 0.1), | ||
(getcellset(grid, "around"), 1.0), | ||
) | ||
for cellnr in cells | ||
## Reinitialize cellvalues for this cell | ||
cell = getcells(grid, cellnr) | ||
getcoordinates!(x, grid, cell) | ||
celldofs!(dofs, dh, cellnr) | ||
reinit!(cellvalues[:u], cell, x) | ||
reinit!(cellvalues[:q], cell, x) | ||
## Reset to 0 | ||
fill!(Ke, 0) | ||
fill!(fe, 0) | ||
## Compute element contribution | ||
assemble_element!(Ke, fe, cellvalues, dofranges, k) | ||
## Assemble Ke and fe into K and f | ||
assemble!(assembler, dofs, Ke, fe) | ||
end | ||
end | ||
return K, f | ||
end | ||
#md nothing # hide | ||
|
||
# ### Solution of the system | ||
K, f = assemble_global(cellvalues, dh); | ||
u = K \ f | ||
#md nothing # hide | ||
|
||
# ### Exporting to VTK | ||
# Currently, exporting discontinuous interpolations is not supported. | ||
# Since in this case, we have a single temperature degree of freedom | ||
# per cell, we work around this by calculating the per-cell temperature. | ||
temperature_dof = first(dof_range(dh, :u)) | ||
u_cells = map(1:getncells(grid)) do i | ||
u[celldofs(dh, i)[temperature_dof]] | ||
end | ||
VTKGridFile("heat_equation_hdiv", dh) do vtk | ||
write_cell_data(vtk, u_cells, "temperature") | ||
end | ||
#md nothing # hide | ||
|
||
# ## Postprocess the total flux | ||
# We applied a constant unit heat source to the body, and the | ||
# total heat flux exiting across the boundary should therefore | ||
# match the area for the considered stationary case. | ||
function calculate_flux(dh, boundary_facets, ip, a) | ||
grid = dh.grid | ||
qr = FacetQuadratureRule{RefTriangle}(4) | ||
ip_geo = geometric_interpolation(getcelltype(grid)) | ||
fv = FacetValues(qr, ip, ip_geo) | ||
|
||
dofrange = dof_range(dh, :q) | ||
flux = 0.0 | ||
dofs = celldofs(dh, 1) | ||
ae = zeros(length(dofs)) | ||
x = getcoordinates(grid, 1) | ||
for (cellnr, facetnr) in boundary_facets | ||
getcoordinates!(x, grid, cellnr) | ||
cell = getcells(grid, cellnr) | ||
celldofs!(dofs, dh, cellnr) | ||
map!(i -> a[i], ae, dofs) | ||
reinit!(fv, cell, x, facetnr) | ||
for q_point in 1:getnquadpoints(fv) | ||
dΓ = getdetJdV(fv, q_point) | ||
n = getnormal(fv, q_point) | ||
q = function_value(fv, q_point, ae, dofrange) | ||
flux += (q ⋅ n) * dΓ | ||
end | ||
end | ||
return flux | ||
end | ||
|
||
println("Outward flux: ", calculate_flux(dh, Γ, ipq, u)) | ||
#md nothing # hide | ||
|
||
# Note that this is not the case for the standard [Heat equation](@ref tutorial-heat-equation), | ||
# as the flux terms are less accurately approximated. A fine mesh is required to converge in that case. | ||
# However, the present example gives a worse approximation of the temperature field. | ||
|
||
#md # ## [Plain program](@id tutorial-heat-equation-hdiv-plain) | ||
#md # | ||
#md # Here follows a version of the program without any comments. | ||
#md # The file is also available here: [`heat_equation_hdiv.jl`](heat_equation_hdiv.jl). | ||
#md # | ||
#md # ```julia | ||
#md # @__CODE__ | ||
#md # ``` |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It might make sense to add some comments about the De-Rahm complex here for readers not familiar with the topic.