Skip to content

MOLE.jl 2.0 Grid API Roadmap #389

Description

@valeriabarra

Overview

As outlined in #378 , there is a plan for defining a new grid API object. This development is part of a road map towards MOLE 2.0. Here we outline the road map for the MOLE.jl Julia implementation to match the desired behavior.

Please anyone review and comment to let us know that this is indeed the desired behavior.
cc: @jbrzensk , @Tony-Drummond , @cpaolini

Goal

Introduce a new Grids module that serves as the central data layer for MOLE 2.0 while preserving compatibility with the existing operator implementations.

The new API should allow users to create a grid once and pass that grid object to operators. Example:

grid = makeGrid(m=64, n=64, dx=1/64, dy=1/64)

G = grad(k, grid)
D = div(k, grid)
L = lap(k, grid)

instead of the current:

G = grad(k, m, dx, n, dy)
D = div(k, m, dx, n, dy)
L = lap(k, m, dx, n, dy)

Phase 1: Create the Grids Module

Directory Structure

MOLE.jl
├── src/
      ├── Grids/
      │   ├── Grids.jl
      │   ├── topologies.jl
      │   ├── make_grid.jl
      │   ├── validate_grid.jl
      │   └── coordinates.jl
      ├── Operators/
      │   ├── Operators.jl
      │   ├── gradient.jl
      │   ├── divergence.jl
      │   ├── laplacian.jl
      │   └── interpol.jl
      └── BCs/
          ├── BCs.jl
          ├── scalarBC.jl
          └── robinBC.jl

Update Package Entry Point

module MOLE

include("Grids/Grids.jl")
include("Operators/Operators.jl")
include("BCs/BCs.jl")

end

Phase 2: Define Grid Types

Grids Data Structure

Create a typed grid object that stores:

  • dimensionality
  • topology
  • spacing information
  • coordinate arrays
  • boundary metadata

Example:

abstract type AbstractGrid end

struct BoundaryMetadata
    isPeriodic::Vector{Bool}
    dc::Vector{Float64}
    nc::Vector{Float64}
end

struct Grid{T} <: AbstractGrid
    dim::Int
    topology::Symbol

    m::Int
    n::Union{Nothing,Int}
    o::Union{Nothing,Int}

    dx::Union{Nothing,T}
    dy::Union{Nothing,T}
    dz::Union{Nothing,T}

    nodes::NamedTuple
    faces::NamedTuple
    centers::NamedTuple

    bc::BoundaryMetadata
end

Phase 3: Implement makeGrid

User-Facing Constructor

Users should only create grids through:

grid = makeGrid(...)

Examples:

grid = makeGrid(m=100, dx=0.01)

grid = makeGrid(
    m=64,
    n=64,
    dx=1/64,
    dy=1/64
)

Responsibilities:

  1. Collect user inputs.
  2. Normalize keyword arguments.
  3. Call validateGrid.
  4. Return a fully populated grid object.

Phase 4: Implement validateGrid

Validation Responsibilities

Infer and validate the following:

Dimensions

Determine:

dim = 1
dim = 2
dim = 3

from:

m
n
o

and/or

dx
dy
dz

Topology

Determine:

:uniform
:periodic
:curvilinear

based on:

  • coordinate arrays
  • periodic boundary flags

Boundary Metadata

Verify:

bc.isPeriodic
bc.dc
bc.nc

Coordinate Arrays

Generate:

nodes
faces
centers

for supported grid types.


Phase 5: Coordinate Generation

Uniform Cartesian Grids

Generate:

Nodes

grid.nodes

Cell Centers

grid.centers

Face Coordinates

grid.faces

Support:

  • 1D
  • 2D

before extending to 3D.


Phase 6: Add Grid-Based Operator Interfaces

New APIs

Add overloads:

grad(k, grid)

div(k, grid)

lap(k, grid)

interpol(k, grid)

Wrapper Strategy

The new methods should call the existing implementations internally.

Example:

function grad(k, grid::Grid)

    if grid.dim == 1
        return grad(
            k,
            grid.m,
            grid.dx;
            dc=grid.bc.dc,
            nc=grid.bc.nc
        )

    elseif grid.dim == 2
        return grad(
            k,
            grid.m,
            grid.dx,
            grid.n,
            grid.dy;
            dc=grid.bc.dc,
            nc=grid.bc.nc
        )
    end
end

Preserve Backward Compatibility

Existing APIs remain unchanged for the migration phase:

grad(k, m, dx)

grad(k, m, dx, n, dy)

Phase 7: Integrate Boundary Conditions

Boundary Metadata Object

Store boundary information directly inside the grid.

More details needed.

Phase 8: Testing

Regression Tests

Verify numerical equivalence between:

Existing API

G1 = grad(k, m, dx)

New API

grid = makeGrid(m=m, dx=dx)

G2 = grad(k, grid)

Tests:

@test G1  G2

Repeat for:

  • grad
  • div
  • lap
  • interpol

Phase 9: Documentation

Migration Guide

Create:

docs/src/migration/grid_api.md

Include:

Old Syntax

G = grad(k, m, dx)

New Syntax

grid = makeGrid(m=m, dx=dx)

G = grad(k, grid)

Benefits

  • simpler user code
  • centralized metadata
  • future support for curvilinear grids
  • easier extension to 3D

Phase 10: Curvilinear Grid Support

After the uniform-grid API is stable:

Add Curvilinear Topology

Support:

topology = :curvilinear

using user-supplied coordinates:

grid = makeGrid(
    X=X,
    Y=Y
)

Curvilinear Coordinate Storage

Store:

grid.nodes.X
grid.nodes.Y

grid.centers.X
grid.centers.Y

grid.faces

using Julia's native array ordering.

Curvilinear Operators

Add specialized implementations for:

grad

div

lap

nodal

that consume the geometric information contained in the grid object.


Recommended Development Order

  1. Create julia/MOLE.jl/Grids/
  2. Define Grid and BoundaryMetadata
  3. Implement makeGrid
  4. Implement validateGrid
  5. Generate 1D uniform coordinates
  6. Generate 2D uniform coordinates
  7. Add grad(k, grid)
  8. Add div(k, grid)
  9. Add lap(k, grid)
  10. Add interpol(k, grid)
  11. Integrate boundary metadata
  12. Add documentation and migration guide
  13. Add curvilinear grid support
  14. Extend to 3D

Metadata

Metadata

Assignees

No one assigned

    Labels

    MOLE-2.0Ideas and issues relating to the MOLE 2.0 development branch and or update.MOLE.jl

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions