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