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

Trixi on unstructured mesh of 2d curved quads #500

Merged
merged 59 commits into from
Apr 16, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
59 commits
Select commit Hold shift + click to select a range
52a985b
added curve interpolant and geometric mappings for 2d curved quads
andrewwinters5000 Mar 26, 2021
54ac6cd
fix type declaration in ElementGeometry
ranocha Mar 26, 2021
91c626a
first working mesh file readin and geometry construction routines.
andrewwinters5000 Mar 29, 2021
5204876
improved comments and cleanup of code. Can use polydeg <= mesh polydeg
andrewwinters5000 Mar 30, 2021
c040f2c
adjusted containers to have surface u and flux values
andrewwinters5000 Apr 1, 2021
3eeda35
first version of right hand side computation of unstructued 2d mesh i…
andrewwinters5000 Apr 6, 2021
791f0b6
convergence working for the 2D curvilinear routines with compressible…
andrewwinters5000 Apr 6, 2021
8be628a
now can handle general meshes but boundary conditions are set via the…
andrewwinters5000 Apr 6, 2021
0207888
added rotation and backrotation routines
andrewwinters5000 Apr 7, 2021
d88ab16
restructure and streamlined the element container to fit better into …
andrewwinters5000 Apr 7, 2021
47100eb
refactor of the interface containers. separated interior and boundary…
andrewwinters5000 Apr 8, 2021
3b8cb2a
Merge branch 'main' into curved_trixi
andrewwinters5000 Apr 8, 2021
2d6f62f
reorganize to avoid naming confusion with structured curved DG implem…
andrewwinters5000 Apr 8, 2021
1809039
improved caches and reworked UnstructuredMesh struct
andrewwinters5000 Apr 8, 2021
88b8a8d
slight restructure of information and include statements
andrewwinters5000 Apr 8, 2021
145ee50
removed ElementGeoemtry struct and reconfigured where geometry inform…
andrewwinters5000 Apr 9, 2021
73b734b
restructure of the mesh struct, container constructors and cache crea…
andrewwinters5000 Apr 9, 2021
e0bb202
appended dummy argument to rhs functions to ensure correct dispatch
andrewwinters5000 Apr 9, 2021
1d70412
Merge branch 'main' into curved_trixi
andrewwinters5000 Apr 9, 2021
8214c2c
reorganized files into a new folder name
andrewwinters5000 Apr 9, 2021
bb1e033
new solver partially integrated into the Trixi ecosystem
andrewwinters5000 Apr 9, 2021
1ab63a2
cleanup of dg_2d for the unstructured solver. Now reuses apply_jacobi…
andrewwinters5000 Apr 9, 2021
fad7295
moved rotation routines into compressible_euler_2d, should be combine…
andrewwinters5000 Apr 9, 2021
5dcb20a
removed another TODO
andrewwinters5000 Apr 9, 2021
ab462a9
first working version of the unstructured solver in the Trixi ecosystem
andrewwinters5000 Apr 9, 2021
d26ef4d
added two tests for the new unstructured solver
andrewwinters5000 Apr 9, 2021
84832b6
improve type stability of UnstructuredQuadMesh and reduce unnecessary…
ranocha Apr 11, 2021
1aef54a
minor improvement of unstructured mesh parsing
ranocha Apr 11, 2021
53b4421
Support rudimentary plotting for unstructured quad meshes
sloede Apr 12, 2021
ab2ee5a
adjusted variable names and loop iterators across the unstructured im…
andrewwinters5000 Apr 13, 2021
dbc3146
changed the variable names in the transfinite quad map and metrics fu…
andrewwinters5000 Apr 13, 2021
5d8687a
now dispatch for things like calc_volume_integral by including the un…
andrewwinters5000 Apr 13, 2021
214297b
adjusted naming in calc_interface_flux to clearly differentiate betwe…
andrewwinters5000 Apr 13, 2021
c7eb612
variable renaming the curve interpolant
andrewwinters5000 Apr 13, 2021
edb36ca
Merge branch 'main' into curved_trixi
andrewwinters5000 Apr 13, 2021
c13efc4
first attempt at adding plot grid lines capability to the unstructure…
andrewwinters5000 Apr 13, 2021
653162d
added the UnstructuredQuadMesh to the visualization testing
andrewwinters5000 Apr 14, 2021
5d2eec4
made Float64 the default type for UnstructuredQuadMesh
andrewwinters5000 Apr 14, 2021
c399451
UnstructuredQuadMesh no longer has NDIMS as a type paramter. Also upd…
andrewwinters5000 Apr 14, 2021
e5a02a5
draft of the docs for the unstructured mesh information and orientation
andrewwinters5000 Apr 14, 2021
420bdb9
wrote small extraction routines to avoid allocations in the interface…
andrewwinters5000 Apr 15, 2021
6df9265
add new docs to the docs and fix typo
ranocha Apr 15, 2021
ed0e2dd
Merge branch 'curved_trixi' of github.com:andrewwinters5000/Trixi.jl …
ranocha Apr 15, 2021
96c85e1
changes suggested by Hendrik on argument ordering
andrewwinters5000 Apr 15, 2021
43aecaf
merge with remote
andrewwinters5000 Apr 15, 2021
46b9834
added line breaks and fixed LaTeX error in docs for unstructured mesh
andrewwinters5000 Apr 15, 2021
595a506
mention numbering convention for curved structured mesh too
andrewwinters5000 Apr 15, 2021
34e81b1
reorder arguements and added a commented docstring for the curve inte…
andrewwinters5000 Apr 15, 2021
98de76b
removed unnecessary tangent vectors from unstructured implementation.…
andrewwinters5000 Apr 15, 2021
cf2121e
Merge branch 'main' into curved_trixi
andrewwinters5000 Apr 15, 2021
e1d3955
adjusted naming of GammaCurve to CurvedSurface
andrewwinters5000 Apr 16, 2021
1caef0f
renamed mesh files
andrewwinters5000 Apr 16, 2021
40b4b98
make error message more descriptive
ranocha Apr 16, 2021
086e9f4
Merge branch 'curved_trixi' of github.com:andrewwinters5000/Trixi.jl …
ranocha Apr 16, 2021
f27a96f
use powers instead of multiplication in normal vector construction. R…
andrewwinters5000 Apr 16, 2021
70bb96c
Merge branch 'curved_trixi' of github.com:andrewwinters5000/Trixi.jl …
andrewwinters5000 Apr 16, 2021
b95c7b6
swapped ordering of coordinates in CurvedSurface
andrewwinters5000 Apr 16, 2021
81a7773
Merge branch 'main' into curved_trixi
andrewwinters5000 Apr 16, 2021
30b7559
Merge branch 'main' into curved_trixi
ranocha Apr 16, 2021
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
3 changes: 3 additions & 0 deletions docs/make.jl
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,9 @@ makedocs(
"Home" => "index.md",
"Visualization" => "visualization.md",
"Conventions" => "conventions.md",
"Meshes" => [
"Unstructured mesh" => joinpath("unstructured_quad_mesh", "unstructured_quad_mesh.md"),
],
"Time integration" => "time_integration.md",
"Callbacks" => "callbacks.md",
"Development" => "development.md",
Expand Down
2 changes: 1 addition & 1 deletion docs/src/conventions.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

## Spatial dimensions and directions

We use the following numbering schemes on Cartesian meshes.
We use the following numbering schemes on Cartesian or curved structured meshes.
- The `orientation`s are numbered as
`1 => x, 2 => y, 3 => z`.
For example, numerical fluxes such as
Expand Down
44 changes: 44 additions & 0 deletions docs/src/unstructured_quad_mesh/example.mesh
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
7 9 3 8
1.0 -1.0
3.0 0.0
1.0 1.0
2.0 0.0
0.0 0.0
3.0 1.0
3.0 -1.0
2 4 3 2 2 -1
3 5 1 0 4 0
1 5 1 0 1 0
1 4 1 3 2 3
2 6 2 0 2 0
1 7 3 0 4 0
3 6 2 0 3 0
2 7 3 0 1 0
3 4 2 1 4 -3
5 1 4 3
0 0 1 0
1.000000000000000 1.000000000000000
1.024948365654583 0.934461926834452
1.116583018200151 0.777350964621867
1.295753434047077 0.606254343587194
1.537500000000000 0.462500000000000
1.768263070247418 0.329729152118310
1.920916981799849 0.185149035378133
1.986035130050921 0.054554577460044
2.000000000000000 0
Slant1 --- --- Slant2
4 2 6 3
0 0 0 1
2.000000000000000 0
1.986035130050921 0.054554577460044
1.920916981799849 0.185149035378133
1.768263070247418 0.329729152118310
1.537500000000000 0.462500000000000
1.295753434047077 0.606254343587194
1.116583018200151 0.777350964621867
1.024948365654583 0.934461926834452
1.000000000000000 1.000000000000000
--- Right Top ---
7 2 4 1
0 0 0 0
Right --- --- Bottom
81 changes: 81 additions & 0 deletions docs/src/unstructured_quad_mesh/example.mesh.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
# General information (could be omitted -> implicit from size of other data structures)
n_corners = 7
n_surfaces = 9
n_elements = 3
mesh_poly_deg = 8

# Coordinates of the corner nodes, stored as `(x,y)` pairs
corner_nodes = [
[1.0, -1.0],
[3.0, 0.0],
[1.0, 1.0],
[2.0, 0.0],
[0.0, 0.0],
[3.0, 1.0],
[3.0, -1.0],
]

# Information about the edges
# - start node, end node
# - primary ("left") element, secondary ("right") element
# - local surface index on primary element, local surface index on secondary element
# A value of zero indicates a boundary interface, a negative value means the secondary element's
# coordinate system if flipped with respect to the primary element's coordinate system
edges = [
[2, 4, 3, 2, 2, -1],
[3, 5, 1, 0, 4, 0],
[1, 5, 1, 0, 1, 0],
[1, 4, 1, 3, 2, 3],
[2, 6, 2, 0, 2, 0],
[1, 7, 3, 0, 4, 0],
[3, 6, 2, 0, 3, 0],
[2, 7, 3, 0, 1, 0],
[3, 4, 2, 1, 4, -3],
]

# Label for each edge: `---` indicates an internal interface, other strings indicate boundaries
edge_labels = [
"---",
"Slant2",
"Slant1",
"---",
"Right",
"Bottom",
"Top",
"Right",
"---",
]

# List of nodes for each element. The starting node indicates the origin of the local coordinate
# system and the nodes are sorted counter-clockwise to yield a right-handed system (i.e., the
# direction from the first to the second node indicates the `\xi` direction)
element_nodes = [
[5, 1, 4, 3],
[4, 2, 6, 3],
[7, 2, 4, 1],
]

# Store for each element if its edges are straight (indicated by `0`) or curved (indicate by
# nonzero value). Nonzero values give the index to the edge coordinates in `element_curves`: a
# positive value means the coordinates are stored according to the right-handed system, a negative
# index means they need to be flipped.
element_curved_edges = [
[0, 0, 1, 0],
[0, 0, -1, 0],
[0, 0, 0, 0],
]

# Store the node locations for each curve
element_curves = [
[
[1.000000000000000, 1.000000000000000],
[1.024948365654583, 0.934461926834452],
[1.116583018200151, 0.777350964621867],
[1.295753434047077, 0.606254343587194],
[1.537500000000000, 0.462500000000000],
[1.768263070247418, 0.329729152118310],
[1.920916981799849, 0.185149035378133],
[1.986035130050921, 0.054554577460044],
[2.000000000000000, 0.000000000000000],
],
]
Binary file added docs/src/unstructured_quad_mesh/example_mesh.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
182 changes: 182 additions & 0 deletions docs/src/unstructured_quad_mesh/unstructured_quad_mesh.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,182 @@
# Unstructured quadrilateral mesh

Herein we describe the conventions taken in the implementation for two-dimensional unstructured
quadrilateral meshes. Principally, this relates to how a file with the extension `.mesh` encodes
information about the numbering and orientation of elements in an unstructured quadrilateral mesh
with possibly curved boundaries.

We use the following unstructured mesh with three elements for this discussion:

![example-mesh](https://user-images.githubusercontent.com/25242486/114917530-552eac00-9e26-11eb-9d79-baed4d4c4c66.png)

Further, we provide a complete mesh file below in the format that could be read into Trixi.


## Mesh file header

The first line of the mesh file lists the total number of *corners*, *surfaces*, *elements*, and
the *polynomial degree* that the mesh will use to represent any curved sides. For the example mesh
these quantities are
```
7 9 3 8
```
corresponding to seven corners, nine surfaces, and three elements. The mesh polynomial degree of
eight is taken only for illustrative purposes. In practice, this mesh polynomial degree depends on
the particular application for which the curved, unstructured mesh is required.


## List of corner nodes

After these global counts that prescribe information about the mesh skeleton, the mesh file give a
list of the physical `(x,y)` coordinates of all the corners. The corner nodes are listed in the
order prescribed by mesh generator. Thus, for the example mesh this node list would be
```
1.0 -1.0
3.0 0.0
1.0 1.0
2.0 0.0
0.0 0.0
3.0 1.0
3.0 -1.0
```
andrewwinters5000 marked this conversation as resolved.
Show resolved Hide resolved
The corner nodes are internally referenced by their position in the list above. For example, here
the node at `(1.0, -1.0)` would have node id 1, node id 2 would be at `(3.0, 0.0)` etc.


## List of neighbor connectivity

After the corner list comes the neighbor connectivity along each surface in the mesh. This includes
local indexing and orientation information necessary to compute the coupling between elements in
the mesh. In 2D each surface is defined by connecting two nodes indexed as with the numbering
above. We adopt the convention that node id 1 < node id 2.

Each surface will have two neighbors where the element on the left locally as one "walks" from node
id 1 to node id 2 is taken to be the `primary` element and the element locally on the right is
taken to be the `secondary` element. If, however, there is no secondary element index, then the
surface lies along a physical boundary. In this case the only available element index is considered
to be `primary` and the secondary index is set to zero.

The final two index numbers within the neighbor information list are used to identify the local
surface within each element. The first local surface index (on the primary element) will always be
positive whereas the second local surface index (on the primary element) can be positive or
negative. If the second local surface index is positive, then the local coordinate systems in the
primary element and secondary element match, i.e., the indexing on either side runs from
`1:polydeg+1`. However, if the local surface index of the secondary element is negative in the mesh
file, then the coordinate system in the secondary element is **flipped** with respect to the
primary element. Therefore, care must be taken in the implementation to ensure that the primary
element indexing runs from `1:polydeg+1` whereas the secondary element indexing must run in reverse
from `polydeg+1:-1:1`. Finally, if the secondary element index is zero, then so will be the local
surface index because the surface is on a physical boundary. Also, there is no *flipping* of
coordinate indexing required at the physical boundary because only the primary element's coordinate
system exists.

### Three examples: One along a physical boundary and two along interior surfaces.

Along edge `{8}` we connect node `(2)` to node `(7)` and are along a physical boundary in element
`3` with the local surface index 1 and the neighbor information:
```
2 7 3 0 1 0
```

Along edge `{1}` we connect node `(2)` to node `(4)` such that the primary element is `3` with
local surface index `2` and the secondary element is `2` with local surface index `1`. Furthermore,
we see that coordinate system in the secondary element `2` is **flipped** with respect to the
primary element's coordinate system such that the sign of the local surface index in the secondary
element flips. This gives the following neighbor information:
```
2 4 3 2 2 -1
```

Along edge `{4}` we connect node `(1)` to node `(4)` such that the primary element is `1` with
local surface index `2` and the secondary element is `3` with local surface index `3`. The
coordinate systems in both elements match and no sign change is required on the local surface
index in the secondary element:
```
1 4 1 3 2 3
```

We collect the complete neighbor information for the example mesh above:
```
2 4 3 2 2 -1
3 5 1 0 4 0
1 5 1 0 1 0
1 4 1 3 2 3
2 6 2 0 2 0
1 7 3 0 4 0
3 6 2 0 3 0
2 7 3 0 1 0
3 4 2 1 4 -3
```

## List of elements

Each quadrilateral element in the unstructured mesh is dictated by four corner points with indexing
taken from the numbering given by the corner list above. We connect a set of four corner points
(starting from the bottom left) in an anti-clockwise fashion thus making the element *right-handed*
indicated using the circular arrow in the figure above. In turn, this right-handedness defines the
local surface indexing (i.e. the four local sides) and the local $(\xi, \eta)$ coordinate
system. For example, the four corners for element 1 would be listed as
```
5 1 4 3
```

The mesh file also encodes information for curved surfaces either interior to the domain (as
surface `{9}` above) or along the physical boundaries. A set of check digits are included
directly below the four corner indexes to indicate whether the local surface index (`1`, `2`,
`3`, or `4`) within the element is straight sided, `0`, or is curved, `1`. If the local surface
is straight sided no additional information is necessary during the mesh file read in. But for
any curved surfaces the mesh file provides `(x,y)` coordinate values in order to construct an
interpolant of this surface with the mesh polynomial order at the Chebyshev-Gauss-Lobatto
nodes. This list of `(x,y)` data will be given in the direction of the local coordinate system.

The last piece of information provided by the mesh file are labels for the different surfaces of an
element. These labels are useful to set boundary conditions along physical surfaces. The labels can
be short descriptive words. The label `---` indicates an internal surface where no boundary
condition is required.

As an example, the complete information for element `1` in the example mesh would be
```
5 1 4 3
0 0 1 0
1.000000000000000 1.000000000000000
1.024948365654583 0.934461926834452
1.116583018200151 0.777350964621867
1.295753434047077 0.606254343587194
1.537500000000000 0.462500000000000
1.768263070247418 0.329729152118310
1.920916981799849 0.185149035378133
1.986035130050921 0.054554577460044
2.000000000000000 0
Slant1 --- --- Slant2
```

We collect the complete set of element information for the example mesh
```
5 1 4 3
0 0 1 0
1.000000000000000 1.000000000000000
1.024948365654583 0.934461926834452
1.116583018200151 0.777350964621867
1.295753434047077 0.606254343587194
1.537500000000000 0.462500000000000
1.768263070247418 0.329729152118310
1.920916981799849 0.185149035378133
1.986035130050921 0.054554577460044
2.000000000000000 0
Slant1 --- --- Slant2
4 2 6 3
0 0 0 1
2.000000000000000 0
1.986035130050921 0.054554577460044
1.920916981799849 0.185149035378133
1.768263070247418 0.329729152118310
1.537500000000000 0.462500000000000
1.295753434047077 0.606254343587194
1.116583018200151 0.777350964621867
1.024948365654583 0.934461926834452
1.000000000000000 1.000000000000000
--- Right Top ---
7 2 4 1
0 0 0 0
Right --- --- Bottom
```
54 changes: 54 additions & 0 deletions examples/2d/elixir_euler_unstructured_quad.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@

using OrdinaryDiffEq
using Trixi

###############################################################################
# semidiscretization of the compressible Euler equations

equations = CompressibleEulerEquations2D(1.4)

initial_condition = initial_condition_convergence_test
source_terms = source_terms_convergence_test
boundary_conditions = boundary_condition_convergence_test

###############################################################################
# Get the DG approximation space

polydeg = 5
surface_flux = flux_hll
solver = DGSEM(polydeg, surface_flux)

###############################################################################
# Get the curved quad mesh from a file

mesh_file = joinpath(@__DIR__, "mesh_box_around_circle.mesh")
periodicity = false
mesh = UnstructuredQuadMesh(mesh_file, periodicity)

###############################################################################
# create the semi discretization object

semi = SemidiscretizationHyperbolic(mesh, equations, initial_condition, solver,
source_terms=source_terms,
boundary_conditions=boundary_conditions)

###############################################################################
# ODE solvers, callbacks etc.

tspan = (0.0, 1.0)
ode = semidiscretize(semi, tspan)

summary_callback = SummaryCallback()

analysis_interval = 100
analysis_callback = AnalysisCallback(semi, interval=analysis_interval)

alive_callback = AliveCallback(analysis_interval=analysis_interval)

callbacks = CallbackSet(summary_callback, analysis_callback, alive_callback)

###############################################################################
# run the simulation

sol = solve(ode, SSPRK43(), save_everystep=false, callback=callbacks);
summary_callback() # print the timer summary
Loading