CurvilinearGrids.jl

CurvilinearGrids.jl: A Julia package for curvilinear coordinate transformations - Published in JOSS (2024)

https://github.com/smillerc/curvilineargrids.jl

Science Score: 100.0%

This score indicates how likely this project is to be science-related based on various indicators:

  • CITATION.cff file
    Found CITATION.cff file
  • codemeta.json file
    Found codemeta.json file
  • .zenodo.json file
    Found .zenodo.json file
  • DOI references
    Found 13 DOI reference(s) in README and JOSS metadata
  • Academic publication links
    Links to: springer.com, joss.theoj.org, zenodo.org
  • Committers with academic emails
    2 of 4 committers (50.0%) from academic institutions
  • Institutional organization owner
  • JOSS paper metadata
    Published in Journal of Open Source Software

Keywords

cfd julia mesh-generation pde
Last synced: 6 months ago · JSON representation ·

Repository

A Julia library for working with curvilinear grids

Basic Info
  • Host: GitHub
  • Owner: smillerc
  • License: mit
  • Language: Julia
  • Default Branch: main
  • Homepage:
  • Size: 1.39 MB
Statistics
  • Stars: 6
  • Watchers: 2
  • Forks: 1
  • Open Issues: 2
  • Releases: 25
Topics
cfd julia mesh-generation pde
Created over 2 years ago · Last pushed 6 months ago
Metadata Files
Readme Contributing License Citation

README.md

CurvilinearGrids

Build Status License: MIT

DOI

DOI

CurvilinearGrids.jl is a Julia package that provides utilities for working with non-uniform curvilinear grids. The core function takes a grid and transforms it from $(x,y,z) \rightarrow (\xi,\eta,\zeta)$, where the transformed grid contains elements of unit length in each dimension. A common example of this is to use a body-fit mesh, e.g. a mesh around a wing, and transform it so that it becomes a uniform grid in $(\xi,\eta,\zeta)$. Then standard finite-difference stencils can be used on the uniform transformed grid. Below is an example of a cylindrical mesh in $(x,y)$ coordinates and the corresponding logical grid in $(\xi,\eta)$.

Alt text

CurvilinearGrids.jl defines CurvilinearGrid1D, CurvilinearGrid2D, and CurvilinearGrid3D types. To construct these, you need to provide the discrete coordinates for the mesh.

Installation

CurvilinearGrids is a registered Julia package, so installation follows the typical procedure: julia using Pkg; Pkg.add("CurvilinearGrids"); using CurvilinearGrids

Example Grid Construction

```julia using CurvilinearGrids

"""Create a spherical grid as a function of (r,θ,ϕ)""" function sphere_grid(nr, ntheta, nphi) r0, r1 = (1, 3) # min/max radius (θ0, θ1) = deg2rad.((35, 180 - 35)) # min/max polar angle (ϕ0, ϕ1) = deg2rad.((45, 360 - 45)) # min/max azimuthal angle

# Linear spacing in each dimension # Sometimes (ξ, η, ζ) is used instead of (i, j, k), depending on preference r(ξ) = r0 + (r1 - r0) * ((ξ - 1) / (nr - 1)) θ(η) = θ0 + (θ1 - θ0) * ((η - 1) / (ntheta - 1)) ϕ(ζ) = ϕ0 + (ϕ1 - ϕ0) * ((ζ - 1) / (nphi - 1))

x = zeros(nr, ntheta, nphi) y = zeros(nr, ntheta, nphi) z = zeros(nr, ntheta, nphi) # simple spherical to cartesian mapping for idx in CartesianIndices(x) i,j,k = idx.I x[idx] = r(i) * sin(θ(j)) * cos(ϕ(k)) y[idx] = r(i) * sin(θ(j)) * sin(ϕ(k)) z[idx] = r(i) * cos(θ(j)) end

return (x, y, z) end

ni, nj, nk = (5, 9, 11) # number of nodes/vertices in each dimension nhalo = 4 # halo cells needed for stencils (can be set to 0)

Obtain the x, y, and z coordinate functions

x, y, z = sphere_grid(ni, nj, nk)

Create the mesh

scheme = :meg6_symmetric # the symmetric scheme is more robust but more costly than :meg6 mesh = CurvilinearGrid3D(x, y, z, scheme) ```

Exported Functions

The API is still a work-in-progress, but for the moment, these functions are exported:

Here idx can be a Tuple or CartesianIndex, and mesh is an AbstractCurvilinearGrid. Important: The indices provided to these functions are aware of halo regions, so the functions do the offsets for you. Halo cells, or halo regions, are an additional layer of cells around the boundary of the mesh that do not contain geometric information. Halo cells are used to apply boundary conditions in a simple manner and to exchange data between domains (in a domain-decomposed setting, e.g. using MPI). This is by design, since fields attached to the mesh, like density or pressure for example, will have halo regions, and loops through these fields typically have pre-defined limits that constrain the loop to only work in the non-halo cells. If you don't use halo cells, just set nhalo=0 in the constructors.

The index can be a Tuple, scalar Integer, or CartesianIndex. - coord(mesh, idx): Get the $(x,y,z)$ coordinates at index idx. This can be 1, 2, or 3D. - centroid(mesh, idx): Get the $(x,y,z)$ coordinates of the cell centroid at cell index idx. This can be 1, 2, or 3D.

These functions are primarily used to get the complete set of coordinates for plotting or post-processing. These do not use halo regions, since there geometry is ill-defined here. - coords(mesh) Get the: array of coordinates for the entire mesh (typically for writing to a .vtk for example) - centroids(mesh) Get the: array of centroid coordinates for the entire mesh (typically for writing to a .vtk file)

Constructors

General purpuse constructors for 1D/2D/3D grids. These need a vector/matrix/array of vertex coordinates and the number of halo cells to pad by. - CurvilinearGrid1D(x::AbstractVector{T}, scheme::Symbol) - CurvilinearGrid2D(x::AbstractMatrix{T}, y::AbstractMatrix{T}, scheme::Symbol) - CurvilinearGrid3D(x::AbstractArray{T,3}, y::AbstractArray{T,3}, z::AbstractArray{T,3}, scheme::Symbol)

The scheme is currently limited to the following: - :meg6 : See Chandravamsi et. al (https://doi.org/10.1016/j.compfluid.2023.105859) - :meg6_symmetric : For the meg6 scheme with grid metrics computed via a symemtric scheme - See Nonmura et. al (https://doi.org/10.1016/j.compfluid.2014.09.025)

A few convienence constructors have been added to make it simpler to generate certain types of grids. Use the ? in the REPL to see the useage.

  • rectilinear_grid: A rectilinear grid in 1D/2D/3D
  • rectilinear_cylindrical_grid: A rectilinear grid with cylindrical symmetry
  • rectilinear_spherical_grid: A rectilinear grid with spherical symmetry
  • axisymmetric_rectilinear_grid: A rectilinear grid with axisymmetry about a given axis

  • rtheta_grid: Provide (r,θ) coordinates to generate a polar mesh

  • axisymmetric_rtheta_grid: Provide (r,θ) coordinates to generate a polar mesh with axisymmetry

  • rthetaphi_grid: : Provide (r,θ,ϕ) coordinates to generate a polar mesh

Grid Metrics

Grid metrics are required for curvilinear grids. These are stored as members of the CurvilinearGrid types. There are three primary grid metric types: 1. forward metrics $(x\xi, y\xi, ...)$, 2. inverse metrics $(\xix, \etay, ...)$, and 3. normalized inverse metrics $(\hat{\xi}x, \hat{\eta}y, ...)$. The subscript denotes a partial derivative, so $\xix = \partial \xi / \partial x$. The inverse and normalized inverse metrics are computing using conservative schemes that satisfy the Geometric Conservation Law (Thomas & Lombard 1979). Metrics are interpolated from cell-center to edge interfaces using the same discretization scheme that computed the derivatives (this is essential for adherance to the GCL). The metrics are StructArrays that include the Jacobian J, metrics $\xii, \etai, \zetai$ for $i={x1}, _{x2}, _{x3}$. For a 3D mesh, for example: ```julia julia> keys(pairs(mesh.edgemetrics)) (:i₊½, :j₊½, :k₊½)

julia> keys(pairs(mesh.edge_metrics.i₊½)) (:ξ̂, :η̂, :ζ̂, :ξ, :η, :ζ)

julia> keys(pairs(mesh.cellcentermetrics)) (:J, :ξ, :η, :ζ, :ξ̂, :η̂, :ζ̂, :x₁, :x₂, :x₃) ```

Jacobian matrices of transformation

Terminology can be somewhat confusing, but the "Jacobian matrix" is the matrix of partial derivatives that describe the forward or inverse transformation, and uses a bold-face $\textbf{J}$. The "Jacobian" then refers to the determinant of the Jacobian matrix, and is the non-bolded $J$. Some authors refer to the matrix as the "Jacobi matrix" as well. See Wikipedia for more details.

Forward transformation, or $T: (\xi,\eta,\zeta) \rightarrow (x,y,z)$. These functions are what is provided to the CurvilinearGrid constructors. See the included examples above and in the unit tests.

$$ \textbf{J} = \begin{bmatrix} x\xi & x\eta & x\zeta \ y\xi & y\eta & y\zeta \ z\xi & z\eta & z_\zeta \end{bmatrix} $$

$$ J = \det [\textbf{J}] $$

Inverse transformation $T^{-1}$: $(x,y,z) \rightarrow (\xi,\eta,\zeta)$ :

$$ \textbf{J}^{-1} = \begin{bmatrix} \xix & \xiy & \xiz \ \etax & \etay & \etaz \ \zetax & \zetay & \zeta_z \end{bmatrix} $$

$$ J^{-1} = \det [\textbf{J}^{-1}] $$

These matrices can be accessed by calling J = jacobian_matrix(mesh, I::CartesianIndex). The inverse can be found via inv(J). Note that the inverse metrics found this way will not be conservative and may introduce errors into your discretization. This is why the inverse metrics are stored in mesh.metrics.

Using metrics in a PDE discretization

Curvilinear transformations are often used to simulate PDEs like the heat equation or the Euler equations for fluid flow. A vastly simplified example is shown below, where the divergence of the flux ($\nabla \cdot q$) is found for a 1D rectilinear grid. A good description of metrics and PDE discretization is in Chapter 3 of Huang, W. & Russell, R. D. Adaptive Moving Mesh Methods.

```julia using CurvilinearGrids: rectilinear_grid using CartesianDomains: shift

x0, x1 = (-1.0, 1.0) ncells = 100 scheme = :meg6_symmetric

rectilinear_grid() is a CurvilinearGrid1D constructor for uniform geometry

mesh = rectilineargrid(x0, x1, scheme) ξx = mesh.cellcenter_metrics.ξ.x₁

const iaxis = 1

u = rand(size(mesh.iterators.cell.full)...) # solution qᵢ₊½ = zeros(size(mesh.iterators.cell.full)) # flux of u ∇dotq = zeros(size(mesh.iterators.cell.full)) # flux divergence α = ones(size(mesh.iterators.cell.full)) # diffusivity

Find the fluxes across the edges

for i in mesh.iterators.cell.domain # only loop through the inner domain (ignore halo region) ᵢ₊₁ = shift(i, iaxis, +1) # shift is useful for indexing in arbitrary dimensions

αᵢ₊½ = (α[i] + α[ᵢ₊₁]) / 2 # face averaged conductivity qᵢ₊½[i] = -αᵢ₊½ * (u[ᵢ₊₁] - u[i]) # flux of u across the interface at ᵢ₊½ end

Now find the flux divergence

for i in mesh.iterators.cell.domain ᵢ₋₁ = shift(i, iaxis, -1)

# note the use of the mesh metric, # which for this case is just the cell spacing ∇dotq[i] = ξx[i]^2 * (qᵢ₊½[i] - qᵢ₊½[ᵢ₋₁]) end ```

Owner

  • Name: Sam Miller
  • Login: smillerc
  • Kind: user
  • Location: Rochester, NY
  • Company: Laboratory for Laser Energetics, University of Rochester

Computational Physicist - Studying fluid instabilities in direct-drive inertial confinement fusion implosions

JOSS Publication

CurvilinearGrids.jl: A Julia package for curvilinear coordinate transformations
Published
December 17, 2024
Volume 9, Issue 104, Page 7508
Authors
Samuel C. Miller ORCID
Laboratory for Laser Energetics, University of Rochester, Rochester, NY USA
Editor
Mehmet Hakan Satman ORCID
Tags
mesh grids curvilinear

Citation (CITATION.cff)

cff-version: "1.2.0"
authors:
- family-names: Miller
  given-names: Samuel C.
  orcid: "https://orcid.org/0000-0001-6452-2308"
doi: 10.5281/zenodo.14510381
message: If you use this software, please cite our article in the
  Journal of Open Source Software.
preferred-citation:
  authors:
  - family-names: Miller
    given-names: Samuel C.
    orcid: "https://orcid.org/0000-0001-6452-2308"
  date-published: 2024-12-17
  doi: 10.21105/joss.07508
  issn: 2475-9066
  issue: 104
  journal: Journal of Open Source Software
  publisher:
    name: Open Journals
  start: 7508
  title: "CurvilinearGrids.jl: A Julia package for curvilinear
    coordinate transformations"
  type: article
  url: "https://joss.theoj.org/papers/10.21105/joss.07508"
  volume: 9
title: "CurvilinearGrids.jl: A Julia package for curvilinear coordinate
  transformations"

GitHub Events

Total
  • Fork event: 2
  • Create event: 21
  • Commit comment event: 26
  • Issues event: 6
  • Release event: 10
  • Watch event: 5
  • Delete event: 8
  • Member event: 1
  • Issue comment event: 15
  • Push event: 86
  • Pull request review event: 1
  • Pull request review comment event: 1
  • Pull request event: 20
Last Year
  • Fork event: 2
  • Create event: 21
  • Commit comment event: 26
  • Issues event: 6
  • Release event: 10
  • Watch event: 5
  • Delete event: 8
  • Member event: 1
  • Issue comment event: 15
  • Push event: 86
  • Pull request review event: 1
  • Pull request review comment event: 1
  • Pull request event: 20

Committers

Last synced: 7 months ago

All Time
  • Total Commits: 324
  • Total Committers: 4
  • Avg Commits per committer: 81.0
  • Development Distribution Score (DDS): 0.179
Past Year
  • Commits: 153
  • Committers: 4
  • Avg Commits per committer: 38.25
  • Development Distribution Score (DDS): 0.268
Top Committers
Name Email Commits
Miller, Samuel s****l@l****u 266
Aiden Rohrbach a****j@p****m 38
CompatHelper Julia c****y@j****g 19
Jenny Gorman-Maher j****m@u****u 1
Committer Domains (Top 20 + Academic)

Issues and Pull Requests

Last synced: 6 months ago

All Time
  • Total issues: 2
  • Total pull requests: 30
  • Average time to close issues: 10 days
  • Average time to close pull requests: 3 days
  • Total issue authors: 2
  • Total pull request authors: 5
  • Average comments per issue: 13.5
  • Average comments per pull request: 0.07
  • Merged pull requests: 26
  • Bot issues: 0
  • Bot pull requests: 19
Past Year
  • Issues: 1
  • Pull requests: 11
  • Average time to close issues: 19 days
  • Average time to close pull requests: 10 days
  • Issue authors: 1
  • Pull request authors: 5
  • Average comments per issue: 8.0
  • Average comments per pull request: 0.18
  • Merged pull requests: 7
  • Bot issues: 0
  • Bot pull requests: 4
Top Authors
Issue Authors
  • ajrohr2 (1)
  • DanielVandH (1)
  • jgormanm (1)
  • smillerc (1)
  • JuliaTagBot (1)
Pull Request Authors
  • github-actions[bot] (33)
  • ajrohr2 (9)
  • smillerc (9)
  • jbytecode (2)
  • danielskatz (2)
Top Labels
Issue Labels
Pull Request Labels

Packages

  • Total packages: 1
  • Total downloads:
    • julia 14 total
  • Total dependent packages: 0
  • Total dependent repositories: 0
  • Total versions: 25
juliahub.com: CurvilinearGrids

A Julia library for working with curvilinear grids

  • Versions: 25
  • Dependent Packages: 0
  • Dependent Repositories: 0
  • Downloads: 14 Total
Rankings
Dependent repos count: 10.1%
Dependent packages count: 40.5%
Average: 44.4%
Forks count: 53.1%
Stargazers count: 73.9%
Last synced: 6 months ago

Dependencies

.github/workflows/CI.yml actions
  • actions/checkout v3 composite
  • julia-actions/cache v1 composite
  • julia-actions/julia-buildpkg v1 composite
  • julia-actions/julia-runtest v1 composite
  • julia-actions/setup-julia v1 composite
.github/workflows/TagBot.yml actions
  • JuliaRegistries/TagBot v1 composite
.github/workflows/CompatHelper.yml actions
  • julia-actions/setup-julia v1 composite