Skip to content
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
wants to merge 165 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
165 commits
Select commit Hold shift + click to select a range
c44c02d
Introduce FunctionValues and GeometryValues
KnutAM Jul 12, 2023
1d1f7c6
Add benchmark and temporarily support renamed old types
KnutAM Jul 12, 2023
92b9779
Fix inline annotation for julia 1.6 ?
KnutAM Jul 12, 2023
8fef34d
Move callsite inline to function definitions
KnutAM Jul 12, 2023
506a6f7
Fix shell example, used internals of cellvalues
KnutAM Jul 12, 2023
d2eda0f
Use FunctionValues in FaceValues too
KnutAM Jul 12, 2023
744ba44
Use get_x_values for facevalues
KnutAM Jul 18, 2023
5cb7052
Initial work - some ex works, not all tests
KnutAM Aug 11, 2023
bb47cdb
Fix construction of FaceValues
KnutAM Aug 12, 2023
7ae714e
Trying out to get RT working
KnutAM Aug 28, 2023
7f484eb
Add definition of positive faces and edges
KnutAM Aug 28, 2023
ec6e21a
Finish merge
KnutAM Sep 16, 2023
6daaf65
Fix show to old values
KnutAM Sep 16, 2023
2a6aee0
Seemingly working triangle and nedelec
KnutAM Sep 18, 2023
ac04724
Add notes for new iterator
KnutAM Sep 19, 2023
4994e6e
Generalize and support 2nd order Nedelec on triangle
KnutAM Sep 20, 2023
f62961c
Add citation from master
KnutAM Sep 20, 2023
eeb1245
Empty cell_values.jl
KnutAM Sep 20, 2023
d89b268
Merge master
KnutAM Sep 20, 2023
6f7f988
Use mapping requirement info in GeometryValues
KnutAM Sep 20, 2023
f1020f3
Add test for gradient and continuity of Nedelec
KnutAM Sep 21, 2023
02051ee
Basic RaviartThomas implementation, gradient mapping seems to have an…
KnutAM Sep 21, 2023
df83ae8
Fix error in ContravariantPiolaMapping gradient calculation
KnutAM Sep 22, 2023
c4e1d63
Reenable tests, setup tmp ci, add mapping desc to devdocs
KnutAM Sep 23, 2023
562041a
bijective to diffeomorphic in theory section
KnutAM Sep 25, 2023
cf44f6c
Work on maxwell eigenproblem, but doesn't give correct results
KnutAM Sep 27, 2023
bafd9ce
Remove unintended comments
KnutAM Oct 3, 2023
eed2740
Create mixed formulation, RaviartThomas example
KnutAM Oct 7, 2023
026c753
Update docs manifest
KnutAM Oct 7, 2023
25ddd17
Merge master
KnutAM Oct 7, 2023
4df280e
Instantiate new Manifest
KnutAM Oct 7, 2023
2557b3e
Correct Manifest update oopsi
KnutAM Oct 7, 2023
27a22cc
Update examples to calculate flux
KnutAM Oct 7, 2023
3facc07
Change parameterization and fix test tolerances
KnutAM Oct 7, 2023
a6e4505
Relax type-constraints in GeometryValues and FunctionValues
KnutAM Oct 8, 2023
85bf3f7
Create extra titles for heat eq modifications
KnutAM Oct 8, 2023
06a097d
Use RequiresHessian in CellValues, and comment out unused future func…
KnutAM Oct 8, 2023
bcb25d3
Fix copy for CellValues and FaceValues
KnutAM Oct 8, 2023
5c33c5b
Fix show of values
KnutAM Oct 8, 2023
8b16b97
Fix test on julia 1.6
KnutAM Oct 8, 2023
ab28d25
Relax tolerance for gradient check a bit
KnutAM Oct 8, 2023
d5f7191
Move to old files
KnutAM Oct 8, 2023
7f17ffe
Rename files
KnutAM Oct 8, 2023
fbed8e5
Move includes to top level
KnutAM Oct 8, 2023
7bbc5e4
Remove unused example files and notes
KnutAM Oct 8, 2023
d322caf
Rename back and re-add docstrings
KnutAM Oct 8, 2023
8384d01
Remove CairoMakie from docs
KnutAM Oct 8, 2023
97eebbe
Add better error message if sdim don't match during reinit
KnutAM Oct 8, 2023
0cee936
Docfixes
KnutAM Oct 8, 2023
90ccab1
Show check for triangle mesh for the heat equation
KnutAM Oct 8, 2023
3f6cd9b
Remove benchmark script
KnutAM Oct 8, 2023
3aad963
Generalize example to try with 2nd order Lagrange
KnutAM Oct 8, 2023
0668d46
Rename GeometryValues -> GeometryMapping
KnutAM Oct 13, 2023
cf5d398
Correct i to alpha in mapping documentation
KnutAM Oct 13, 2023
2c67048
Add white background to make visible in dark mode
KnutAM Oct 13, 2023
6141453
Add error if cell===nothing for non-identity mappings
KnutAM Oct 13, 2023
35e8790
Move mapping docs to topics and add walkthrough of SimpleCellValues
KnutAM Oct 13, 2023
c76c0af
Add performance annotations and rename checkface to boundscheck_face
KnutAM Oct 13, 2023
b5e4121
Improve PointValues constructor from CellValues
KnutAM Oct 13, 2023
089c42a
Use internal functions for geometric ip when testing cellvalues
KnutAM Oct 13, 2023
07e3851
Add devdocs, other docfixes, and fallback for shape value and gradien…
KnutAM Oct 13, 2023
f3e6564
Fix so that API docs for FEValues is ok again
KnutAM Oct 13, 2023
f5c662c
Rename xx_values.jl to XxValues.jl
KnutAM Oct 13, 2023
f9e9aa5
Rename at include too
KnutAM Oct 13, 2023
c418594
Merge docs/Manifest from master
KnutAM Oct 13, 2023
d47ae33
Minor formatting fixes according to review
KnutAM Oct 13, 2023
b508556
Forgot rename of type param
KnutAM Oct 13, 2023
3805c6c
Merge master
KnutAM Oct 16, 2023
4451fac
Use new functions
KnutAM Oct 16, 2023
72e4404
Update docs manifest
KnutAM Oct 16, 2023
3049dc4
Move svg to gh-pages
KnutAM Oct 21, 2023
24591b5
Use shape_x_x_and_x instead of precompute_values
KnutAM Oct 21, 2023
9dfceeb
Reintroduce precompute_values
KnutAM Oct 21, 2023
ea7e33e
Fix test of show
KnutAM Oct 21, 2023
1a7e9c9
Remove unused internal methods
KnutAM Oct 21, 2023
41ae092
Test error paths
KnutAM Oct 21, 2023
9b020da
Remove unused test-code
KnutAM Oct 21, 2023
00e2e4f
Test show(::PointValues)
KnutAM Oct 21, 2023
09cf607
Fix test of show(::PointValues)
KnutAM Oct 21, 2023
43970f3
Remove unused methods
KnutAM Oct 21, 2023
005659a
Grammar and stylistic fixes
KnutAM Oct 23, 2023
69b50b4
Add further devdoc explanations
KnutAM Oct 23, 2023
f829e88
Describe FEValues interface
KnutAM Nov 4, 2023
d4c36c2
Delete checkquadpoint method that causes illegal (at)inbounds
KnutAM Nov 4, 2023
2550a75
Fix typo in devdocs
KnutAM Nov 4, 2023
acefcde
Add type specification to shape_value and shape_gradient docstring spec
KnutAM Nov 5, 2023
94c174f
Testing it out
KnutAM Nov 10, 2023
c36ffda
Passing tests
KnutAM Nov 11, 2023
4ab9ba2
Fix performance annotations to come on par with master
KnutAM Nov 11, 2023
cc0c806
Move utils to common_values
KnutAM Nov 21, 2023
e109c9b
Remove PointValuesInternal
KnutAM Nov 21, 2023
34beb70
Fix test
KnutAM Nov 21, 2023
05fab53
Add custom values instructions to devdocs
KnutAM Nov 22, 2023
be6daf8
Add test that check instructions in devdocs for custom FEValues
KnutAM Nov 22, 2023
66bf56d
Address Dennis' comments on SimpleCellValues
KnutAM Nov 24, 2023
b31e821
Address Dennis' comments on common values
KnutAM Nov 24, 2023
0bbc09d
Simplifications
KnutAM Dec 1, 2023
ae80cfb
Fix PointValues usage in PointEvalHandler
KnutAM Dec 3, 2023
810e5d8
Merge master
KnutAM Dec 3, 2023
1d5b9f1
Fix tests after merge
KnutAM Dec 3, 2023
7ea7fbf
Merge branch 'kam/dev/FVG' into kam/FunctionValuesGeneralization
KnutAM Dec 3, 2023
76a9312
Fix missing double-comment for literate
KnutAM Dec 3, 2023
679a4ac
Improved naming/interfaces
KnutAM Dec 3, 2023
a913c9b
Fix formatting of SimpleCellValues example
KnutAM Dec 3, 2023
8b6c097
Simplify text in SimpleCellValues example
KnutAM Dec 3, 2023
96a9766
Consistent code formatting and minimize diff
KnutAM Dec 3, 2023
a807738
Removed wrong whitespace
KnutAM Dec 3, 2023
9833fe8
Use sprint(show, ...) instead of helper fun for testing
KnutAM Dec 4, 2023
c76b57f
Use (at)eval instead of eval(quote
KnutAM Dec 4, 2023
6fe3fc6
Include missed code from master merge
KnutAM Dec 4, 2023
7d497d0
Change order or args for reinit
KnutAM Dec 4, 2023
86655d9
Fix errors due to changed order
KnutAM Dec 4, 2023
8f16066
Update docstrings to new order in reinit
KnutAM Dec 4, 2023
08a67af
Change input kwargs
KnutAM Dec 4, 2023
be5d910
Simplify code for FunctionValues construction
KnutAM Dec 4, 2023
41c92c4
Fix order of args
KnutAM Dec 4, 2023
36c018e
More logic if in FunctionValues
KnutAM Dec 4, 2023
c7d7a0e
Remove use of (at)eval and be explicit instead
KnutAM Dec 5, 2023
65e916e
Remove credit from SimpleCellValues literate
KnutAM Dec 5, 2023
8faecd4
Parse the generated file and return the MD string to show it
KnutAM Dec 5, 2023
5c75770
Apply review suggestions
KnutAM Dec 6, 2023
b3ce313
Fix type instability in point eval
KnutAM Dec 6, 2023
2cbd2b9
Include cell in interface reinits
KnutAM Dec 6, 2023
8df8d52
Merge branch 'master' into kam/FunctionValuesGeneralization
KnutAM Dec 6, 2023
3da6bf0
Add 2nd order RT ip on triangle
KnutAM Dec 6, 2023
7170f49
Merge master
KnutAM Dec 6, 2023
2710cbb
Use old naming
KnutAM Dec 6, 2023
988f916
Add files forgotten to save
KnutAM Dec 6, 2023
3a62893
merge
KnutAM Dec 6, 2023
ec7b92c
Merge branch 'dev' into kam/FunctionValuesGeneralization
KnutAM Dec 6, 2023
3e57f37
Merge branch 'master' into kam/FunctionValuesGeneralization
KnutAM Dec 6, 2023
94d50f7
Merge master
KnutAM Jan 2, 2024
7e54d45
Merge branch 'master' into kam/FunctionValuesGeneralization
KnutAM Feb 28, 2024
3f5721e
Fix after merge
KnutAM Feb 28, 2024
89fe1ee
Merge branch 'master' into kam/FunctionValuesGeneralization
KnutAM Mar 21, 2024
90dbf68
Make CellCache reinit work
KnutAM Mar 21, 2024
10b2dfd
Nonworking Nedelec on Hexahedron
KnutAM Mar 21, 2024
fc38951
Fix Nedelec{3,RefHexahedron}
KnutAM Mar 22, 2024
d356a42
Add temporary visualization script and project
KnutAM Mar 22, 2024
876bea9
Disable JET testing on nightly
KnutAM Mar 22, 2024
a281994
Reenable JET, doesn't help anyways
KnutAM Mar 22, 2024
230864a
Add grid pertubations to interpolation tests
KnutAM Mar 22, 2024
f2278e0
Add tests for basic properties and fullfill them
KnutAM Mar 22, 2024
714d67c
Merge branch 'master' into kam/FunctionValuesGeneralization
KnutAM Apr 25, 2024
1bfec52
Merge master
KnutAM Aug 18, 2024
4567f0c
Fix merge errors
KnutAM Aug 19, 2024
c054b8e
Merge master
KnutAM Oct 18, 2024
bb1eea5
Merge branch 'master' into kam/FunctionValuesGeneralization
KnutAM Oct 29, 2024
d2a9699
Add some refs
KnutAM Oct 29, 2024
d26c168
Merge master
KnutAM Oct 31, 2024
35529ec
Fix formatting using pre-commit
KnutAM Oct 31, 2024
fa2a317
Started adding BrezziDouglasMarini
KnutAM Nov 1, 2024
a696fe0
Fix BrezziDouglasMarini
KnutAM Nov 12, 2024
80f5b25
Work through tutorial
KnutAM Nov 12, 2024
1ccbb56
Merge branch 'master' into kam/FunctionValuesGeneralization
KnutAM Nov 12, 2024
c60e530
Clean and run runic
KnutAM Nov 12, 2024
c26cad6
Fix link and imports
KnutAM Nov 12, 2024
e0935dd
Add nonworking maxwell eigenvalues example
KnutAM Nov 13, 2024
f0a8d1b
Reduce elements in hdiv example
KnutAM Nov 13, 2024
5140c98
Disable failing Maxwell eigenvalue solve
KnutAM Nov 13, 2024
7911cbd
Add test for correct BC indices, non-homogeneous not yet working
KnutAM Nov 14, 2024
e810a69
Merge branch 'kam/FunctionValuesGeneralization' of github.com:Ferrite…
KnutAM Nov 14, 2024
01a8306
Reenable tests
KnutAM Nov 14, 2024
508eec7
Improve tutorial formatting
KnutAM Nov 15, 2024
5ebcccf
Add link to potential test case to check for maxwell problem
KnutAM Nov 15, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 29 additions & 1 deletion docs/Manifest.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

julia_version = "1.11.1"
manifest_format = "2.0"
project_hash = "4e52f4aa4cee9f66ec4f633f0ae538fbd227ac5e"
project_hash = "c8cd4f9010376e633064839ca68de8e4b622021f"

[[deps.ADTypes]]
git-tree-sha1 = "eea5d80188827b35333801ef97a40c2ed653b081"
Expand Down Expand Up @@ -69,6 +69,18 @@ git-tree-sha1 = "d57bd3762d308bded22c3b82d033bff85f6195c6"
uuid = "ec485272-7323-5ecc-a04f-4719b315124d"
version = "0.4.0"

[[deps.Arpack]]
deps = ["Arpack_jll", "Libdl", "LinearAlgebra", "Logging"]
git-tree-sha1 = "9b9b347613394885fd1c8c7729bfc60528faa436"
uuid = "7d9fca2a-8960-54d3-9f78-7d1dccf2cb97"
version = "0.5.4"

[[deps.Arpack_jll]]
deps = ["Artifacts", "CompilerSupportLibraries_jll", "JLLWrappers", "Libdl", "OpenBLAS_jll", "Pkg"]
git-tree-sha1 = "5ba6c757e8feccf03a1554dfaf3e26b3cfc7fd5e"
uuid = "68821587-b530-5797-8361-c406ea357684"
version = "3.5.1+1"

[[deps.ArrayInterface]]
deps = ["Adapt", "LinearAlgebra"]
git-tree-sha1 = "3640d077b6dafd64ceb8fd5c1ec76f7ca53bcf76"
Expand Down Expand Up @@ -931,6 +943,16 @@ git-tree-sha1 = "267dad6b4b7b5d529c76d40ff48d33f7e94cb834"
uuid = "ba0b0d4f-ebba-5204-a429-3ac8c609bfb7"
version = "0.9.6"

[[deps.KrylovKit]]
deps = ["GPUArraysCore", "LinearAlgebra", "PackageExtensionCompat", "Printf", "Random", "VectorInterface"]
git-tree-sha1 = "3ba86a12066c19a6ed0bc963984bcf89d495133e"
uuid = "0b1a1467-8014-51b9-945f-bf0ae24f4b77"
version = "0.8.2"
weakdeps = ["ChainRulesCore"]

[deps.KrylovKit.extensions]
KrylovKitChainRulesCoreExt = "ChainRulesCore"

[[deps.LAME_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl"]
git-tree-sha1 = "170b660facf5df5de098d866564877e119141cbd"
Expand Down Expand Up @@ -2325,6 +2347,12 @@ git-tree-sha1 = "c2d0db3ef09f1942d08ea455a9e252594be5f3b6"
uuid = "4004b06d-e244-455f-a6ce-a5f9919cc534"
version = "1.0.1"

[[deps.VectorInterface]]
deps = ["LinearAlgebra"]
git-tree-sha1 = "cea8abaa6e43f72f97a09cf95b80c9eb53ff75cf"
uuid = "409d34a3-91d5-4945-b6ec-7529ddf182d8"
version = "0.4.9"

[[deps.VectorizationBase]]
deps = ["ArrayInterface", "CPUSummary", "HostCPUFeatures", "IfElse", "LayoutPointers", "Libdl", "LinearAlgebra", "SIMDTypes", "Static", "StaticArrayInterface"]
git-tree-sha1 = "e7f5b81c65eb858bed630fe006837b935518aca5"
Expand Down
2 changes: 2 additions & 0 deletions docs/Project.toml
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
[deps]
Arpack = "7d9fca2a-8960-54d3-9f78-7d1dccf2cb97"
BlockArrays = "8e7c35d0-a365-5155-bbbb-fb81a777f24e"
Changelog = "5217a498-cd5d-4ec6-b8c2-9b85a09b6e3e"
Documenter = "e30172f5-a6a5-5a46-863b-614d45cd2de4"
Expand All @@ -9,6 +10,7 @@ FerriteMeshParser = "0f8c756f-80dd-4a75-85c6-b0a5ab9d4620"
ForwardDiff = "f6369f11-7733-5829-9624-2563aa707210"
Gmsh = "705231aa-382f-11e9-3f0c-b7cb4346fdeb"
IterativeSolvers = "42fd0dbc-a981-5370-80f2-aaf504508153"
KrylovKit = "0b1a1467-8014-51b9-945f-bf0ae24f4b77"
LineSearches = "d3d80556-e9d4-5f37-9878-2ab0fcc64255"
LinearSolve = "7ed4a6bd-45f5-4d41-b270-4a48e9bafcae"
Literate = "98b081ad-f1c9-55d3-8b20-4c87d4299306"
Expand Down
2 changes: 1 addition & 1 deletion docs/liveserver.jl
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ push!(ARGS, "liveserver")
# Run LiveServer.servedocs(...)
import LiveServer
LiveServer.servedocs(;
host = "0.0.0.0",
# host = "0.0.0.0",
# Documentation root where make.jl and src/ are located
foldername = joinpath(repo_root, "docs"),
# Extra source folder to watch for changes
Expand Down
2 changes: 2 additions & 0 deletions docs/make.jl
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ bibtex_plugin = CitationBibliography(
"Tutorials" => [
"Tutorials overview" => "tutorials/index.md",
"tutorials/heat_equation.md",
"tutorials/heat_equation_hdiv.md",
"tutorials/linear_elasticity.md",
"tutorials/incompressible_elasticity.md",
"tutorials/hyperelasticity.md",
Expand All @@ -67,6 +68,7 @@ bibtex_plugin = CitationBibliography(
"tutorials/reactive_surface.md",
"tutorials/linear_shell.md",
"tutorials/dg_heat_equation.md",
"tutorials/maxwell.md",
],
"Topic guides" => [
"Topic guide overview" => "topics/index.md",
Expand Down
22 changes: 22 additions & 0 deletions docs/src/assets/references.bib
Original file line number Diff line number Diff line change
Expand Up @@ -190,3 +190,25 @@ @article{CroRav:1973:cnf
year={1973},
publisher={EDP Sciences}
}
@book{Gatica2014,
title = {A Simple Introduction to the Mixed Finite Element Method: Theory and Applications},
ISBN = {9783319036953},
ISSN = {2191-8201},
url = {http://dx.doi.org/10.1007/978-3-319-03695-3},
DOI = {10.1007/978-3-319-03695-3},
journal = {SpringerBriefs in Mathematics},
publisher = {Springer International Publishing},
author = {Gatica, Gabriel N.},
year = {2014}
}
@book{Boffi2013,
title = {Mixed Finite Element Methods and Applications},
ISBN = {9783642365195},
ISSN = {0179-3632},
url = {http://dx.doi.org/10.1007/978-3-642-36519-5},
DOI = {10.1007/978-3-642-36519-5},
journal = {Springer Series in Computational Mathematics},
publisher = {Springer Berlin Heidelberg},
author = {Boffi, Daniele and Brezzi, Franco and Fortin, Michel},
year = {2013}
}
238 changes: 238 additions & 0 deletions docs/src/literate-tutorials/heat_equation_hdiv.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,238 @@
# # [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
# [Fenics' mixed poisson example](https://fenicsproject.org/olddocs/dolfin/1.4.0/python/demo/documented/mixed-poisson/python/documentation.html).
KnutAM marked this conversation as resolved.
Show resolved Hide resolved
#
# ![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})$
#
# ## 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 = Ferrite.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 # ```
Loading