Developer Guide

This guide covers the repository structure, development workflow, testing, and contribution guidelines for GeoDynamo.jl.


Repository Layout

GeoDynamo.jl/
├── src/
│   ├── GeoDynamo.jl              # Module entry point & exports
│   │
│   │   # ─────────────────────────────────────────────────────────
│   │   # CORE INFRASTRUCTURE
│   │   # ─────────────────────────────────────────────────────────
│   ├── fields.jl                 # PencilArray-backed field types
│   ├── parameters.jl             # GeoDynamoParameters definition
│   ├── pencil_decomps.jl         # PencilArrays decomposition setup
│   ├── linear_algebra.jl         # Banded matrix operations
│   │
│   │   # ─────────────────────────────────────────────────────────
│   │   # SHTnsKit INTEGRATION
│   │   # ─────────────────────────────────────────────────────────
│   ├── shtnskit_transforms.jl    # SHTnsKit config, FFT plans, transposes
│   ├── shtnskit_field_functions.jl # Transforms, spectra, rotations
│   │
│   │   # ─────────────────────────────────────────────────────────
│   │   # PHYSICS KERNELS
│   │   # ─────────────────────────────────────────────────────────
│   ├── velocity.jl               # Velocity field evolution
│   ├── magnetic.jl               # Magnetic field induction/diffusion
│   ├── thermal.jl                # Temperature advection-diffusion
│   ├── compositional.jl          # Composition advection-diffusion
│   ├── scalar_field_common.jl    # Shared scalar field operations
│   │
│   │   # ─────────────────────────────────────────────────────────
│   │   # TIME INTEGRATION & SIMULATION
│   │   # ─────────────────────────────────────────────────────────
│   ├── timestep.jl               # CNAB2/EAB2/ERK2 integrators
│   ├── simulation.jl             # High-level driver
│   ├── InitialConditions.jl      # Initial condition setup
│   │
│   │   # ─────────────────────────────────────────────────────────
│   │   # I/O & UTILITIES
│   │   # ─────────────────────────────────────────────────────────
│   ├── outputs_writer.jl         # NetCDF writer with MPI support
│   ├── combiner.jl               # Distributed output combiner
│   ├── optimizations.jl          # Performance utilities
│   ├── gpu_backend.jl            # GPU acceleration (experimental)
│   │
│   │   # ─────────────────────────────────────────────────────────
│   │   # BOUNDARY CONDITIONS
│   │   # ─────────────────────────────────────────────────────────
│   ├── bcs/
│   │   ├── bcs.jl               # Main BC module
│   │   ├── common.jl             # Shared BC utilities
│   │   ├── thermal.jl            # Thermal BCs
│   │   ├── velocity.jl           # Velocity BCs
│   │   ├── magnetic.jl           # Magnetic BCs
│   │   ├── composition.jl        # Composition BCs
│   │   ├── interpolation.jl      # BC interpolation
│   │   ├── integration.jl        # BC time integration
│   │   ├── timestepping.jl       # BC timestepping
│   │   ├── netcdf_io.jl          # BC NetCDF I/O
│   │   └── programmatic.jl       # Programmatic BC definitions
│   │
│   │   # ─────────────────────────────────────────────────────────
│   │   # GEOMETRY MODULES
│   │   # ─────────────────────────────────────────────────────────
│   ├── Shell/                    # Spherical shell geometry
│   │   └── Shell.jl
│   └── Ball/                     # Solid ball geometry
│       └── Ball.jl
│
├── docs/                         # Documenter.jl configuration
├── extras/                       # CLI utilities
├── scripts/                      # Analysis scripts
├── test/                         # Test suite
└── config/                       # Sample parameter files

Setting Up a Dev Environment

Clone and Initialize

git clone https://github.com/subhk/GeoDynamo.jl
cd GeoDynamo.jl

If developing against a local SHTnsKit checkout:

julia --project -e '
    using Pkg
    Pkg.develop(PackageSpec(path="../SHTnsKit.jl"))
    Pkg.instantiate()
'

Install Dependencies

julia --project -e 'using Pkg; Pkg.instantiate()'

MPI Development

When working on MPI-dependent features, launch Julia with mpiexec:

mpiexec -n 4 julia --project
Note

Inside the REPL, activate the project with using Pkg; Pkg.activate(".") and load utilities as needed.


Testing

Running Tests

CommandDescription
julia --project -e 'using Pkg; Pkg.test()'Full test suite
julia --project test/shtnskit_roundtrip.jlSingle test file
julia --project test/ball_finiteness.jlSpecific test

CI Matrix

The CI runs on multiple platforms via .github/workflows/ci.yml:

PlatformJulia VersionsMPINotes
Linux (Ubuntu)1.10, 1.11MPICHlibnetcdf-dev
macOS1.11Open MPIHomebrew packages
Windows1.11Microsoft MPIChocolatey

The workflow:

  1. Caches Julia artifacts
  2. Instantiates the project
  3. Executes Pkg.test()
Keep CI Green

After adding new features, ensure existing tests pass or extend the suite to cover new functionality. GitHub Actions must remain green before merging.


Building Documentation

Documentation is built with Documenter.jl.

Local Build

# Install doc dependencies
julia --project=docs -e 'using Pkg; Pkg.instantiate()'

# Build documentation
julia --project=docs docs/make.jl

# Preview (open in browser)
open docs/build/index.html

CI Deployment

The CI workflow automatically publishes to gh-pages on each push to main.


Coding Guidelines

Performance

GuidelineReason
Prefer mutating functionsUpdate preallocated buffers; garbage hurts scaling
Use @inbounds sparinglyOnly after profiling confirms safety
Cache LU factorizationsReuse across timesteps

MPI Safety

GuidelineReason
Test single-rank behaviorEnsure code works without implicit reductions
Use global loop boundsPrevent deadlocks with collectives
All I/O is collectiveAll ranks must call NCDataset(...) together for parallel I/O

Documentation

GuidelineDetails
Add high-level docstringsDocumenter will surface them in API reference
Export new functionalityAdd to GeoDynamo.jl exports
Update the docsAdd entries to relevant .md files

SHTnsKit Integration

The spherical harmonic transform layer spans two files:

FilePurpose
shtnskit_transforms.jlConfiguration, pencil decomposition, FFT plans
shtnskit_field_functions.jlTransform operations, energy spectra, rotations

Adding New Transform Functions

  1. Implement the function in shtnskit_field_functions.jl

  2. Use try/catch for version compatibility:

function my_new_function(config, alm)
    try
        return SHTnsKit.new_feature(config.sht_config, alm)
    catch e
        # Fallback implementation
        @debug "new_feature not available: $e"
        return manual_implementation(config, alm)
    end
end
  1. Export in GeoDynamo.jl

  2. Document in docs/src/shtnskit.md

Feature Detection

Use get_shtnskit_version_info() to check capabilities:

info = get_shtnskit_version_info()
if info.has_qst_transforms
    # Use native QST
else
    # Use fallback
end

Performance Tips

TipFunction
Use in-place transformsshtnskit_synthesis_inplace! / shtnskit_analysis_inplace!
Cache BC configs_get_cached_bc_shtns_config()
Enable scratch buffersSHTNSKIT_USE_SCRATCH_BUFFERS = true
Profile performanceget_shtnskit_performance_stats()

Boundary Conditions

Boundary definitions live under src/bcs/.

Adding a New Boundary Type

  1. Extend the relevant bcs.* module to parse your data source

  2. Update outputs_writer.jl if fields should be recorded in NetCDF

  3. Document the format in Data Output & Restart Files

Module Structure

ModulePurpose
bcs.jlMain module, config caching
common.jlShared utilities and types
thermal.jlThermal boundary handling
velocity.jlVelocity boundary handling
magnetic.jlMagnetic boundary handling
composition.jlComposition boundary handling
interpolation.jlSpatial/temporal interpolation
netcdf_io.jlNetCDF read/write
programmatic.jlCode-defined boundaries

Contributing

Workflow

  1. Fork the repository and create a feature branch

  2. Implement your changes with tests

  3. Run the test suite and build docs locally:

    julia --project -e 'using Pkg; Pkg.test()'
    julia --project=docs docs/make.jl
  4. Open a pull request describing:

    • Motivation for the change
    • Implementation approach
    • Validation performed

Bug Reports

When filing issues, include:

InformationPurpose
MPI configurationNumber of ranks, MPI implementation
SHTnsKit versionget_shtnskit_version_info() output
Parameter filesReproduce the problem
Error messagesFull stack traces
Minimal exampleIsolate the issue

Feature Requests

Feature requests are welcome! Please describe:

  • The use case
  • Expected behavior
  • Any proposed implementation approach

Next Steps

GoalResource
Understand the I/O systemData Output & Restart Files
Learn about time integrationTime Integration
Explore configuration optionsConfiguration & Parameters
Browse the APIAPI Reference