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

p4est datastructures #780

Open
wants to merge 159 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 140 commits
Commits
Show all changes
159 commits
Select commit Hold shift + click to select a range
6c830d7
add lookup tables and helper functions
koehlerson Aug 2, 2021
b47f930
clean up and tests for lookup
koehlerson Aug 2, 2021
294b463
added parent and child_id
koehlerson Aug 3, 2021
61fba0e
change to UInt8
koehlerson Aug 4, 2021
bbcac4d
fixed parent and included child_id for 2d case
koehlerson Aug 4, 2021
3c51d2c
fixed parent and included child_id for 2d case
koehlerson Aug 4, 2021
e4486cb
add check in parent for root node, added test for that
koehlerson Aug 4, 2021
a60ef58
add some comment about child_id ordering
koehlerson Aug 4, 2021
e827fa4
further test
koehlerson Aug 4, 2021
81290c4
added descendants, face edge and corner_neighbor, descendants, edge a…
koehlerson Aug 5, 2021
689997b
shifted morton index by 1 and included morton index constructor tests
koehlerson Aug 6, 2021
5ceba3f
include TODOs
koehlerson Aug 6, 2021
e70bf11
proper docstrings
koehlerson Aug 6, 2021
44d4c98
AssertionError in test for morton index constructor
koehlerson Aug 6, 2021
e33d859
fixed descendants, need to wait for zulip responds to confirm those c…
koehlerson Aug 6, 2021
98d8ac0
I think I have found a bug in tests and in child_id, now morton inde…
koehlerson Aug 7, 2021
5944c57
fix 2d version of child_id, added tests with child_id morton index ma…
koehlerson Aug 7, 2021
fa2509c
fixed edge neighbor, included 2D corner neighbor, included tests for …
koehlerson Aug 7, 2021
99f2fc6
maxlevel always last arg with default value based on Burstedde et al.
koehlerson Aug 9, 2021
517b6a6
started adaptive grid
koehlerson Aug 10, 2021
17f145f
corner neighborhood for 2D
koehlerson Aug 14, 2021
621c091
face neighbor for 2D
koehlerson Aug 14, 2021
96c9392
topology for 3D
koehlerson Aug 14, 2021
4871b45
Merge branch 'master' into mk/adaptivehex
koehlerson Oct 1, 2022
d352bb3
cleanup topology from the past
koehlerson Oct 1, 2022
a4a6d89
Merge branch 'master' into mk/p4est
koehlerson Oct 7, 2022
13c994f
add constructor for Octree and Forest
koehlerson Oct 7, 2022
4201ab9
maximumsize of octant
koehlerson Oct 7, 2022
af61a76
start of refine, not fully working yet
koehlerson Oct 10, 2022
834936f
Merge branch 'master' into mk/p4est
koehlerson Oct 10, 2022
9d91717
refinement works in 2D
koehlerson Oct 10, 2022
5199e0b
add morton dispatch for dimension 3 and test cases for dimension 3
koehlerson Oct 10, 2022
f3eadee
morton index tests, now works properly, need to generalize with a for…
koehlerson Oct 11, 2022
9e92ad6
found a bug in refine included unit tests for all cells refinement do…
koehlerson Oct 12, 2022
ee6489f
add parents test
koehlerson Oct 12, 2022
d309d34
add coarsening with tests; remove the parents test from before (sanit…
koehlerson Oct 12, 2022
21caf80
dimension generalization of morton function; parametrization of coord…
koehlerson Oct 12, 2022
ef8c905
better but not perfect parametrization for *_neighbor dispatches
koehlerson Oct 12, 2022
ebe9af8
dispatch as I wanted
koehlerson Oct 14, 2022
b7102e3
start interfacing the grid interface; non fully working version of tr…
koehlerson Oct 15, 2022
5f6ccd7
included getcells dispatch without index and with integer index, need…
koehlerson Oct 26, 2022
312cc48
generalize getcells for idx::Int dispatch
koehlerson Oct 26, 2022
85bb2d7
getcells(forest,i) was wrong before, now a version which seems to wor…
koehlerson Oct 27, 2022
7162191
add md
koehlerson Oct 27, 2022
a22b5a8
add warning for slow dispatches
koehlerson Oct 27, 2022
ba5cba9
make md file nice for quarto compilation
koehlerson Oct 30, 2022
d8e33a2
start of getnodes
koehlerson Oct 30, 2022
250966f
Merge branch 'master' into mk/p4est
koehlerson Oct 30, 2022
1e2bc7f
transform corner and a nonworking version of getnodes
koehlerson Oct 31, 2022
b4c89e7
include algorithm paper in md
koehlerson Nov 1, 2022
6dc687a
dimension agnostic child_id and introduction of ancestor_id
koehlerson Nov 4, 2022
3c56a70
add split_array
koehlerson Nov 4, 2022
2ca0180
little bit of utility and started the search implementation, however,…
koehlerson Nov 5, 2022
35cc7a1
add vertex, face and edge computation of octant
koehlerson Nov 6, 2022
a622955
octant boundary sets
koehlerson Nov 7, 2022
cbeaf8c
first non-working find_range_boundaries
koehlerson Nov 7, 2022
dc7866d
convenience find_range_boundaries dispatch
koehlerson Nov 8, 2022
3cd88d5
merge master and rename test_octant to test_p4est
koehlerson Dec 13, 2022
4fe94b2
merge master
koehlerson Dec 28, 2022
d71a63f
merge master
koehlerson Feb 21, 2023
fc74358
small bug
koehlerson Feb 22, 2023
5ef1218
introduce OctantIndices
koehlerson Feb 23, 2023
435e77e
successfully created a over complicated identity mapping
koehlerson Feb 23, 2023
9b7678c
Merge branch 'master' into mk/p4est
koehlerson Apr 14, 2023
9c993d4
get rid of boundarysettype and use union
koehlerson Apr 14, 2023
621731e
typo in recursive algo paper in find_range_boundaries algorithm 4.2 l…
koehlerson Apr 17, 2023
439d910
add placeholder for isrelevant algorithm 5.1
koehlerson Apr 17, 2023
e013d63
o instead of 1
koehlerson Apr 23, 2023
beccb63
merge master for 1.0 compatibility
koehlerson Jul 3, 2023
f194cb0
visualization script not included in Ferrite; transformation of point…
koehlerson Jul 3, 2023
8932233
1 based index fun in transform_face
koehlerson Jul 3, 2023
c1b1122
maybe a 2D working version of getnodes
koehlerson Jul 3, 2023
0bfd8a4
add refine_all and convenience transform_pointBWG
koehlerson Jul 4, 2023
6e96c8a
refine_all and coarsen_all at proper place; included some docs
koehlerson Jul 5, 2023
06e8d63
help
koehlerson Jul 5, 2023
6219524
enhance old algorithm by nodeid and nodeowners; need a isreplaced nod…
koehlerson Jul 6, 2023
09d1346
Merge branch 'master' into mk/p4est
koehlerson Jul 6, 2023
1834b3c
create grid works in 2D I guess
koehlerson Jul 6, 2023
e31d62b
be in inner peace by distributing with reversed policy
koehlerson Jul 6, 2023
f42f0a1
revert policy again, I'm not smart enough
koehlerson Jul 6, 2023
a33cb4a
add script to solve on p4est grid; works for unrefined grid already; …
koehlerson Jul 7, 2023
5a75a40
verify that it works for refinement even though boundarysets have bee…
koehlerson Jul 7, 2023
0d65967
Merge branch 'master' into mk/p4est
koehlerson Jul 19, 2023
155f326
Merge branch 'master' into mk/p4est
koehlerson Jul 31, 2023
afb54fa
reconstruct facesets in 2D for refined grid
koehlerson Jul 31, 2023
d7b3858
fix test
koehlerson Jul 31, 2023
6be5454
'localize' comparison of neighboring octree nodes
koehlerson Aug 2, 2023
53ce18a
simplify vertex similar to face check
koehlerson Aug 2, 2023
a5286db
start hanging nodes
koehlerson Aug 4, 2023
bc58095
interoctree hnodes detection
koehlerson Aug 4, 2023
9ef7cf6
I meant intraoctree..
koehlerson Aug 4, 2023
820432e
interoctree works for hanging nodes probably too, need more testing
koehlerson Aug 4, 2023
be6581e
solve with constraint
koehlerson Aug 4, 2023
39c4c02
initial nonworking version of balancing intraoctree
koehlerson Aug 7, 2023
2c88a95
Seems like working version of balancing intraoctree, need more tests
koehlerson Aug 8, 2023
72acdeb
remove bugs and add one more test for balancing
koehlerson Aug 8, 2023
05986ba
first interoctree balancing sketch, need further tests, first simple …
koehlerson Aug 8, 2023
f94d40f
first interoctree balancing sketch, need further tests, first simple …
koehlerson Aug 8, 2023
37e288d
more testing; not sure if nc level > 2 needs to be covered interoctre…
koehlerson Aug 8, 2023
9e53661
first sketch of adaptive manufactured solution; need to bookkeep a sh…
koehlerson Aug 8, 2023
21e7556
manufactured solution 2d adaptivity done
koehlerson Aug 8, 2023
1fa0c9b
Merge branch 'master' into mk/p4est
koehlerson Sep 28, 2023
fe5a6ad
started elasticity adaptivity example
koehlerson Oct 4, 2023
864677e
add application of affine constraints
koehlerson Oct 4, 2023
cd24959
the master of copy-pasta striked again; fixed balancing bug
koehlerson Oct 9, 2023
5dcbcae
first somewhat okayish looking elasticity
koehlerson Oct 9, 2023
f802c69
non-working L2 Projector
koehlerson Oct 10, 2023
df1f6ea
Add heat example and first hotfix for elasticity example.
termi-official Oct 10, 2023
2bf3a4e
Hotfix L2 projection with affine constraints.
termi-official Oct 10, 2023
70fffdf
Change solution for heat to something more local. AMR follows the sol…
termi-official Oct 10, 2023
bdcbb7b
make hotfix nicer
koehlerson Oct 10, 2023
26f5d41
Fix affine constaint for y component in elasticity example.
termi-official Oct 10, 2023
9503bd7
add vertex permutations to creategrid
koehlerson Oct 11, 2023
fab6539
[X-PR] p4est/p8est face transformation fix (#890)
termi-official Apr 9, 2024
0611729
p4est constraint handler integration (#900)
termi-official Apr 11, 2024
f57cfe2
[X-PR] p4est edge operations and consistent corner operation (#902)
koehlerson Apr 30, 2024
ecaae64
multiple corner connections in balancing
koehlerson May 2, 2024
7e69430
merge master
koehlerson May 7, 2024
c7f3c6f
remove changes in linear_elasticity.jl docs
koehlerson May 9, 2024
359c821
start some devdocs
koehlerson May 9, 2024
aed19ef
update docstrings and remove md file from home directory (moved into …
koehlerson May 9, 2024
a453798
a bit more devdocs
koehlerson May 9, 2024
6b0caa8
more devdocs
koehlerson May 9, 2024
08ad4d8
move things into submodule
koehlerson May 10, 2024
0eec30c
adjust devdocs to submodule
koehlerson May 10, 2024
20d0130
get_coordinate_eltype in vtk_grid
koehlerson May 10, 2024
9ddca47
use for now different mesh for docs build
koehlerson May 10, 2024
b4f7c4f
export refine_all into Ferrite namespace
koehlerson May 10, 2024
d11504f
fix doc build
koehlerson May 10, 2024
ffcdf96
Apply suggestions from code review
koehlerson May 13, 2024
9af1812
improve devdocs
koehlerson May 13, 2024
79ac08d
add relation of size computation and remove once the function call
koehlerson May 13, 2024
47c966e
Update docs/src/devdocs/AMR.md
koehlerson May 13, 2024
e7a4856
multiple corner connections test in 2D by disc discretization
koehlerson May 15, 2024
731dfbb
include multiple edge connection case with tests
koehlerson May 15, 2024
b237152
merge master and hotfix renaming
koehlerson May 21, 2024
361f8e0
add some topics docs on AMR
koehlerson May 21, 2024
d938b70
update examples and vtk export for abstractgrid
koehlerson May 22, 2024
d7a399e
update ns_vs_diffeq example?
koehlerson May 22, 2024
24d4f64
whoopsie
koehlerson May 22, 2024
92ac19f
Update src/Dofs/DofHandler.jl
koehlerson May 22, 2024
fb3df4c
make the pre-commit linter happy
koehlerson May 22, 2024
d788f96
fix DofHandler definition
koehlerson May 22, 2024
d54ae18
add amr to topics overview
koehlerson May 22, 2024
d9c4688
change tuple in dofhandler construction
koehlerson May 22, 2024
be5ac8a
change to get_facet_facet_neighborhood
koehlerson May 23, 2024
a0696b1
rename face to facet
koehlerson May 27, 2024
f5420de
Merge branch 'master' into mk/p4est
koehlerson May 27, 2024
f07da5f
face_neighbor to facet_neighbor
koehlerson May 27, 2024
c12a154
include simple maximum marking in elasticity example
koehlerson Jun 10, 2024
fb20338
add pvd export
koehlerson Jun 10, 2024
bc1db41
change qr for error estimator in elasticity example
koehlerson Jun 12, 2024
c746834
resolve reported bug by adjusting the nrefcells logic to something th…
koehlerson Jun 13, 2024
b7492cf
[skip ci] test coverage for failing MWEs in 3D
termi-official Jun 17, 2024
d50665d
Derp
termi-official Jun 18, 2024
8461ed6
typo in hanging nodes; doesn't resolve bug
koehlerson Jun 19, 2024
30a3b36
failing example; something fishy in the conformity info
koehlerson Jun 19, 2024
9b38d62
Fix shared edge node detection.
termi-official Jun 19, 2024
b913af4
heat_adaptivity 3D version for debugging
koehlerson Jun 19, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
3 changes: 2 additions & 1 deletion docs/make.jl
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,8 @@ bibtex_plugin = CitationBibliography(
"topics/boundary_conditions.md",
"topics/constraints.md",
"topics/grid.md",
"topics/export.md"
"topics/export.md",
"topics/amr.md"
],
"Reference" => [
"Reference overview" => "reference/index.md",
Expand Down
30 changes: 30 additions & 0 deletions docs/src/assets/references.bib
Original file line number Diff line number Diff line change
Expand Up @@ -123,3 +123,33 @@ @article{Mu:2014:IP
keywords = {Discontinuous Galerkin, Finite element, Interior penalty, Second-order elliptic equations, Hybrid mesh},
abstract = {This paper provides a theoretical foundation for interior penalty discontinuous Galerkin methods for second-order elliptic equations on very general polygonal or polyhedral meshes. The mesh can be composed of any polygons or polyhedra that satisfy certain shape regularity conditions characterized in a recent paper by two of the authors, Wang and Ye (2012) [11]. The usual H1-conforming finite element methods on such meshes are either very complicated or impossible to implement in practical computation. The interior penalty discontinuous Galerkin method provides a simple and effective alternative approach which is efficient and robust. Results with such general meshes have important application in computational sciences.}
}
@article{BWG2011,
title={p4est: Scalable algorithms for parallel adaptive mesh refinement on forests of octrees},
author={Burstedde, Carsten and Wilcox, Lucas C and Ghattas, Omar},
journal={SIAM Journal on Scientific Computing},
volume={33},
number={3},
pages={1103--1133},
year={2011},
publisher={SIAM}
}
@article{IBWG2015,
title={Recursive algorithms for distributed forests of octrees},
author={Isaac, Tobin and Burstedde, Carsten and Wilcox, Lucas C and Ghattas, Omar},
journal={SIAM Journal on Scientific Computing},
volume={37},
number={5},
pages={C497--C531},
year={2015},
publisher={SIAM}
}
@article{SSB2008,
title={Bottom-up construction and 2: 1 balance refinement of linear octrees in parallel},
author={Sundar, Hari and Sampath, Rahul S and Biros, George},
journal={SIAM Journal on Scientific Computing},
volume={30},
number={5},
pages={2675--2708},
year={2008},
publisher={SIAM}
}
217 changes: 217 additions & 0 deletions docs/src/devdocs/AMR.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,217 @@
# Adaptive Mesh Refinement (AMR)

## P4est

Ferrite's P4est implementation is based on these papers:

- [BWG2011](@citet)
- [IBWG2015](@citet)

where almost everything is implemented in a serial way from the first paper.
Only certain specific algorithms of the second paper are implemented and there is a lot of open work to include the iterators of the second paper.
Look into the issues of Ferrite.jl and search for the AMR tag.

### Important Concepts

One of the most important concepts, which everything is based on, are space filling curves (SFC).
In particular, [Z-order (also named Morton order, Morton space-filling curves)](https://en.wikipedia.org/wiki/Z-order_curve) are used in p4est.
The basic idea is that each Octant (in 3D) or quadrant (in 2D) can be encoded by 2 quantities

- the level `l`
- the lower left (front) coordinates `xyz`
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here I got a bit confused since we change meaning of "lower" and "front" going 2d to 3d. Should it say something like "the coordinates of the vertex with the smallest coordinates" (not sure how to describe the best, from the restriction would "the coordinates of the vertex closest to the origin" work?)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What do you mean with changing the meaning by going 2d to 3d? Do you mean that Ferrite does this? I think the problem is that you need to define where the origin is and they decided for the lower left front coordinate (without rotation)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, in Ferrite and 2d, bottom/top refers to the y-coordinate, but in 3d bottom/top refers to the z-coordinate (and front/back to the y-coordinate). I was confused because I first thought front would be the largest coordinate value (but it isn't), so it is correct (and logical) the way it is defined. But I find that refering to what is closest to the orgin / has the smallest coordinate value is easier, since it doesn't require knowing what is defined as front/back, left/right etc.

julia> grid = generate_grid(Hexahedron, (1,1,1));

julia> x = getcoordinates(grid, 1);

julia> fv = FaceValues(FaceQuadratureRule{RefHexahedron}(1), Lagrange{RefHexahedron,1}());

julia> for (key, face) in grid.facesets
           reinit!(fv, x, first(face)[2])
           println(key, ": ", spatial_coordinate(fv, 1, x))
       end
left: [-1.0, 0.0, 0.0]
bottom: [0.0, 0.0, -1.0]
right: [1.0, 0.0, 0.0]
back: [0.0, 1.0, 0.0]
top: [0.0, 0.0, 1.0]
front: [0.0, -1.0, 0.0]

julia> grid = generate_grid(Quadrilateral, (1,1));

julia> x = getcoordinates(grid, 1);

julia> fv = FaceValues(FaceQuadratureRule{RefQuadrilateral}(1), Lagrange{RefQuadrilateral,1}());

julia> for (key, face) in grid.facesets
           reinit!(fv, x, first(face)[2])
           println(key, ": ", spatial_coordinate(fv, 1, x))
       end
left: [-1.0, 0.0]
bottom: [0.0, -1.0]
right: [1.0, 0.0]
top: [0.0, 1.0]

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK, I see. I think it's just two different ways of attaching meaning to "lower", "left" etc, where p4est seems to be strict with the z-order logic. AFAIU the problem with defining the origin based on the lowest coordinate is that it would be a circular definition. You need some anchor point to define the coordinate system. The anchor point you choose will inevitably have the lowest coordinates.


Based on them a unique identifier, the morton index, can be computed.
The mapping from (`l`, `xyz`) -> `mortonidx(l,xyz)` is bijective, meaning we can flip the approach
and can construct each octant/quadrant solely by the `mortonidx` and a given level `l`.

The current implementation of an octant looks currently like this:
```julia
struct OctantBWG{dim, N, T} <: AbstractCell{RefHypercube{dim}}
koehlerson marked this conversation as resolved.
Show resolved Hide resolved
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
struct OctantBWG{dim, N, T} <: AbstractCell{RefHypercube{dim}}
struct OctantBWG{dim, N, T <: Integer} <: AbstractCell{RefHypercube{dim}}

And is this an ok restriction? Would make the discreteness clearer IMO

#Refinement level
l::T
#x,y,z \in {0,...,2^b} where (0 ≤ l ≤ b)}
xyz::NTuple{dim,T}
end
```
whenever coordinates are considered we follow the z order logic, meaning x before y before z.
Note that the acronym BWG stands for the initials of the surname of the authors of the p4est paper.
The coordinates of an octant are described in the *octree coordinate system* which goes from $[0,2^b]^{dim}$.
The parameter $b$ describes the maximum level of refinement and is set a priori.
Another important aspect of the octree coordinate system is, that it is a discrete integer coordinate system.
The size of an octant at the lowest possible level `b` is always 1, sometimes these octants are called atoms.

The octree is implemented as:
```julia
struct OctreeBWG{dim,N,T} <: AbstractAdaptiveCell{RefHypercube{dim}}
leaves::Vector{OctantBWG{dim,N,T}}
#maximum refinement level
b::T
nodes::NTuple{N,Int}
end
```

So, only the leaves of the tree are stored and not any intermediate refinement level.
The field `b` is the maximum refinement level and is crucial. This parameter determines the size of the octree coordinate system.
The octree coordinate system is the coordinate system in which the coordinates `xyz` of any `octant::OctantBWG` are described.

### Examples

Let's say the maximum octree level is $b=3$, then the coordinate system is in 2D $[0,2^3]^2 = [0, 8]^2$.
So, our root is on level 0 of size 8 and has the lower left coordinates `(0,0)`

```julia
# different constructors available, first one OctantBWG(dim,level,mortonid,maximumlevel)
# other possibility by giving directly level and a tuple of coordinates OctantBWG(level,(x,y))
julia> dim = 2; level = 0; maximumlevel=3
julia> oct = OctantBWG(dim,level,1,maximumlevel)
OctantBWG{2,4,4}
l = 0
xy = 0,0
```
The size of octants at a specific level can be computed by a simple operation
```julia
julia> Ferrite.AMR._compute_size(#=b=#3,#=l=#0)
8
```
This computation is based on the relation $\text{size}=2^{b-l}$.
Now, to fully understand the octree coordinate system we go a level down, i.e. we cut the space in $x$ and $y$ in half.
This means, that the octants are now of size $2^{3-1}=4$.
Construct all level 1 octants based on mortonid:
```julia
# note the arguments are dim,level,mortonid,maximumlevel
julia> dim = 2; level = 1; maximumlevel = 3
julia> oct = Ferrite.AMR.OctantBWG(dim, level, 1, maximumlevel)
OctantBWG{2,4,4}
l = 1
xy = 0,0

julia> oct = Ferrite.AMR.OctantBWG(dim, level, 2, maximumlevel)
OctantBWG{2,4,4}
l = 1
xy = 4,0

julia> oct = Ferrite.AMR.OctantBWG(dim, level, 3, maximumlevel)
OctantBWG{2,4,4}
l = 1
xy = 0,4

julia> oct = Ferrite.AMR.OctantBWG(dim, level, 4, maximumlevel)
OctantBWG{2,4,4}
l = 1
xy = 4,4
```

So, the morton index is on **one** specific level just a x before y before z "cell" or "element" identifier
```
x-----------x-----------x
| | |
| | |
| 3 | 4 |
| | |
| | |
x-----------x-----------x
| | |
| | |
| 1 | 2 |
| | |
| | |
x-----------x-----------x
```

The operation to compute octants/quadrants is cheap, since it is just bitshifting.
An important aspect of the morton index is that it's only consecutive on **one** level in this specific implementation.
Note that other implementation exists that incorporate the level integer within the morton identifier and by that have a unique identifier across levels.
If you have a tree like this below:

```
x-----------x-----------x
| | |
| | |
| 9 | 10 |
| | |
| | |
x-----x--x--x-----------x
| |6 |7 | |
| 3 x--x--x |
| |4 |5 | |
x-----x--x--x 8 |
| | | |
| 1 | 2 | |
x-----x-----x-----------x
```

you would maybe think this is the morton index, but strictly speaking it is not.
What we see above is just the `leafindex`, i.e. the index where you find this leaf in the `leaves` array of `OctreeBWG`.
Let's try to construct the lower right based on the morton index on level 1

```julia
julia> o = Ferrite.OctantBWG(2,1,8,3)
ERROR: AssertionError: m ≤ (one(T) + one(T)) ^ (dim * l) # 8 > 4
Stacktrace:
[1] OctantBWG(dim::Int64, l::Int32, m::Int32, b::Int32)
@ Ferrite ~/repos/Ferrite.jl/src/Adaptivity/AdaptiveCells.jl:23
[2] OctantBWG(dim::Int64, l::Int64, m::Int64, b::Int64)
@ Ferrite ~/repos/Ferrite.jl/src/Adaptivity/AdaptiveCells.jl:43
[3] top-level scope
@ REPL[93]:1
```

The assertion expresses that it is not possible to construct a morton index 8 octant, since the upper bound of the morton index is 4 on level 1.
The morton index of the lower right cell is 2 on level 1.

```julia
julia> o = Ferrite.AMR.OctantBWG(2,1,2,3)
OctantBWG{2,4,4}
l = 1
xy = 4,0
```

### Octant operation

There are multiple useful functions to compute information about an octant e.g. parent, childs, etc.

```@docs
Ferrite.AMR.isancestor
Ferrite.AMR.morton
Ferrite.AMR.children
Ferrite.AMR.vertices
Ferrite.AMR.edges
Ferrite.AMR.faces
Ferrite.AMR.transform_pointBWG
```

### Intraoctree operation

Intraoctree operation stay within one octree and compute octants that are attached in some way to a pivot octant `o`.
These operations are useful to collect unique entities within a single octree or to compute possible neighbors of `o`.
[BWG2011](@citet) Algorithm 5, 6, and 7 describe the following intraoctree operations:

```@docs
Ferrite.AMR.corner_neighbor
Ferrite.AMR.edge_neighbor
Ferrite.AMR.face_neighbor
Ferrite.AMR.possibleneighbors
```

### Interoctree operation

Interoctree operation are in contrast to intraoctree operation by computing octant transformations across different octrees.
Thereby, one needs to account for topological connections between the octrees as well as possible rotations of the octrees.
[BWG2011](@citet) Algorithm 8, 10, and 12 explain the algorithms that are implemented in the following functions:

```@docs
Ferrite.AMR.transform_corner
Ferrite.AMR.transform_edge
Ferrite.AMR.transform_face
```

Note that we flipped the input and to expected output logic a bit to the proposed algorithms of the paper.
However, the original proposed versions are implemented as well in:

```@docs
Ferrite.AMR.transform_corner_remote
Ferrite.AMR.transform_edge_remote
Ferrite.AMR.transform_face_remote
```

despite being never used in the code base so far.
2 changes: 1 addition & 1 deletion docs/src/devdocs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,5 @@ developing the library.

```@contents
Depth = 1
Pages = ["reference_cells.md", "interpolations.md", "elements.md", "FEValues.md", "dofhandler.md", "performance.md"]
Pages = ["reference_cells.md", "interpolations.md", "elements.md", "FEValues.md", "dofhandler.md", "performance.md", "AMR.md"]
```