Skip to content

Commit

Permalink
Merge pull request #61 from FluidNumerics/feature/blockmesh2d
Browse files Browse the repository at this point in the history
Feature/blockmesh2d
  • Loading branch information
garrettbyrd authored Oct 14, 2024
2 parents 371d535 + ef5b5fd commit 091f424
Show file tree
Hide file tree
Showing 908 changed files with 41,894 additions and 15,641 deletions.
20 changes: 20 additions & 0 deletions .github/workflows/main-docs.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
name: Publish documentation
on:
push:
branches:
- main

jobs:
build:
name: Deploy docs
runs-on: ubuntu-latest
steps:
- name: Checkout main
uses: actions/checkout@v2

- name: Deploy docs
uses: mhausenblas/mkdocs-deploy-gh-pages@master
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
CONFIG_FILE: mkdocs.yml
REQUIREMENTS: docs/requirements.txt
1 change: 1 addition & 0 deletions docs/GettingStarted/building-with-self.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
# Using SELF to Build your own applications
File renamed without changes.
244 changes: 165 additions & 79 deletions docs/GettingStarted/install.md

Large diffs are not rendered by default.

Empty file added docs/MeshGeneration/HOPr.md
Empty file.
12 changes: 12 additions & 0 deletions docs/MeshGeneration/Overview.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@

## Overview of Mesh generation
<figure markdown="span">
![Image title](img/spectral-element-mesh.png){ width=600 }
<figcaption></figcaption>
</figure>

Every model in SELF needs to be associated with an interpolant, a mesh, and geometry. SELF uses a static unstructured mesh of elements. Within each element is a structured grid where the points in computational space are defined at Gauss-type quadrature points (Legendre Gauss or Legendre Gauss Lobatto).

The typical workflow for instantiating a model is to first create the mesh and the interpolant. The mesh defines the bounding vertices for each element, the relationship between the vertex IDs and the elements, the relationship between the bounding edges(2-D)/faces(3-D) and the neighboring elements, material identifiers for each element, and boundary conditions for physical model boundaries. The interpolant specifies the degree of the Lagrange interpolating polynomial and the interpolation knots. For spectral accuracy, the interpolation knots are equal to the quadrature points and are either `GAUSS` or `GAUSS_LOBATTO`. This in turn determines weights used in the interpolation and differentiation routines.

From the mesh and interpolant information, we can create the geometry details. The geometry includes the physical positions, covariant basis vectors, contravariant basis vectors, and the jacobian of the coordinate transformation. All of this information is necessary for computing derivatives in mapped coordinates and for computing fluxes between neighboring elements.
103 changes: 103 additions & 0 deletions docs/MeshGeneration/StructuredMesh.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
# Structured Mesh Generation in SELF


Although SELF uses unstructured mesh data structures, we have provided methods to create structured meshes and store them as an unstructured mesh. This can be quite useful as you are getting started with SELF or if the geometry for your problem can be defined using a structured mesh layout.


## One Dimension (1-D)
In one dimension, the only mesh we use is a structured mesh. To generate a structured mesh in one dimension, use the `StructuredMesh` generic in the [`Mesh1D`](../ford/type/mesh1d.html) class.

At the moment, only uniformly space structured meshes of elements can be generated. This means that all of the elements are of the same width; keep in mind that within each element, there is a quadrature grid. The points in the quadrature grid are spaced so that spectral accuracy is guaranteed.

To generate a structured grid in 1-D, you need to provide the number of elements and the left and right endpoints of the mesh.

In the example below, we create a 1-D mesh with 20 elements on the domain $x ∈ [0,1]$. The geometry fields are created from the mesh information and a $7^{th}$ degree interpolant through the Legendre-Gauss points.


```fortran
type(Mesh1D),target :: mesh
type(Lagrange),target :: interp
type(Geometry1D),target :: geometry
call mesh % StructuredMesh(nElem=20, &
x=(/0.0_prec,1.0_prec/))
call interp % Init(N=7, controlNodeType=GAUSS, &
M=10, targetNodeType=UNIFORM)
call geometry % Init(interp,mesh%nElem)
call geometry % GenerateFromMesh(mesh)
```

Notice that initializing the geometry requires an interpolant and the number of elements as input.

!!! note
Under the hood, the interpolant for the geometry (`geometry % interp` ) is associated with a pointer to `interp`, ie `geometry % interp => interp`.

Once the geometry is initialized, the physical positions and metric terms can be calculated and stored using the `GenerateFromMesh` method.

## Two Dimensions (2-D)
To generate a structured mesh in two dimensions, use the `StructuredMesh` generic in the [`Mesh2D`](../ford/type/mesh2d.html) class.

At the moment, only uniformly space structured meshes of elements can be generated. This means that all of the elements are of the same width; keep in mind that within each element, there is a quadrature grid. The points in the quadrature grid are spaced so that spectral accuracy is guaranteed.

SELF uses a tiled structured grid. Tiled grids divide the 2-D grid into `nTilex`x`nTiley` tiles of size `nxPerTile`x`nyPerTile` . The width and height of the elements are defined as `dx` and `dy`. With these parameters,

* `nx = nTilex*nxPerTile` is the total number of elements in the x-direction
* `ny = nTiley*nyPerTile` is the total number of elements in the y-direction
* `nelem = nx*ny` is the total number of elements
* `Lx = dx*nx` is the domain length in the x-direction
* `Ly = dy*ny` is the domain length in the y-direction

You can set boundary conditions for each of the four sides of the structured mesh using a 1-D array of integers of length 4. The boundary conditions must be provided in counter-clockwise order, starting with the "south" boundary (south, east, north, west). The following built-in flags are available for setting boundary conditions

* `SELF_BC_NONORMALFLOW`
* `SELF_BC_PRESCRIBED`
* `SELF_BC_RADIATION`

The tiled layout is convenient for domain decomposition, when you are wanting to scale up your application for distributed memory platforms. You can further enable domain decomposition by setting the optional `enableDomainDecompisition` input to `.true.` . In this case, when you launch your application with `mpirun`, the domain will be automatically divided as evenly as possible across all MPI ranks.

!!! note
It's good practice to set the total number of tiles equal to the number of MPI ranks that you are running with. Alternatively, you can use fairly small tiles when working with a large number of MPI ranks to increase the chance of minimizing point-to-point communications .

In the example below, we create a 2-D mesh with the following attributes

* $2 × 2$ tiles for the domain
* $10 × 10$ elements per tile
* Each element is has dimensions of $0.05 × 0.05$. The domain dimensions are then $L_x × L_y = 1 × 1$
* Domain decomposition is enabled

The geometry fields are created from the mesh information and a $7^{th}$ degree interpolant through the Legendre-Gauss points.


```fortran
type(Mesh2D),target :: mesh
type(Lagrange),target :: interp
type(SEMQuad),target :: geometry
integer :: bcids(1:4)
bcids(1:4) = [SELF_BC_PRESCRIBED,& ! south boundary
SELF_BC_PRESCRIBED,& ! east boundary
SELF_BC_PRESCRIBED,& ! north boundary
SELF_BC_PRESCRIBED] ! west boundary
call mesh % StructuredMesh( nxPerTile=10, nyPerTile=10,&
nTileX=2, nTileY=2,&
dx=0.05_prec, dy=0.05_prec, &
bcids)
call interp % Init(N=7, controlNodeType=GAUSS, &
M=10, targetNodeType=UNIFORM)
call geometry % Init(interp,mesh%nElem)
call geometry % GenerateFromMesh(mesh)
```

Notice that initializing the geometry requires an interpolant and the number of elements as input.

!!! note
Under the hood, the interpolant for the geometry (`geometry % interp` ) is associated with a pointer to `interp`, ie `geometry % interp => interp`.

Once the geometry is initialized, the physical positions and metric terms can be calculated and stored using the `GenerateFromMesh` method.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
74 changes: 0 additions & 74 deletions docs/Models/CompressibleNavierStokes.md

This file was deleted.

Loading

0 comments on commit 091f424

Please sign in to comment.