API Reference
The table below lists the main entry points exported by GeoDynamo. The listing is automatically generated during the documentation build.
Main Module
GeoDynamo.AbstractScalarField — Type
Abstract type for scalar fields (temperature, composition, etc.)
GeoDynamo.AdvancedThreadManager — Type
AdvancedThreadManagerAdvanced thread management with CPU affinity, NUMA awareness, and work-stealing.
GeoDynamo.AsyncCommManager — Type
AsyncCommManager{T}Advanced asynchronous communication manager for overlapping computation and communication.
GeoDynamo.CPUParallelizer — Type
CPUParallelizer{T}Advanced CPU parallelization system with SIMD, NUMA, and task-based parallelism.
GeoDynamo.CombinerConfig — Type
CombinerConfigConfiguration structure for field combination process.
GeoDynamo.DynamicLoadBalancer — Type
DynamicLoadBalancerDynamic load balancing system that adapts to computational heterogeneity.
GeoDynamo.EAB2ALUCacheEntry — Type
EAB2ALUCacheEntry{T}Type-stable cache entry for EAB2 (Exponential Adams-Bashforth 2) method. Stores banded matrices and their LU factorizations for each spherical harmonic degree l.
GeoDynamo.ERK2Cache — Type
ERK2Cache{T}Cached data structure for Exponential 2nd Order Runge-Kutta method. Stores precomputed matrix exponentials and φ functions for each spherical harmonic mode.
GeoDynamo.EnergyTracker — Type
EnergyTrackerStructure for tracking energy conservation during simulation.
GeoDynamo.FieldCombiner — Type
FieldCombiner{T}Structure for combining distributed GeoDynamo.jl output files using the consistent field structures and parameter system.
GeoDynamo.HybridParallelizer — Type
HybridParallelizer{T}Coordinates MPI and threads for maximum CPU parallelization.
GeoDynamo.MasterParallelizer — Type
MasterParallelizer{T}Comprehensive parallelization system combining all techniques.
GeoDynamo.MemoryOptimizer — Type
MemoryOptimizer{T}Advanced memory management with cache optimization and NUMA awareness.
GeoDynamo.NaNDetectionConfig — Type
NaNDetectionConfigConfiguration for NaN/Inf detection during simulation.
GeoDynamo.ParallelIOOptimizer — Type
ParallelIOOptimizer{T}Advanced parallel I/O optimization with asynchronous writes and data staging.
GeoDynamo.PerformanceMonitor — Type
PerformanceMonitorComprehensive performance monitoring for parallel efficiency analysis.
GeoDynamo.Phi2ConditioningMonitor — Type
Phi2ConditioningMonitorGlobal structure for monitoring φ₂ function conditioning during ERK2 integration. Tracks worst conditioning, series expansion usage, and numerical issues.
GeoDynamo.RadialDomain — Type
RadialDomainSpecification of the radial discretization for the spherical shell.
Radial Grid
The simulation domain is a spherical shell between inner radius ri (e.g., inner core boundary) and outer radius ro (e.g., core-mantle boundary). The radial direction is discretized using Chebyshev collocation for spectral accuracy.
Fields
N: Number of radial pointslocal_range: Indices of radial points local to this MPI processr: Radial coordinate values [1, N]dr_matrices: Radial derivative matrices (1st, 2nd order, etc.)radial_laplacian: Matrix for radial part of Laplacianintegration_weights: Quadrature weights for radial integration
GeoDynamo.SHTnsKitConfig — Type
SHTnsKitConfig <: AbstractSHTnsConfigMain configuration structure for spherical harmonic transforms using SHTnsKit. This struct encapsulates all parameters needed for transforms and parallelization.
Fields
Core SHTnsKit Configuration
sht_config: The underlying SHTnsKit.SHTConfig object
Grid Parameters
nlat::Int: Number of latitude (theta) points (Gauss-Legendre grid)nlon::Int: Number of longitude (phi) points (uniform grid)lmax::Int: Maximum spherical harmonic degreemmax::Int: Maximum spherical harmonic order (≤ lmax)nlm::Int: Total number of (l,m) spectral mode pairs
Parallelization Infrastructure
pencils::NamedTuple: Collection of PencilArrays Pencil objects for different data orientations (:theta, :phi, :r, :spec, :mixed)fft_plans::Dict{Symbol,Any}: Precomputed FFTW plans for FFT operationstranspose_plans::Dict{Symbol,Any}: Plans for data redistribution between pencils
Auxiliary Data
memory_estimate::String: Human-readable memory usage estimatel_values::Vector{Int}: Spherical harmonic degree for each spectral indexm_values::Vector{Int}: Spherical harmonic order for each spectral indextheta_grid::Vector{Float64}: Latitude values (Gauss-Legendre nodes)phi_grid::Vector{Float64}: Longitude values (uniform spacing)gauss_weights::Vector{Float64}: Gauss-Legendre quadrature weights
Internal
_buffer_cache::Dict{Symbol,Any}: Reusable work arrays to reduce allocations
Usage
config = create_shtnskit_config(lmax=32, mmax=32, nlat=64, nlon=128)GeoDynamo.SHTnsPhysicalField — Type
SHTnsPhysicalField{T}A scalar field represented on the physical (θ, φ, r) grid.
Storage Layout
Field values stored in a 3D array:
- Dimension 1: Latitude index (1 to nlat), Gauss-Legendre points
- Dimension 2: Longitude index (1 to nlon), uniform spacing
- Dimension 3: Radial level index
Pencil Orientation
The pencil field specifies how data is distributed across MPI processes. Different pencil orientations are optimal for different operations:
- phi pencil: Optimal for FFTs (all longitudes local)
- theta pencil: Optimal for Legendre transforms (all latitudes local)
- r pencil: Optimal for radial operations (all radii local)
GeoDynamo.SHTnsSpectralField — Type
SHTnsSpectralField{T}A scalar field represented in spectral space as spherical harmonic coefficients.
Storage Layout
Coefficients are stored as separate real and imaginary parts in 3D arrays:
- Dimension 1: Combined (l,m) spectral index (1 to nlm)
- Dimension 2: Dummy dimension (size 1) for PencilArrays compatibility
- Dimension 3: Radial level index
Boundary Conditions
Each (l,m) mode can have independent boundary conditions at the inner and outer radial boundaries. Common types:
- DIRICHLET: Specified value at boundary
- NEUMANN: Specified derivative at boundary
Fields
config: SHTnsKit configuration (grid and transform parameters)nlm: Total number of spectral modesdata_real,data_imag: Real/imaginary parts of coefficientspencil: PencilArrays pencil defining data distributionbc_type_inner/outer: Boundary condition type for each modeboundary_values: Boundary values [2, nlm] for inner/outer
GeoDynamo.SHTnsTorPolField — Type
SHTnsTorPolField{T}Vector field in toroidal-poloidal spectral representation.
The Toroidal-Poloidal Decomposition
Any solenoidal (divergence-free) vector field can be written as: v = ∇ × (T r̂) + ∇ × ∇ × (P r̂)
where T and P are scalar functions called the toroidal and poloidal potentials.
Why This Representation?
- Automatically satisfies ∇·v = 0 (mass conservation for incompressible flow)
- Decouples certain physical processes in the equations
- Reduces storage: 2 scalars instead of 3 vector components
- Natural for spherical geometry and spectral methods
Fields
toroidal: Toroidal potential T(l,m,r) in spectral spacepoloidal: Poloidal potential P(l,m,r) in spectral space
GeoDynamo.SHTnsVectorField — Type
SHTnsVectorField{T}A vector field represented by its three spherical components in physical space.
Components:
r_component: Radial component v_r(θ, φ, r)θ_component: Latitudinal component v_θ(θ, φ, r)φ_component: Longitudinal component v_φ(θ, φ, r)
Each component is a SHTnsPhysicalField, potentially with different pencil orientations for optimal computation of different operations.
GeoDynamo.SIMDOptimizer — Type
SIMDOptimizer{T}Advanced SIMD vectorization for mathematical operations with AVX/NEON support.
GeoDynamo.SimulationState — Type
SimulationState{T}Unified simulation state with comprehensive parallelization and diagnostics. Type-stable version with concrete cache types for optimal performance.
GeoDynamo.SolenoidalMonitor — Type
SolenoidalMonitorStructure for monitoring solenoidal constraint ∇·v = 0 for velocity and magnetic fields.
GeoDynamo.SpectralToPhysicalConverter — Type
SpectralToPhysicalConverter{T}Structure for converting spectral field data to physical space using the GeoDynamo.jl infrastructure (PencilArrays + SHTns).
GeoDynamo.TaskGraph — Type
TaskGraphRepresents computation as a directed acyclic graph for optimal scheduling.
GeoDynamo.TaskNode — Type
TaskNodeRepresents a computation task in a dependency graph.
GeoDynamo.ThreadingAccelerator — Type
ThreadingAccelerator{T} (Backward Compatibility)Basic CPU threading acceleration for existing code.
GeoDynamo._get_influence_cache — Method
_get_influence_cache(domain::RadialDomain, dr_matrix)Get or create cached influence functions and matrix for given domain. Note: drmatrix should be a BandedMatrix (defined in linearalgebra.jl)
GeoDynamo._get_tau_cache — Method
_get_tau_cache(domain::RadialDomain)Get or create cached tau polynomials and derivatives for given domain.
GeoDynamo._shtns_make_transpose — Method
_shtns_make_transpose(pair)Create a PencilArrays transpose plan between two pencil configurations. Used internally to set up efficient data redistribution operations.
Arguments
pair: A Pair of source and destination Pencil objects (src => dest)
Returns
- A Transposition object that can be used with
mul!for data redistribution
GeoDynamo.add_internal_sources_local! — Method
add_internal_sources_local!(field::AbstractScalarField{T}, domain::RadialDomain) where TAdd volumetric sources (completely local operation). This works for any scalar field with radial source profile.
GeoDynamo.analyze_load_balance — Method
analyze_load_balance(pencil::Pencil)Analyze and report load balance for a given pencil decomposition.
GeoDynamo.apply_banded_full! — Method
apply_banded_full!(out, B, v)Apply banded matrix to full vector.
GeoDynamo.apply_composition_boundary_conditions! — Method
apply_composition_boundary_conditions!(field; time_index=nothing)Refresh composition boundary values from the BoundaryConditions subsystem and enforce Dirichlet data in spectral space.
GeoDynamo.apply_enhanced_implicit_step! — Method
apply_enhanced_implicit_step!(state, dt)Apply enhanced implicit time integration with advanced solvers.
GeoDynamo.apply_exponential_filter! — Method
apply_exponential_filter!(config::SHTnsKitConfig, alm::Matrix{ComplexF64};
order::Int=16, cutoff::Float64=0.65,
alm_out::Union{Matrix{ComplexF64},Nothing}=nothing)Apply an exponential spectral filter for dealiasing. filter(l) = exp(-α * (l/lmax)^order) where α is chosen so filter(cutoff*lmax) = 0.5
Arguments
config: SHTnsKit configurationalm: Input spectral coefficientsorder: Filter order (higher = sharper cutoff, default 16)cutoff: Fraction of lmax where filter = 0.5 (default 0.65)alm_out: Optional output array
GeoDynamo.apply_flux_bc_direct! — Method
apply_flux_bc_direct!(spec_real, spec_imag, local_lm, lm_idx,
field::AbstractScalarField, domain, r_range)Direct modification of boundary values to approximately satisfy flux BC. This is the simplest but least accurate method.
GeoDynamo.apply_flux_bc_influence_matrix! — Method
apply_flux_bc_influence_matrix!(spec_real, spec_imag, local_lm, lm_idx,
apply_inner, apply_outer, field::AbstractScalarField,
domain, r_range)Apply flux boundary conditions using the influence matrix method.
GeoDynamo.apply_flux_bc_spectral! — Method
apply_flux_bc_spectral_complete!(temp_field, domain)Complete implementation of flux boundary conditions in spectral space. This modifies the spectral coefficients to satisfy ∂T/∂r = prescribed_flux.
GeoDynamo.apply_flux_bc_tau! — Method
apply_flux_bc_tau!(spec_real, spec_imag, local_lm, lm_idx,
apply_inner, apply_outer, field::AbstractScalarField,
domain, r_range)Apply flux boundary conditions using the tau method. This is the generalized version that works with any scalar field.
GeoDynamo.apply_geometric_factors_spectral! — Method
apply_geometric_factors_spectral!(field::AbstractScalarField{T}, domain::RadialDomain) where TApply geometric factors (1/r, 1/(r sin θ)) in spectral space. For gradients in spherical coordinates. This is generic.
GeoDynamo.apply_horizontal_laplacian! — Method
apply_horizontal_laplacian!(config::SHTnsKitConfig, alm::Matrix{ComplexF64};
alm_out::Union{Matrix{ComplexF64},Nothing}=nothing)Apply the horizontal (angular) Laplacian to spectral coefficients. ∇²h Yl^m = -l(l+1) Y_l^m
This scales each coefficient by -l(l+1), which is the eigenvalue of the horizontal Laplacian on the unit sphere.
Arguments
config: SHTnsKit configurationalm: Input spectral coefficientsalm_out: Optional output array (if nothing, modifies alm in-place)
Returns
The Laplacian-transformed coefficients
GeoDynamo.apply_inverse_horizontal_laplacian! — Method
apply_inverse_horizontal_laplacian!(config::SHTnsKitConfig, alm::Matrix{ComplexF64};
alm_out::Union{Matrix{ComplexF64},Nothing}=nothing,
regularize_l0::Bool=true)Apply the inverse horizontal Laplacian to spectral coefficients. This scales each coefficient by -1/(l(l+1)), which is useful for solving Poisson equations.
Arguments
config: SHTnsKit configurationalm: Input spectral coefficientsalm_out: Optional output arrayregularize_l0: If true, set l=0 mode to zero (since 1/0 is undefined)
Returns
The inverse-Laplacian-transformed coefficients
GeoDynamo.apply_magnetic_boundary_conditions! — Method
apply_magnetic_boundary_conditions!(fields; time_index=nothing)Refresh magnetic boundary data from the BoundaryConditions subsystem and enforce the corresponding Dirichlet values in spectral space.
GeoDynamo.apply_scalar_flux_bc_spectral! — Method
apply_scalar_flux_bc_spectral!(field::AbstractScalarField{T}, domain::RadialDomain;
method::Symbol=:tau) where TApply flux boundary conditions to a scalar field in spectral space. Methods available: :tau (most robust), :influence_matrix, :direct (simplest).
GeoDynamo.apply_spectral_filter! — Method
apply_spectral_filter!(config::SHTnsKitConfig, alm::Matrix{ComplexF64},
filter_func::Function;
alm_out::Union{Matrix{ComplexF64},Nothing}=nothing)Apply a custom spectral filter to coefficients. The filter function takes (l, m) and returns a scaling factor.
Arguments
config: SHTnsKit configurationalm: Input spectral coefficientsfilter_func: Function (l, m) -> scale_factoralm_out: Optional output array
Example
# Exponential filter for dealiasing
exp_filter(l, m) = exp(-(l/lmax)^16)
apply_spectral_filter!(config, alm, exp_filter)GeoDynamo.apply_tau_correction! — Method
apply_tau_correction!(profile::Vector{T}, tau_coeffs, domain::RadialDomain) where TAdd tau correction to the radial profile.
GeoDynamo.apply_temperature_boundary_conditions! — Method
apply_temperature_boundary_conditions!(field; time_index=nothing)Refresh cached boundary values through the BoundaryConditions subsystem and enforce Dirichlet data directly in spectral space when appropriate.
GeoDynamo.apply_velocity_boundary_conditions! — Method
apply_velocity_boundary_conditions!(fields; time_index=nothing)Refresh velocity boundary data from the BoundaryConditions subsystem and immediately enforce Dirichlet constraints in spectral space.
GeoDynamo.apply_velocity_component_flux_bc! — Method
apply_velocity_component_flux_bc!(field::SHTnsSpectralField{T},
domain::RadialDomain,
dr_matrix::BandedMatrix{T},
method::Symbol) where TApply stress-free boundary conditions to a single velocity component (toroidal or poloidal).
All methods now correctly enforce ∂T/∂r = T/r for stress-free boundaries.
Methods
:tau- High-order accurate tau method (recommended, default):direct- First-order finite difference approximation:physical_stress- First-order finite difference (equivalent to :direct)
Performance
Uses pre-allocated workspace buffers if available (set via setvelocityworkspace!). Otherwise allocates temporary arrays (slower).
GeoDynamo.apply_velocity_flux_bc_direct! — Method
apply_velocity_flux_bc_direct!(spec_real, spec_imag, local_lm, lm_idx,
apply_inner, apply_outer, domain, r_range)Apply stress-free boundary conditions using direct substitution.
Stress-Free Boundary Condition Physics
For the toroidal velocity potential T in spherical coordinates, the stress-free (free-slip) boundary condition requires zero tangential stress at the boundary.
The tangential stress tensor component is: σrθ ∝ r ∂/∂r(vθ/r) + (1/r)∂v_r/∂θ
For toroidal flow (vr = 0), this reduces to: σrθ ∝ r ∂/∂r(vθ/r) = ∂vθ/∂r - v_θ/r
Setting σrθ = 0 gives: ∂vθ/∂r = v_θ/r
Since v_θ ∝ T for toroidal flow, this becomes: ∂T/∂r = T/r
This is NOT the same as simple Neumann (∂T/∂r = 0)!
Implementation
Using first-order finite difference at boundary: (T[2] - T[1])/Δr = T[1]/r[1]
Solving for T[1]: T[1] = T[2] / (1 + Δr/r[1])
Similarly for outer boundary: (T[nr] - T[nr-1])/Δr = T[nr]/r[nr] T[nr] = T[nr-1] / (1 - Δr/r[nr])
GeoDynamo.apply_velocity_flux_bc_direct_ws! — Method
apply_velocity_flux_bc_direct_ws!(spec_real, spec_imag, local_lm, lm_idx,
apply_inner, apply_outer,
domain, r_range, ws, tid)Workspace-based version of direct stress-free BC (zero allocation). Uses pre-allocated buffers from workspace ws for thread tid.
Stress-Free Boundary Condition Physics
For the toroidal velocity potential T in spherical coordinates, the stress-free (free-slip) boundary condition requires zero tangential stress at the boundary.
The tangential stress tensor component is: σrθ ∝ r ∂/∂r(vθ/r) + (1/r)∂v_r/∂θ
For toroidal flow (vr = 0), this reduces to: σrθ ∝ r ∂/∂r(vθ/r) = ∂vθ/∂r - v_θ/r
Setting σrθ = 0 gives: ∂vθ/∂r = v_θ/r
Since v_θ ∝ T for toroidal flow, this becomes: ∂T/∂r = T/r
This is NOT the same as simple Neumann (∂T/∂r = 0)!
Implementation
Using first-order finite difference at boundary: (T[2] - T[1])/Δr = T[1]/r[1]
Solving for T[1]: T[1] = T[2] / (1 + Δr/r[1])
Similarly for outer boundary: (T[nr] - T[nr-1])/Δr = T[nr]/r[nr] T[nr] = T[nr-1] / (1 - Δr/r[nr])
GeoDynamo.apply_velocity_flux_bc_physical_stress! — Method
apply_velocity_flux_bc_physical_stress!(spec_real, spec_imag, local_lm, lm_idx,
apply_inner, apply_outer, domain, r_range)Apply flux boundary conditions for proper stress-free boundaries. Enforces ∂T/∂r = T/r at boundaries, which corresponds to zero tangential stress.
Physical Justification
For stress-free boundaries: τ = ∂vtan/∂r - vtan/r = 0 In spectral form with v_tan = T(r) × f(θ,φ): ∂(T×f)/∂r - (T×f)/r = 0 (∂T/∂r - T/r) × f = 0 => ∂T/∂r = T/r
This is the CORRECT condition for stress-free boundaries in spherical coordinates.
GeoDynamo.apply_velocity_flux_bc_physical_stress_ws! — Method
apply_velocity_flux_bc_physical_stress_ws!(spec_real, spec_imag, local_lm, lm_idx,
apply_inner, apply_outer,
domain, r_range, ws, tid)Workspace-based version of physical stress BC (zero allocation). Enforces ∂T/∂r = T/r for proper stress-free boundaries.
GeoDynamo.apply_velocity_flux_bc_spectral! — Method
apply_velocity_flux_bc_spectral!(fields::SHTnsVelocityFields{T}, domain::RadialDomain;
method::Symbol=:tau) where TApply stress-free boundary conditions to velocity field components in spectral space.
This function enforces the correct stress-free condition for the toroidal velocity potential. For stress-free boundaries:
- Poloidal (radial) component: P = 0 (Dirichlet, vr = 0, handled by enforcevelocityboundaryvalues!)
- Toroidal (tangential) component: ∂T/∂r = T/r (stress-free condition, handled here)
Arguments
fields: Velocity field structure with toroidal and poloidal componentsdomain: Radial domain informationmethod: Method for applying BCs (default:taurecommended for accuracy):tau- High-order accurate tau method (recommended):direct- First-order finite difference:physical_stress- First-order finite difference (equivalent to :direct)
Physical Interpretation
For stress-free boundaries, the zero tangential stress condition requires: σrθ = r ∂/∂r(vθ/r) = ∂vθ/∂r - vθ/r = 0
For the toroidal potential T where v_θ ∝ T, this becomes: ∂T/∂r = T/r at boundaries
Note: This is NOT the same as simple Neumann (∂T/∂r = 0)!
GeoDynamo.apply_velocity_flux_bc_tau! — Method
apply_velocity_flux_bc_tau!(spec_real, spec_imag, local_lm, lm_idx,
apply_inner, apply_outer, dr_matrix, domain, r_range)Apply stress-free boundary conditions using the tau method for velocity components.
Stress-Free Boundary Condition Physics
For the toroidal velocity potential T in spherical coordinates, the stress-free (free-slip) boundary condition requires zero tangential stress at the boundary.
The correct condition is: ∂T/∂r = T/r
This means the target flux at each boundary is NOT zero, but T/r:
- Inner boundary: target_flux = T[1]/r[1]
- Outer boundary: target_flux = T[nr]/r[nr]
The tau method adds a correction polynomial to enforce this condition exactly.
GeoDynamo.apply_velocity_flux_bc_tau_ws! — Method
apply_velocity_flux_bc_tau_ws!(spec_real, spec_imag, local_lm, lm_idx,
apply_inner, apply_outer, dr_matrix,
domain, r_range, ws, tid)Workspace-based version of tau method stress-free BC (zero allocation). Uses pre-allocated buffers for profiles, derivatives, and corrections.
Stress-Free Boundary Condition Physics
For the toroidal velocity potential T in spherical coordinates, the stress-free (free-slip) boundary condition requires zero tangential stress at the boundary.
The correct condition is: ∂T/∂r = T/r
This means the target flux at each boundary is NOT zero, but T/r:
- Inner boundary: target_flux = T[1]/r[1]
- Outer boundary: target_flux = T[nr]/r[nr]
The tau method adds a correction polynomial to enforce this condition exactly.
GeoDynamo.batch_convert_directory — Method
batch_convert_directory(input_dir::String, output_dir::String = "";
pattern::String = "combined_global_time_",
precision::Type{T} = Float64,
compute_diagnostics::Bool = true) where TConvert all spectral files matching a pattern in a directory.
GeoDynamo.batch_magnetic_transforms! — Method
batch_magnetic_transforms!(mag_fields::SHTnsMagneticFields{T}) where TPerform batched transforms for better cache efficiency using shtnskit_transforms.jl
GeoDynamo.batch_shtnskit_transforms! — Method
batch_shtnskit_transforms!(specs::Vector{SHTnsSpectralField{T}},
physs::Vector{SHTnsPhysicalField{T}}) where TBatch process multiple transforms using SHTnsKit with PencilArrays.
GeoDynamo.batch_spectral_to_physical! — Method
batch_spectral_to_physical!(specs, physs)Compatibility wrapper that calls batch_shtnskit_transforms! for batched spectral→physical transforms using SHTnsKit with PencilArrays/MPI.
GeoDynamo.batch_velocity_transforms! — Method
batch_velocity_transforms!(fields::SHTnsVelocityFields{T}) where TPerform batched transforms for better cache efficiency using shtnskit_transforms.jl
GeoDynamo.batch_write_spectral_fields! — Method
batch_write_spectral_fields!(nc_file, fields::Dict, config::OutputConfig, field_info::FieldInfo)Write multiple spectral fields in batched operations for better I/O performance
GeoDynamo.build_banded_A — Method
build_banded_A(T, domain, diffusivity, l) -> BandedMatrix{T}Construct banded A = ν*(d²/dr² + (2/r)d/dr − l(l+1)/r²) in banded storage.
GeoDynamo.build_influence_matrix — Method
build_influence_matrix(G_inner, G_outer, dr_matrix, domain)Construct a 2×2 matrix mapping influence amplitudes to boundary flux errors. Rows correspond to (inner, outer) boundaries; columns to (inner, outer) influence functions.
GeoDynamo.build_rhs_cnab2! — Method
build_rhs_cnab2!(rhs, un, nl, nl_prev, dt, matrices)Build RHS for CNAB2 IMEX: rhs = un/dt + (1-θ)·L·un + (3/2)·nl − (1/2)·nl_prev, where θ = matrices.theta and L is the diffusivity-scaled linear operator.
GeoDynamo.build_theta_derivative_matrix — Method
build_theta_derivative_matrix(::Type{T}, config::SHTnsKitConfig) where TBuild sparse matrix for θ-derivatives in spectral space. This matrix couples different l modes with the same m.
GeoDynamo.calculate_linear_neighbors — Method
calculate_linear_neighbors(rank::Int, dim::Int, proc_dims::Tuple, boundaries::Symbol)Calculate neighbor ranks for non-Cartesian topologies.
GeoDynamo.check_field_for_nan — Method
check_field_for_nan(field_data::AbstractArray, field_name::String, config::NaNDetectionConfig, step::Int)Check a field for NaN or Inf values. Returns (hasnan, hasinf, nancount, infcount).
GeoDynamo.check_simulation_state_for_nan — Method
check_simulation_state_for_nan(state::SimulationState, step::Int;
config::NaNDetectionConfig=DEFAULT_NAN_CONFIG)Comprehensive NaN/Inf check across all simulation fields. Returns true if any NaN/Inf detected.
GeoDynamo.check_solenoidal_constraint! — Method
check_solenoidal_constraint!(state::SimulationState)Check and record solenoidal constraint for velocity and magnetic fields.
GeoDynamo.check_spectral_field_for_nan — Method
check_spectral_field_for_nan(field::SHTnsSpectralField, field_name::String,
config::NaNDetectionConfig, step::Int)Check both real and imaginary parts of a spectral field.
GeoDynamo.combine_distributed_time — Method
combine_distributed_time(output_dir::String, time::Float64;
config::CombinerConfig = create_combiner_config(),
precision::Type{T} = Float64) where TMain function to combine distributed files for a specific time.
GeoDynamo.combine_magnetic_spectral! — Method
combine_magnetic_spectral!(combiner::FieldCombiner{T}, lm_mapping::Dict) where TCombine magnetic spectral coefficients from all distributed files.
GeoDynamo.combine_physical_fields! — Method
combine_physical_fields!(combiner::FieldCombiner{T}) where TCombine physical space temperature field from distributed files.
GeoDynamo.combine_spectral_fields! — Method
combine_spectral_fields!(combiner::FieldCombiner{T}) where TCombine spectral field data from distributed files.
GeoDynamo.combine_time_series — Method
combine_time_series(output_dir::String, time_range::Tuple{Float64,Float64};
config::CombinerConfig = create_combiner_config(),
precision::Type{T} = Float64) where TCombine multiple time points into a time series.
GeoDynamo.combine_to_global! — Method
combine_to_global!(combiner::FieldCombiner{T}) where TCombine distributed field data into global field structures.
GeoDynamo.combine_velocity_spectral! — Method
combine_velocity_spectral!(combiner::FieldCombiner{T}, lm_mapping::Dict) where TCombine velocity spectral coefficients from all distributed files.
GeoDynamo.compute_all_gradients_spectral! — Method
compute_all_gradients_spectral!(field::AbstractScalarField{T}, domain::RadialDomain) where TCompute all gradient components (θ, φ, r) in spectral space. This is the main driver function that works for any scalar field.
GeoDynamo.compute_all_nonlinear_terms! — Method
compute_all_nonlinear_terms!(fields, temp_field, comp_field, mag_field, domain)Compute all nonlinear forcing terms for the momentum equation.
Governing Equation (Dimensional)
In a rotating reference frame with angular velocity Ω:
∂u/∂t = -u×ω - ∇p/ρ + 2Ω(ẑ×u) + ν∇²u + (αg/ρ)T·r̂ + (Δρg/ρ)C·r̂ + (1/μ₀ρ)(∇×B)×B
where:
- u: velocity, ω = ∇×u: vorticity
- Ω: rotation rate, ẑ: rotation axis
- ν: kinematic viscosity
- α: thermal expansion coefficient, g: gravity
- T: temperature perturbation, C: composition perturbation
- B: magnetic field, μ₀: permeability
Non-Dimensionalization (Magnetic Diffusion Time Scaling)
Length scale: d (shell thickness or ball radius) Time scale: τ = d²/η (magnetic diffusion time) Velocity scale: U = η/d Magnetic field scale: B₀ Temperature scale: ΔT
Dimensionless parameters:
- E = ν/(Ω d²): Ekman number
- Pm = ν/η: Magnetic Prandtl number
- Pr = ν/κ: Prandtl number
- Sc = ν/D: Schmidt number
- Ra = (αgΔT d³)/(νκ): Rayleigh number
- Ra_C = (Δρg d³)/(ρνD): Compositional Rayleigh number
Non-Dimensional Momentum Equation
(E/Pm) ∂ũ/∂τ + (E/Pm)(∇×ũ)×ũ + ẑ×ũ = -∇p̃ + (Pm/Pr)Ra·T̃·r̂ + (Pm/Sc)Ra_C·C̃·r̂ + (∇×B̃)×B̃ + E∇²ũ
where tilde denotes dimensionless quantities.
Implementation Notes
After dividing Eq. (1) by E/Pm, the explicit RHS entering the time integrator is: RHS = ũ×ω̃ - (Pm/E)(ẑ×ũ) + (Pm/E)(Pm/Pr)Ra·T̃·r̂ + (Pm/E)(Pm/Sc)Ra_C·C̃·r̂ + (Pm/E)(∇×B̃)×B̃
- The advection term ũ×ω̃ already matches −(∇×ũ)×ũ without extra scaling.
- Coriolis, buoyancy, and Lorentz forces carry the (Pm/E) prefactor (=
rossby_factor). - Viscous diffusion is treated implicitly with coefficient Pm (passed via
diffusivity).
The time derivative retains the (E/Pm) mass term and is handled by the integrator.
GeoDynamo.compute_boundary_fluxes — Method
compute_boundary_fluxes(profile::Vector{T}, dr_matrix, domain::RadialDomain) where TCompute flux (dT/dr) at both boundaries using the derivative matrix. Note: drmatrix should be a BandedMatrix{T} (defined in linearalgebra.jl)
GeoDynamo.compute_chebyshev_polynomial — Method
compute_chebyshev_polynomial(n::Int, domain::RadialDomain)Compute Chebyshev polynomial T_n on the radial grid.
GeoDynamo.compute_divergence_spectral — Method
compute_divergence_spectral(tor_spec::SHTnsSpectralField, pol_spec::SHTnsSpectralField,
domain::RadialDomain) where TCompute divergence of a vector field in spectral space. For toroidal-poloidal decomposition: v = ∇×(T r̂) + ∇×∇×(P r̂) The divergence is: ∇·v = ∇·(∇×∇×(P r̂)) = 0 theoretically But numerically we check: div_max = max |∇·v|
GeoDynamo.compute_enstrophy — Method
compute_enstrophy(config::SHTnsKitConfig, Tlm::Matrix{ComplexF64}; real_field::Bool=true)Compute enstrophy (mean square vorticity) from toroidal coefficients. Enstrophy is related to the rotational part of the kinetic energy.
GeoDynamo.compute_field_energy — Method
compute_field_energy(field_data::Array{T,3}) where TCompute L2 energy of a 3D field: E = ½ ∫ |f|² dV ≈ ½ Σ |f_ijk|²
GeoDynamo.compute_global_diagnostics — Method
compute_global_diagnostics(combiner::FieldCombiner{T}) where TCompute global diagnostics for the combined fields.
GeoDynamo.compute_global_diagnostics — Method
compute_global_diagnostics(converter::SpectralToPhysicalConverter{T}) where TCompute global field diagnostics using MPI reductions.
GeoDynamo.compute_horizontal_gradient_magnitude — Method
compute_horizontal_gradient_magnitude(config::SHTnsKitConfig, alm::Matrix{ComplexF64})Compute the magnitude of the horizontal gradient |∇h f|² in spectral space. |∇h f|² = l(l+1) |f_lm|² (summed over all modes)
This is useful for computing gradient energy or penalty terms.
Arguments
config: SHTnsKit configurationalm: Spectral coefficients
Returns
Scalar value of the integrated horizontal gradient magnitude squared
GeoDynamo.compute_influence_functions_flux — Method
compute_influence_functions_flux(oc_domain::RadialDomain)Compute influence functions for flux BCs. These are solutions to the homogeneous equation with specific BCs.
GeoDynamo.compute_inner_tau_function — Method
compute_inner_tau_function(domain::RadialDomain)Compute tau function for inner boundary only (zero derivative at outer).
GeoDynamo.compute_magnetic_helicity — Method
compute_magnetic_helicity(mag_fields::SHTnsMagneticFields{T}) where TCompute magnetic helicity using enhanced spectral integration
GeoDynamo.compute_nonlinear! — Method
compute_nonlinear!(parallelizer, temp_field, vel_fields, domain)Advanced CPU computation with SIMD, NUMA, and task-based parallelism.
GeoDynamo.compute_outer_tau_function — Method
compute_outer_tau_function(domain::RadialDomain)Compute tau function for outer boundary only (zero derivative at inner).
GeoDynamo.compute_phi1_function — Method
compute_phi1_function(A, expA)Compute φ1(A) = (exp(A) - I) / A efficiently with comprehensive error handling. Uses series expansion for small ||A|| to avoid numerical issues.
GeoDynamo.compute_phi2_function — Method
compute_phi2_function(A, expA; l=0)Compute φ2(A) = (exp(A) - I - A) / A² efficiently with comprehensive error handling. Uses series expansion for small ||A|| to avoid numerical issues. Tracks conditioning statistics when monitoring is enabled.
GeoDynamo.compute_phi_gradient_spectral! — Method
compute_phi_gradient_spectral!(field::AbstractScalarField{T}) where TCompute ∂field/∂φ using spherical harmonic properties (local operation). This is generic and works for any scalar field.
GeoDynamo.compute_radial_gradient_spectral! — Method
compute_radial_gradient_spectral!(field::AbstractScalarField{T}, domain::RadialDomain) where TCompute ∂field/∂r using banded matrix derivative operator in spectral space (local operation). This uses the pre-computed derivative matrices from the field for optimal accuracy and efficiency.
GeoDynamo.compute_scalar_advection_local! — Method
compute_scalar_advection_local!(field::AbstractScalarField{T}, vel_fields) where TCompute -u·∇field in physical space (completely local operation). This works for any scalar field.
GeoDynamo.compute_scalar_energy — Method
compute_scalar_energy(field::AbstractScalarField{T}, oc_domain::RadialDomain) where TCompute energy ∫ field² dV
GeoDynamo.compute_scalar_energy_spectrum — Method
compute_scalar_energy_spectrum(config::SHTnsKitConfig, alm::Matrix{ComplexF64}; real_field::Bool=true)Compute the energy spectrum per spherical harmonic degree l using SHTnsKit v1.1.15.
Returns
Vector of length lmax+1 with energy at each degree l.
GeoDynamo.compute_scalar_rms — Method
compute_scalar_rms(field::AbstractScalarField{T}, oc_domain::RadialDomain) where TCompute RMS value of scalar field.
GeoDynamo.compute_spectral_energy_diagnostics! — Method
compute_spectral_energy_diagnostics!(diagnostics, component, real_part, imag_part, field_info)Compute spectral energy distribution diagnostics using SHTns configuration
GeoDynamo.compute_tangential_stress_components — Method
compute_tangential_stress_components(v_theta, v_phi, dv_theta_dr, dv_phi_dr, r_val)Compute tangential stress components from velocity and derivatives.
For incompressible flow with vr = 0: τrθ = μ(∂vθ/∂r - vθ/r) τrφ = μ(∂vφ/∂r - v_φ/r)
Arguments
v_theta, v_phi: Tangential velocity components [nlat, nlon]dv_theta_dr, dv_phi_dr: Radial derivatives [nlat, nlon]r_val: Radial position
Returns
tau_theta, tau_phi: Stress components [nlat, nlon] with μ = 1max_stress: Maximum stress magnitude
GeoDynamo.compute_tau_coefficients_both — Method
compute_tau_coefficients_both(flux_error_inner::T, flux_error_outer::T, domain::RadialDomain) where TCompute tau polynomial coefficients for both boundaries. Uses highest two Chebyshev modes as tau functions.
GeoDynamo.compute_tau_coefficients_inner — Method
compute_tau_coefficients_inner(flux_error::T, domain::RadialDomain) where TCompute tau coefficient for inner boundary only. Uses a single tau function that doesn't affect outer boundary.
GeoDynamo.compute_tau_coefficients_outer — Method
compute_tau_coefficients_outer(flux_error::T, domain::RadialDomain) where TCompute tau coefficient for outer boundary only. Uses a single tau function that doesn't affect inner boundary.
GeoDynamo.compute_tau_correction_both_boundaries! — Method
compute_tau_correction_both_boundaries!(correction::Vector{T}, ...)In-place version that writes to pre-allocated correction buffer.
GeoDynamo.compute_tau_correction_inner_boundary! — Method
compute_tau_correction_inner_boundary!(correction::Vector{T}, ...)In-place version that writes to pre-allocated correction buffer.
GeoDynamo.compute_tau_correction_outer_boundary! — Method
compute_tau_correction_outer_boundary!(correction::Vector{T}, ...)In-place version that writes to pre-allocated correction buffer.
GeoDynamo.compute_theta_gradient_spectral! — Method
compute_theta_gradient_spectral!(field::AbstractScalarField{T}) where TCompute ∂field/∂θ using spherical harmonic recurrence relations (local operation). This is generic and works for any scalar field.
GeoDynamo.compute_theta_recurrence_coefficients — Method
compute_theta_recurrence_coefficients(::Type{T}, config::SHTnsKitConfig) where TPre-compute recurrence coefficients for θ-derivatives. Store as [nlm, 2] matrix: [:, 1] for l-1 coupling, [:, 2] for l+1 coupling
GeoDynamo.compute_total_energy! — Method
compute_total_energy!(state::SimulationState)Compute and record total energy of the simulation state.
GeoDynamo.compute_total_scalar_energy — Method
compute_total_scalar_energy(config::SHTnsKitConfig, alm::Matrix{ComplexF64}; real_field::Bool=true)Compute total energy of a scalar field from its spectral coefficients.
GeoDynamo.compute_total_vector_energy — Method
compute_total_vector_energy(config::SHTnsKitConfig, Slm::Matrix{ComplexF64}, Tlm::Matrix{ComplexF64}; real_field::Bool=true)Compute total kinetic energy of a vector field from spheroidal/toroidal coefficients.
GeoDynamo.compute_vector_energy — Method
compute_vector_energy(v_r::Array{T,3}, v_theta::Array{T,3}, v_phi::Array{T,3}) where TCompute kinetic/magnetic energy: E = ½ ∫ |v|² dV = ½ ∫ (vr² + vθ² + v_φ²) dV
GeoDynamo.compute_vector_energy_spectrum — Method
compute_vector_energy_spectrum(config::SHTnsKitConfig, Slm::Matrix{ComplexF64}, Tlm::Matrix{ComplexF64}; real_field::Bool=true)Compute the kinetic energy spectrum per spherical harmonic degree l for a vector field decomposed into spheroidal (Slm) and toroidal (Tlm) components.
Returns
Vector of length lmax+1 with kinetic energy at each degree l.
GeoDynamo.convert_spectral_file — Method
convert_spectral_file(input_filename::String, output_filename::String = "";
precision::Type{T} = Float64,
compute_diagnostics::Bool = true) where TMain function to convert a single spectral data file to physical space.
GeoDynamo.convert_to_physical! — Method
convert_to_physical!(converter::SpectralToPhysicalConverter{T}) where TConvert all loaded spectral data to physical space using SHTns transforms.
GeoDynamo.create_boundary_slice — Method
create_boundary_slice(size_arr::Tuple, dim::Int, side::Symbol, width::Int)Create array slice for boundary data extraction.
GeoDynamo.create_combiner_config — Method
create_combiner_config(; kwargs...)Create combiner configuration with keyword arguments.
GeoDynamo.create_computation_pencils — Method
create_computation_pencils(topology, dims, config)Create specialized pencils for different stages of computation.
GeoDynamo.create_enhanced_field_variables! — Method
create_enhanced_field_variables!(nc_file, field_info::FieldInfo, config::OutputConfig,
available_fields::Vector{String})Enhanced field variable setup that leverages SHTns configuration
GeoDynamo.create_enhanced_output_config — Method
create_enhanced_output_config(state)Create output configuration with enhanced I/O settings.
GeoDynamo.create_erk2_cache — Method
create_erk2_cache(config, domain, diffusivity, dt; use_krylov=false, m=20, tol=1e-8)Create ERK2 cache with precomputed matrix functions for all spherical harmonic modes.
GeoDynamo.create_erk2_config — Method
create_erk2_config(; lmax, mmax, nlat, nlon, optimize_for_erk2=true)Create an SHTnsKit configuration for ERK2 timestepping.
GeoDynamo.create_etd_cache — Method
create_etd_cache(config, domain, diffusivity, dt) -> ETDCacheBuild per-l exponential cache for the linear operator Al = diffusivity*(d²/dr² + (2/r)d/dr − l(l+1)/r²). Computes exp(dt Al) and phi1(dt A_l) via dense methods. Single-rank recommended.
GeoDynamo.create_field_combiner — Method
create_field_combiner(output_dir::String, time::Float64;
precision::Type{T} = Float64) where TCreate a field combiner by reading configuration from distributed files.
GeoDynamo.create_halo_slice — Method
create_halo_slice(size_arr::Tuple, dim::Int, side::Symbol, width::Int)Create array slice for halo region insertion.
GeoDynamo.create_memory_efficient_output_buffer — Method
create_memory_efficient_output_buffer(data_size::Int, precision::DataType)Create appropriately sized buffer for output operations
GeoDynamo.create_parameter_template — Method
create_parameter_template(filename::String)Create a template parameter file for users to customize.
GeoDynamo.create_pencil_array — Method
create_pencil_array(::Type{T}, pencil::Pencil; init=:zero) where TCreate a PencilArray with specified initialization.
GeoDynamo.create_pencil_decomposition_shtnskit — Function
create_pencil_decomposition_shtnskit(nlat, nlon, nr, sht_config, comm, optimize)Create PencilArrays decomposition optimized for spherical harmonic transforms.
The Pencil Decomposition Strategy
In a pencil decomposition, 3D data is distributed across MPI processes such that one dimension is always fully local (not split across processes). This enables efficient operations along that dimension without MPI communication.
Physical Space Pencils (nlat × nlon × nr)
theta pencil: [θ local] × [φ distributed] × [r distributed]
→ Best for operations along latitude (Legendre transforms)
phi pencil: [θ distributed] × [φ local] × [r distributed]
→ Best for FFTs along longitude
r pencil: [θ distributed] × [φ distributed] × [r local]
→ Best for radial operations (derivatives, boundary conditions)Spectral Space Pencil (nlm × 1 × nr)
The spectral pencil stores spherical harmonic coefficients indexed by a combined (l,m) index. The middle dimension is 1 (dummy) for compatibility.
Arguments
nlat, nlon, nr: Grid dimensionssht_config: SHTnsKit configuration (provides nlm)comm: MPI communicatoroptimize: Whether to optimize process topology for load balance
Returns
NamedTuple with pencil configurations: (:theta, :θ, :phi, :φ, :r, :spec, :mixed)
GeoDynamo.create_pencil_fft_plans — Method
create_pencil_fft_plans(pencils, dims) -> Dict{Symbol,Any}Create precomputed FFTW plans for efficient FFT operations.
Why Precomputed Plans?
FFTW achieves best performance when FFT plans are created once and reused. Plan creation involves:
- Analyzing the input size and memory layout
- Choosing optimal algorithm (Cooley-Tukey, Bluestein, etc.)
- Possibly benchmarking different strategies
Plan Types Created
:phi_forward/:phi_backward: FFT/IFFT along longitude (dimension 2):theta_forward/:theta_backward: FFT/IFFT for theta pencil orientation
Technical Notes
- Plans operate on the
parent()array of PencilArrays (the underlying Julia array) - We use FFTW directly rather than PencilFFTPlan because we need single-dimension transforms, not full multi-dimensional distributed FFTs
- The plans are tied to specific array sizes and memory layouts
Arguments
pencils: NamedTuple of Pencil configurationsdims: Tuple (nlat, nlon, nr) of grid dimensions
Returns
Dict mapping plan names to FFTW plan objects. Contains :fallback => true on error.
GeoDynamo.create_pencil_topology — Method
create_pencil_topology(shtns_config; optimize=true)Create enhanced pencil decomposition for SHTns grids. Supports both 1D and 2D decompositions with automatic optimization. Accepts an object with fields nlat, nlon, and nlm (e.g., SHTnsKitConfig).
GeoDynamo.create_shtns_aware_output_config — Method
create_shtns_aware_output_config(shtns_config::SHTnsKitConfig, pencils::NamedTuple;
base_config::OutputConfig = default_config())Create output configuration that integrates with SHTns configuration and pencil decomposition
GeoDynamo.create_shtns_physical_field — Method
create_shtns_physical_field(T, config, oc_domain, pencil) -> SHTnsPhysicalField{T}Create a new physical space field initialized to zero.
Arguments
T: Element type (typically Float64)config: SHTnsKit configuration providing grid dimensionsoc_domain: RadialDomain (for consistency with spectral field API)pencil: PencilArrays Pencil defining the data distribution
Returns
A new SHTnsPhysicalField with all grid values initialized to zero.
GeoDynamo.create_shtns_spectral_field — Method
create_shtns_spectral_field(T, config, oc_domain, pencil_spec) -> SHTnsSpectralField{T}Create a new spectral field initialized to zero with default Dirichlet BCs.
Arguments
T: Element type (typically Float64)config: SHTnsKit configuration providing nlm and other parametersoc_domain: RadialDomain specifying the radial discretizationpencil_spec: PencilArrays Pencil defining the data distribution
Returns
A new SHTnsSpectralField with:
- All spectral coefficients initialized to zero
- Dirichlet boundary conditions on all modes
- Zero boundary values
GeoDynamo.create_shtns_vector_field — Method
create_shtns_vector_field(T, config, oc_domain, pencils) -> SHTnsVectorField{T}Create a new vector field with three physical space components.
Arguments
T: Element typeconfig: SHTnsKit configurationoc_domain: RadialDomain specificationpencils: Either a NamedTuple with :theta/:θ, :phi/:φ, :r keys, or a tuple (pencilθ, pencilφ, pencil_r)
Returns
A new SHTnsVectorField with all components initialized to zero. Each component uses a potentially different pencil orientation for optimal computation of different operations.
GeoDynamo.create_shtnskit_config — Method
create_shtnskit_config(; lmax, mmax, nlat, nlon, nr, optimize_decomp) -> SHTnsKitConfigCreate and initialize a complete SHTnsKit configuration for spherical harmonic transforms with MPI parallelization.
Keyword Arguments
lmax::Int: Maximum spherical harmonic degree (required)mmax::Int=lmax: Maximum spherical harmonic order (≤ lmax)nlat::Int: Number of latitude points. Must be ≥ lmax+1 for numerical accuracy. Defaults to max(lmax+2, parameter system value)nlon::Int: Number of longitude points. Must be ≥ 2*mmax+1 for alias-free transforms. Powers of 2 are preferred for FFT efficiency.nr::Int=i_N: Number of radial points (from parameter system)optimize_decomp::Bool=true: Whether to optimize MPI process topology
Returns
SHTnsKitConfig: Fully initialized configuration ready for transforms
Algorithm
- Create base SHTnsKit configuration with Gauss-Legendre grid
- Set up pencil decomposition for MPI parallelization
- Create FFT plans for longitude transforms
- Create transpose plans for data redistribution
- Initialize grid coordinates and quadrature weights
Example
# Create config for lmax=63 simulation
config = create_shtnskit_config(lmax=63, nlat=96, nlon=192)GeoDynamo.create_shtnskit_transpose_plans — Method
create_shtnskit_transpose_plans(pencils) -> Dict{Symbol,Any}Create transpose plans for redistributing data between pencil orientations.
What is a Transpose?
In pencil decomposition, a "transpose" is an MPI all-to-all communication that redistributes data so a different dimension becomes local. For example:
- theta → phi transpose: makes longitude local (for FFTs)
- phi → r transpose: makes radius local (for radial derivatives)
Why Plans?
Like FFT plans, transpose plans encode the communication pattern and can optimize buffer allocation and MPI operations.
Transpose Constraints
PencilArrays requires that source and destination pencils differ in at most one distributed dimension. If they differ in two dimensions, we need a multi-step transpose (e.g., phi → theta → r).
Plan Keys Created
:theta_to_phi,:phi_to_theta: Switch between theta and phi local:theta_to_r,:r_to_theta: Switch between theta and r local:phi_to_r,:r_to_phi: May be direct or marked as:multi_step
Usage
# Transpose data from theta-local to phi-local orientation
mul!(dest_array, transpose_plans[:theta_to_phi], src_array)GeoDynamo.create_spectral_converter — Method
create_spectral_converter(filename::String; precision::Type{T} = Float64) where TCreate a spectral to physical converter by reading configuration from a NetCDF file.
GeoDynamo.create_transpose_plans — Method
create_transpose_plans(pencils)Create enhanced transpose plans between pencil orientations. Includes caching and communication optimization.
GeoDynamo.eab2_update! — Method
eab2_update!(u, nl, nl_prev, etd, config)Apply EAB2 update per (l,m): u^{n+1} = E u^n + dtphi1(3/2 nl^n − 1/2 nl^{n−1}).
GeoDynamo.eab2_update_krylov! — Method
eab2_update_krylov!(u, nl, nl_prev, domain, diffusivity, config, dt; m=20, tol=1e-8)EAB2 update using Krylov exp/φ1 actions and banded LU for φ1.
GeoDynamo.eab2_update_krylov_cached! — Method
eab2_update_krylov_cached!(u, nl, nl_prev, alu_map, domain, ν, config, dt; m=20, tol=1e-8)Same as eab2updatekrylov!, but reuses cached banded A and LU per l.
GeoDynamo.enforce_composition_boundary_values! — Method
enforce_composition_boundary_values!(field)Anchor spectral boundary modes to stored Dirichlet values when applicable.
GeoDynamo.enforce_magnetic_boundary_values! — Method
enforce_magnetic_boundary_values!(fields)Anchor magnetic toroidal/poloidal spectral data to cached Dirichlet boundary values on the inner and outer radial surfaces.
GeoDynamo.enforce_temperature_boundary_values! — Method
enforce_temperature_boundary_values!(field)Anchor spectral boundary coefficients to stored Dirichlet values when needed.
GeoDynamo.enforce_velocity_boundary_values! — Method
enforce_velocity_boundary_values!(fields)Anchor toroidal and poloidal spectral coefficients to the currently cached Dirichlet boundary values on the inner and outer radial surfaces.
GeoDynamo.erk2_stage_residual_stats — Method
erk2_stage_residual_stats(buffers) -> NamedTupleCompute diagnostic statistics for the difference between stage nonlinear terms and the base-step nonlinear terms.
GeoDynamo.estimate_field_count — Method
estimate_field_count() -> IntEstimate the number of field arrays typically allocated simultaneously. Used for memory usage estimation. Returns 6 as a reasonable default covering velocity (3 components), temperature, composition, and magnetic field.
GeoDynamo.estimate_memory_usage — Method
estimate_memory_usage(pencils, field_count::Int, precision::Type)Estimate memory usage for given pencil configuration.
GeoDynamo.estimate_memory_usage_shtnskit — Method
estimate_memory_usage_shtnskit(nlat, nlon, lmax, field_count, T)Estimate memory usage for SHTnsKit-based transforms with PencilArrays.
GeoDynamo.eval_with_context — Method
eval_with_context(expr, param_dict::Dict{Symbol, Any})Evaluate an expression by substituting symbols with values from param_dict.
GeoDynamo.evaluate_chebyshev_derivative — Method
evaluate_chebyshev_derivative(n::Int, r::T, domain::RadialDomain) where TEvaluate derivative of Chebyshev polynomial at a point.
GeoDynamo.evaluate_tau_derivative_inner — Method
evaluate_tau_derivative_inner(tau::Vector, domain::RadialDomain)Evaluate tau function derivative at inner boundary.
GeoDynamo.evaluate_tau_derivative_outer — Method
evaluate_tau_derivative_outer(tau::Vector, domain::RadialDomain)Evaluate tau function derivative at outer boundary.
GeoDynamo.exchange_dimension_halos! — Method
exchange_dimension_halos!(data::Array, pencil::Pencil, dim::Int,
halo_width::Int, boundaries::Symbol, comm::MPI.Comm)Perform halo exchange along a specific dimension using MPI point-to-point communication.
GeoDynamo.exp_action_krylov — Method
exp_action_krylov(Aop!, v, dt; m=20, tol=1e-8) -> y ≈ exp(dt A) vSimple Arnoldi-based approximation of the exponential action.
GeoDynamo.extract_coefficients_for_shtnskit! — Method
extract_coefficients_for_shtnskit!(coeffs_buffer, spec_real, spec_imag, r_local, config)Extract spectral coefficients into SHTnsKit's expected matrix format.
Data Format Conversion
Our internal format: Linear array indexed by combined (l,m) index SHTnsKit format: Matrix indexed by [l+1, m+1]
Arguments
coeffs_buffer: Pre-allocated (lmax+1) × (mmax+1) complex matrix (output)spec_real,spec_imag: Real and imaginary parts of spectral coefficientsr_local: Radial level index (1-based)config: SHTnsKit configuration
Threading
Uses @threads for parallel filling of the coefficient matrix.
GeoDynamo.extract_coefficients_for_shtnskit — Method
extract_coefficients_for_shtnskit(spec_real, spec_imag, r_local, config) -> Matrix{ComplexF64}High-level coefficient extraction with automatic buffer management and MPI gathering.
This is the main entry point for preparing spectral coefficients for SHTnsKit. It handles:
- Buffer allocation/reuse from cache
- Local coefficient extraction
- MPI Allreduce to combine coefficients from all processes
Why MPI Gathering?
Spectral coefficients may be distributed across MPI processes. SHTnsKit needs the complete coefficient matrix, so we sum partial contributions from all processes.
Returns
A complete (lmax+1) × (mmax+1) coefficient matrix ready for SHTnsKit.synthesis()
GeoDynamo.extract_divergence_coefficients — Method
extract_divergence_coefficients(config::SHTnsKitConfig, Slm::Matrix{ComplexF64})Extract divergence spectral coefficients from spheroidal potential. The divergence field in spectral space is related to Slm by the horizontal Laplacian.
Returns
Matrix of divergence coefficients.
GeoDynamo.extract_local_radial_profile! — Method
extract_local_radial_profile!(profile, data, local_lm, nr, r_range)In-place version to avoid allocations; writes the local radial line into profile for the given local_lm using the provided r_range.
GeoDynamo.extract_physical_slice_generic! — Method
extract_physical_slice_generic!(slice_buffer, phys_data, r_local, config)Generic extraction for any pencil orientation using pre-allocated buffer.
GeoDynamo.extract_physical_slice_phi_local! — Method
extract_physical_slice_phi_local!(slice_buffer, phys_data, r_local, config)Extract physical slice when in phi-local pencil using pre-allocated buffer.
GeoDynamo.extract_spectral_subset — Method
extract_spectral_subset(field::SHTnsSpectralField{T}; l_max::Int = 10) where TExtract a subset of spectral modes for analysis.
GeoDynamo.extract_vector_component_generic! — Method
extract_vector_component_generic!(component_buffer, v_data, r_local, config)Generic extraction for vector components using pre-allocated buffer.
GeoDynamo.extract_vorticity_coefficients — Method
extract_vorticity_coefficients(config::SHTnsKitConfig, Tlm::Matrix{ComplexF64})Extract vorticity spectral coefficients from toroidal potential. The vorticity field in spectral space is related to Tlm by the horizontal Laplacian.
Returns
Matrix of vorticity coefficients.
GeoDynamo.find_distributed_files — Function
find_distributed_files(output_dir::String, time::Float64, filename_prefix::String = "geodynamo")Find all distributed files for a specific simulation time.
GeoDynamo.find_package_root — Method
find_package_root()Find the root directory of the GeoDynamo.jl package.
GeoDynamo.get_comm — Method
get_comm()Get MPI communicator, initializing MPI if needed. Provides thread-safe lazy initialization.
GeoDynamo.get_default_nlat — Method
get_default_nlat() -> IntGet the default number of latitude points for the grid. Tries to read from the parameter system first, falls back to 64. Used during precompilation when parameters may not be available.
GeoDynamo.get_default_nlon — Method
get_default_nlon() -> IntGet the default number of longitude points for the grid. Tries to read from the parameter system first, falls back to 128. Power of 2 is preferred for efficient FFT operations.
GeoDynamo.get_dimension_neighbors — Method
get_dimension_neighbors(pencil::Pencil, dim::Int, boundaries::Symbol) -> (Int, Int)Get left and right neighbor process ranks for a given dimension. Returns (leftneighbor, rightneighbor) where MPI.MPIPROCNULL indicates no neighbor.
GeoDynamo.get_eab2_alu_cache! — Method
get_eab2_alu_cache!(caches, key, ν, T, domain) -> Dict{Int,Tuple{BandedMatrix{T},BandedLU{T}}}Retrieve or initialize a cache mapping l -> (Abanded, LU(Abanded)) for EAB2. Reinitializes if ν or nr changed. Type-stable version using EAB2ALUCacheEntry.
GeoDynamo.get_erk2_cache! — Method
get_erk2_cache!(caches, key, diffusivity, config, domain, dt; use_krylov=false)Retrieve or create ERK2 cache with automatic invalidation when parameters change. Type-stable version using concrete ERK2Cache{T} type.
GeoDynamo.get_flux_value — Method
get_flux_value(lm_idx::Int, boundary::Int, field::AbstractScalarField)Get prescribed flux value for given mode and boundary from scalar field. This is a generic version that works with any scalar field.
GeoDynamo.get_nprocs — Method
get_nprocs()Get total number of MPI processes.
GeoDynamo.get_parameters — Method
get_parameters()Get the current global parameters. If not set, loads default parameters. Thread-safe lazy initialization with type-stable return.
GeoDynamo.get_pencil_orientation — Method
get_pencil_orientation(pencil) -> SymbolDetermine which dimension(s) are fully local in a pencil decomposition.
Returns
:theta_phi: Both angular dimensions local (serial or single-node):theta: Latitude (θ) dimension is local:phi: Longitude (φ) dimension is local:r: Radial dimension is local
Usage
Used to choose optimal transform strategies based on data layout.
GeoDynamo.get_process_dimensions — Method
get_process_dimensions(topology) -> TupleExtract process grid dimensions from topology.
GeoDynamo.get_rank — Method
get_rank()Get MPI rank of current process.
GeoDynamo.get_shtnskit_performance_stats — Method
get_shtnskit_performance_stats()Get performance statistics for SHTnsKit transforms with PencilArrays. Returns information about the v1.1.15+ features being used.
GeoDynamo.get_shtnskit_version_info — Method
get_shtnskit_version_info()Get version and capability information about the SHTnsKit installation.
GeoDynamo.get_velocity_workspace — Method
get_velocity_workspace(::Type{T})::Union{VelocityWorkspace{T}, Nothing} where TGet the global velocity workspace if available and matches type T. Returns nothing if not set or type mismatch.
GeoDynamo.hybrid_compute_nonlinear! — Method
hybrid_compute_nonlinear!(parallelizer, temp_field, vel_fields, domain)Compute nonlinear terms using hybrid MPI+threading parallelism.
GeoDynamo.index_to_lm_shtnskit — Method
index_to_lm_shtnskit(idx, lmax, mmax) -> (l, m)Convert linear spectral index to spherical harmonic degree (l) and order (m).
Index Ordering
The linear index follows the convention where m varies fastest within each l:
- idx=1: (l=0, m=0)
- idx=2: (l=1, m=0)
- idx=3: (l=1, m=1)
- idx=4: (l=2, m=0)
- idx=5: (l=2, m=1)
- idx=6: (l=2, m=2)
- ...
Performance Note
This function uses a linear search. For performance-critical code with many lookups, consider precomputing the lvalues and mvalues arrays (stored in SHTnsKitConfig).
GeoDynamo.infer_pencils_from_transpose_name — Method
infer_pencils_from_transpose_name(name::Symbol, plan) -> (src_pencil, dest_pencil)Infer source and destination pencils from transpose operation name and plan. For TransposeOperator, we need to extract pencil info from context since the operator itself doesn't expose src/dest pencils directly.
GeoDynamo.initialize_enhanced_simulation — Method
initialize_enhanced_simulation(::Type{T}=Float64; kwargs...)Initialize simulation with all parallelization features enabled.
GeoDynamo.initialize_parameters — Function
initialize_parameters(config_file::String = "")Initialize the global parameter system.
GeoDynamo.initialize_simulation — Method
initialize_master_simulation(::Type{T}=Float64; kwargs...)Initialize simulation with comprehensive CPU parallelization.
GeoDynamo.install_erk2_cache_bundle! — Method
install_erk2_cache_bundle!(target, bundle)Copy ERK2 caches from bundle into the target cache dictionary.
GeoDynamo.list_available_times — Function
list_available_times(output_dir::String, filename_prefix::String = "geodynamo")List all available simulation times in the output directory.
GeoDynamo.load_distributed_fields! — Method
load_distributed_fields!(combiner::FieldCombiner{T}) where TLoad field data from all distributed files into the combiner structure.
GeoDynamo.load_erk2_cache_bundle! — Method
load_erk2_cache_bundle!(target, path) -> metadataLoad caches from path and install them into target, returning metadata.
GeoDynamo.load_erk2_cache_bundle — Method
load_erk2_cache_bundle(path) -> (caches, metadata)Load ERK2 caches and associated metadata from disk.
GeoDynamo.load_parameters — Function
load_parameters(config_file::String = "")Load parameters from a configuration file. If no file is specified, loads from the default config/default_params.jl file.
Arguments
config_file::String: Path to parameter file (optional)
Returns
GeoDynamoParameters: Loaded parameters
GeoDynamo.load_parameters_from_file — Method
load_parameters_from_file(config_file::String)Load parameters from a Julia file containing parameter definitions.
GeoDynamo.load_physical_temperature! — Method
load_physical_temperature!(field::SHTnsPhysicalField{T}, nc_file, var_name::String) where TLoad physical space temperature data from NetCDF file.
GeoDynamo.load_single_file! — Method
load_single_file!(combiner::FieldCombiner{T}, filename::String) where TLoad data from a single file (no combination needed).
GeoDynamo.load_single_spectral_field! — Method
load_single_spectral_field!(field::SHTnsSpectralField{T}, nc_file,
real_var::String, imag_var::String) where TLoad a single spectral field from NetCDF file.
GeoDynamo.load_spectral_coefficients! — Method
load_spectral_coefficients!(field::SHTnsSpectralField{T}, nc_file,
real_var_name::String, imag_var_name::String,
l_values::Vector{Int}, m_values::Vector{Int},
r_spectral::Vector{Float64}) where TLoad spectral coefficients from NetCDF file into a spectral field structure.
GeoDynamo.load_spectral_data! — Method
load_spectral_data!(converter::SpectralToPhysicalConverter{T}, filename::String) where TLoad spectral field data from NetCDF file into GeoDynamo field structures.
GeoDynamo.main_batch_convert — Method
main_batch_convert(input_dir::String; kwargs...)Main entry point for batch conversion of files.
GeoDynamo.main_combine_time — Method
main_combine_time(output_dir::String, time::Float64; kwargs...)Main entry point for combining distributed files for a single time.
GeoDynamo.main_combine_time_series — Method
main_combine_time_series(output_dir::String, time_range::Tuple{Float64,Float64}; kwargs...)Main entry point for combining time series.
GeoDynamo.main_convert_file — Method
main_convert_file(filename::String; kwargs...)Main entry point for converting a single file.
GeoDynamo.map_spectral_coefficients! — Method
map_spectral_coefficients!(global_tor_real, global_tor_imag, global_pol_real, global_pol_imag,
local_tor_real, local_tor_imag, local_pol_real, local_pol_imag,
local_l, local_m, lm_mapping)Map local spectral coefficients to global arrays using (l,m) index mapping.
GeoDynamo.maybe_log_erk2_stage_residual! — Method
maybe_log_erk2_stage_residual!(label, buffers, step)Emit a diagnostic log entry when ERK2 diagnostics are enabled.
GeoDynamo.modify_for_flux_inner! — Method
modify_for_flux_inner!(spec_real, spec_imag, local_lm, prescribed_flux,
dr_matrix, domain, r_range)Modify coefficients near inner boundary to approximate flux condition. Uses low-order extrapolation.
GeoDynamo.modify_for_flux_outer! — Method
modify_for_flux_outer!(spec_real, spec_imag, local_lm, prescribed_flux,
dr_matrix, domain, r_range)Modify coefficients near outer boundary to approximate flux condition. Uses low-order extrapolation.
GeoDynamo.normalize_influence_function! — Method
normalize_influence_function!(G::Vector{T}, domain::RadialDomain, which_boundary::Int) where TNormalize influence function to have unit flux at the specified boundary.
GeoDynamo.optimize_communication_order — Method
optimize_communication_order(plans::Dict)Determine optimal order for transpose operations to minimize communication.
GeoDynamo.optimize_erk2_transforms! — Method
optimize_erk2_transforms!(config::SHTnsKitConfig)Optimize SHTnsKit transforms for ERK2 timestepping with PencilFFTs. This function pre-warms transform plans and optimizes memory layout.
GeoDynamo.optimize_fft_performance! — Method
optimize_fft_performance!(config::SHTnsKitConfig)Optimize FFT performance by warming up FFTW plans and checking efficiency.
GeoDynamo.optimize_field_data_layout! — Method
optimize_field_data_layout!(field_data::Dict, field_info::FieldInfo)Optimize data layout for output based on pencil decomposition
GeoDynamo.optimize_magnetic_memory_layout! — Method
optimize_magnetic_memory_layout!(mag_fields::SHTnsMagneticFields{T}) where TOptimize memory layout for better cache performance using pencil topology
GeoDynamo.optimize_process_topology — Method
optimize_process_topology(nprocs::Int, dims::Tuple{Int,Int,Int})Find optimal 2D process grid for given number of processes and problem dimensions. Minimizes communication volume.
GeoDynamo.optimize_process_topology_shtnskit — Method
optimize_process_topology_shtnskit(nprocs, nlat, nlon) -> Tuple{Int,Int}Find optimal 2D MPI process grid for theta-phi parallelization.
The Optimization Problem
Given nprocs MPI processes, we need to factor it as nprocs = p_theta × p_phi such that:
- Each process gets at least 2 grid points in each direction
- Load imbalance (due to non-divisibility) is minimized
- The decomposition is valid (exact factorization)
Algorithm
Iterates through all valid factorizations and scores them by load imbalance. The load imbalance for a dimension is: |gridsize mod processes| / gridsize
Example
For nprocs=12, nlat=64, nlon=128:
- Possible factorizations: (1,12), (2,6), (3,4), (4,3), (6,2), (12,1)
- (4,3) gives nlat/4=16 points/proc in θ, nlon/3≈43 points/proc in φ
- This might be optimal if it minimizes total imbalance
Arguments
nprocs: Total number of MPI processesnlat: Number of latitude pointsnlon: Number of longitude points
Returns
(p_theta, p_phi): Optimal process grid dimensions
GeoDynamo.optimize_velocity_memory_layout! — Method
optimize_velocity_memory_layout!(fields::SHTnsVelocityFields{T}) where TOptimize memory layout for better cache performance using pencil topology
GeoDynamo.perform_analysis_direct! — Method
perform_analysis_direct!(phys, spec, config)Direct analysis without transpose (fallback).
GeoDynamo.perform_analysis_from_phi_pencil! — Method
perform_analysis_from_phi_pencil!(phys_phi, spec, config)Perform analysis from phi-pencil data.
GeoDynamo.perform_analysis_phi_local! — Method
perform_analysis_phi_local!(phys, spec, config)Perform analysis when physical field is in phi-pencil orientation.
This is the most efficient analysis path because:
- The phi (longitude) dimension is fully local on each process
- SHTnsKit's FFT operates entirely in local memory
- No MPI communication needed during the transform itself
GeoDynamo.perform_analysis_with_transpose! — Method
perform_analysis_with_transpose!(phys, spec, config, to_phi_plan)Perform analysis with transpose to phi-pencil.
GeoDynamo.perform_synthesis_direct! — Method
perform_synthesis_direct!(spec, phys, config)Direct synthesis method that handles any pencil orientation.
This is the default/fallback method. It works regardless of the physical field's pencil orientation by using a generic storage function that handles the index mapping appropriately.
Note
For phi-pencil physical fields, perform_synthesis_phi_local! is more efficient as it can use optimized storage.
GeoDynamo.perform_synthesis_phi_local! — Method
perform_synthesis_phi_local!(spec, phys, config)Perform synthesis when physical field is in phi-pencil orientation.
This is the most efficient synthesis path because:
- The phi (longitude) dimension is fully local on each process
- SHTnsKit's FFT operates entirely in local memory
- No MPI communication needed during the transform itself
Algorithm for each radial level:
- Extract spectral coefficients into SHTnsKit's (lmax+1, mmax+1) matrix format
- Call SHTnsKit.synthesis() which does Legendre transform + FFT
- Store the resulting (nlat, nlon) physical field slice
GeoDynamo.perform_synthesis_to_phi_pencil! — Method
perform_synthesis_to_phi_pencil!(spec, phys_phi, config)Core synthesis routine that writes directly to a phi-pencil array.
This is the workhorse function called by other synthesis routines. It assumes the destination array is already in phi-pencil orientation.
GeoDynamo.perform_synthesis_with_transpose! — Method
perform_synthesis_with_transpose!(spec, phys, config, back_plan)Perform synthesis when physical field is NOT in phi-pencil orientation.
Strategy
When the target physical field is in a non-phi pencil (e.g., theta or r pencil), we can't directly use SHTnsKit because it requires all longitude points to be local.
Solution:
- Create a temporary phi-pencil array
- Perform synthesis to the temporary array (longitude local)
- Transpose the result to the target pencil orientation
This involves one extra MPI all-to-all communication (the transpose) but ensures the FFT can operate on contiguous local data.
GeoDynamo.phi1_action_krylov — Method
phi1_action_krylov(BA, LU_A, v, dt; m=20, tol=1e-8) -> y ≈ φ1(dt A) vCompute φ1(dt A) v = A^{-1}[(exp(dt A) − I) v]/dt using Krylov exp(action) and banded solve.
GeoDynamo.print_geodynamo_banner — Method
print_geodynamo_banner(config, nprocs::Int, nthreads::Int)Print the GeoDynamo startup banner with configuration information.
GeoDynamo.print_output_verification_report — Method
print_output_verification_report(output_dir::String, hist_numbers::Vector{Int}, nprocs::Int;
geometry::String="shell")Print a comprehensive report verifying output files from all ranks across multiple history snapshots.
GeoDynamo.print_pencil_axes — Method
print_pencil_axes(pencils)Print the axes_local tuple for each pencil, showing the local index ranges for all three axes. This helps verify which axes are distributed (those with nontrivial subranges across ranks) and which axis is contiguous locally.
GeoDynamo.print_pencil_info — Method
print_pencil_info(pencils)Print detailed information about pencil decomposition.
GeoDynamo.print_shtnskit_config_summary — Method
print_shtnskit_config_summary(nlat, nlon, lmax, mmax, nlm, nprocs, memory_estimate)Print configuration summary for SHTnsKit setup.
GeoDynamo.print_transpose_statistics — Method
print_transpose_statistics()Print accumulated transpose timing statistics.
GeoDynamo.read_distributed_metadata — Method
read_distributed_metadata(filename::String)Read metadata from a distributed NetCDF file to determine global configuration.
GeoDynamo.read_file_metadata — Method
read_file_metadata(filename::String)Read metadata from NetCDF file to determine grid configuration.
GeoDynamo.report_energy_conservation — Method
report_energy_conservation(step::Int; interval::Int=100)Report energy conservation statistics periodically.
GeoDynamo.report_phi2_conditioning — Method
report_phi2_conditioning(step::Int; interval::Int=100)Report φ₂ conditioning statistics periodically during simulation.
GeoDynamo.report_solenoidal_constraint — Method
report_solenoidal_constraint(step::Int; interval::Int=100)Report solenoidal constraint violations periodically.
GeoDynamo.reset_energy_tracker! — Method
reset_energy_tracker!()Reset energy tracking data.
GeoDynamo.reset_phi2_monitor! — Method
reset_phi2_monitor!()Reset φ₂ conditioning monitor statistics.
GeoDynamo.reset_solenoidal_monitor! — Method
reset_solenoidal_monitor!()Reset solenoidal constraint monitoring data.
GeoDynamo.rotate_field_90x! — Method
rotate_field_90x!(config::SHTnsKitConfig, alm::Matrix{ComplexF64};
alm_out::Union{Matrix{ComplexF64},Nothing}=nothing)Rotate a scalar field by 90 degrees around the x-axis. Equivalent to: Z(-π/2) * Y(π/2) * Z(π/2)
Arguments
config: SHTnsKit configurationalm: Input spectral coefficientsalm_out: Optional output array
Returns
The rotated coefficients
GeoDynamo.rotate_field_90y! — Method
rotate_field_90y!(config::SHTnsKitConfig, alm::Matrix{ComplexF64};
alm_out::Union{Matrix{ComplexF64},Nothing}=nothing)Rotate a scalar field by 90 degrees around the y-axis. This is a special case with optimized Wigner d-matrix values.
Arguments
config: SHTnsKit configurationalm: Input spectral coefficientsalm_out: Optional output array
Returns
The rotated coefficients
GeoDynamo.rotate_field_euler! — Method
rotate_field_euler!(config::SHTnsKitConfig, alm::Matrix{ComplexF64},
alpha::Real, beta::Real, gamma::Real;
alm_out::Union{Matrix{ComplexF64},Nothing}=nothing)Rotate a scalar field by Euler angles (ZYZ convention) in spectral space. The rotation is: R = Rz(gamma) * Ry(beta) * Rz(alpha)
Arguments
config: SHTnsKit configurationalm: Input spectral coefficientsalpha, beta, gamma: Euler angles in radians (ZYZ convention)alm_out: Optional output array
Returns
The rotated coefficients
GeoDynamo.rotate_field_y! — Method
rotate_field_y!(config::SHTnsKitConfig, alm::Matrix{ComplexF64}, beta::Real;
alm_out::Union{Matrix{ComplexF64},Nothing}=nothing)Rotate a scalar field around the y-axis by angle beta in spectral space. Uses Wigner d-matrices (small Wigner rotation matrices).
Arguments
config: SHTnsKit configurationalm: Input spectral coefficientsbeta: Rotation angle in radiansalm_out: Optional output array
Returns
The rotated coefficients
GeoDynamo.rotate_field_z! — Method
rotate_field_z!(config::SHTnsKitConfig, alm::Matrix{ComplexF64}, alpha::Real;
alm_out::Union{Matrix{ComplexF64},Nothing}=nothing)Rotate a scalar field around the z-axis by angle alpha in spectral space. This is a pure phase rotation: alm[l,m] -> alm[l,m] * exp(-imalpha)
Arguments
config: SHTnsKit configurationalm: Input spectral coefficients (modified in-place if alm_out is nothing)alpha: Rotation angle in radiansalm_out: Optional output array (if nothing, modifies alm in-place)
Returns
The rotated coefficients (alm_out if provided, otherwise alm)
GeoDynamo.run_enhanced_simulation! — Method
run_enhanced_simulation!(state::SimulationState{T})Run geodynamo simulation with all parallelization optimizations.
GeoDynamo.run_simulation! — Method
run_master_simulation!(state::SimulationState{T})Run geodynamo simulation with maximum CPU parallelization optimizations.
GeoDynamo.save_combined_fields — Method
save_combined_fields(combiner::FieldCombiner{T}, output_filename::String;
config::CombinerConfig = create_combiner_config()) where TSave combined fields to NetCDF file using GeoDynamo I/O system.
GeoDynamo.save_combined_time_series — Method
save_combined_time_series(combiners::Vector{FieldCombiner{T}}, output_dir::String,
filename_prefix::String;
config::CombinerConfig = create_combiner_config()) where TSave combined time series to a single NetCDF file.
GeoDynamo.save_erk2_cache_bundle — Method
save_erk2_cache_bundle(path, caches; metadata=Dict())Persist a dictionary of ERK2 caches to disk along with optional metadata.
GeoDynamo.save_parameters — Method
save_parameters(params::GeoDynamoParameters, filename::String)Save parameters to a Julia file.
GeoDynamo.save_physical_fields — Method
save_physical_fields(converter::SpectralToPhysicalConverter{T}, output_filename::String) where TSave converted physical space fields to NetCDF file using parallel I/O.
GeoDynamo.set_parameters! — Method
set_parameters!(params::GeoDynamoParameters; validate::Bool=true, strict::Bool=false)Set the global parameters (thread-safe) with optional validation.
Arguments
params::GeoDynamoParameters: Parameters to setvalidate::Bool=true: Whether to validate parameters before settingstrict::Bool=false: If true, throw error on invalid parameters; if false, proceed with warnings
GeoDynamo.set_shtnskit_threads — Method
set_shtnskit_threads(num_threads::Int)Configure the number of threads used by SHTnsKit transforms. Uses SHTnsKit.shtnsusethreads when available.
GeoDynamo.set_velocity_workspace! — Method
set_velocity_workspace!(ws::Union{VelocityWorkspace{T}, Nothing}) where TRegister a global VelocityWorkspace to be used by velocity kernels when available. Pass nothing to disable and fall back to internal buffers. Type-stable version that only accepts VelocityWorkspace or nothing.
GeoDynamo.setup_shtns_metadata! — Method
setup_shtns_metadata!(nc_file, shtns_config::SHTnsKitConfig, pencils::NamedTuple)Add SHTns-specific metadata to NetCDF file
GeoDynamo.shtnskit_analysis_inplace! — Method
shtnskit_analysis_inplace!(config::SHTnsKitConfig, f::Matrix{Float64},
alm_out::Matrix{ComplexF64})In-place physical-to-spectral analysis using SHTnsKit v1.1.15. Writes result directly to alm_out, avoiding allocation of temporary arrays.
Arguments
config: SHTnsKit configurationf: Input physical field (nlat × nlon)alm_out: Output spectral coefficients (lmax+1 × mmax+1), modified in-place
GeoDynamo.shtnskit_physical_to_spectral! — Method
shtnskit_physical_to_spectral!(phys, spec)Transform physical space values to spectral coefficients (analysis).
The Analysis Operation
Given physical field values f(θ,φ), compute spherical harmonic coefficients: fl^m = ∫∫ f(θ,φ) × Yl^m*(θ,φ) sin(θ) dθ dφ
The integral is computed numerically using:
- Gauss-Legendre quadrature for the θ integral
- FFT for the φ integral (exploiting periodicity)
Implementation
Uses SHTnsKit's analysis function which:
- Performs the FFT along longitude (extracting Fourier modes)
- Performs the Legendre transform (computing l coefficients for each m)
Arguments
phys::SHTnsPhysicalField: Source physical field valuesspec::SHTnsSpectralField: Destination spectral field (modified in-place)
Side Effects
Modifies spec.data_real and spec.data_imag with the computed coefficients
GeoDynamo.shtnskit_qst_to_spatial! — Method
shtnskit_qst_to_spatial!(config::SHTnsKitConfig, Qlm, Slm, Tlm, vr, vtheta, vphi)Convert QST spectral coefficients to full 3D spatial vector field using SHTnsKit v1.1.15.
This is more efficient than separate scalar + vector synthesis as it handles all three components in a single call.
Arguments
Qlm: Q (radial) spectral coefficientsSlm: S (spheroidal/poloidal) spectral coefficientsTlm: T (toroidal) spectral coefficientsvr,vtheta,vphi: Output spatial components (modified in-place)
GeoDynamo.shtnskit_spatial_to_qst! — Method
shtnskit_spatial_to_qst!(config::SHTnsKitConfig, vr, vtheta, vphi, Qlm, Slm, Tlm)Convert full 3D spatial vector field to QST spectral coefficients using SHTnsKit v1.1.15.
Arguments
vr,vtheta,vphi: Input spatial componentsQlm: Output Q (radial) spectral coefficients (modified in-place)Slm: Output S (spheroidal/poloidal) spectral coefficients (modified in-place)Tlm: Output T (toroidal) spectral coefficients (modified in-place)
GeoDynamo.shtnskit_spectral_to_physical! — Method
shtnskit_spectral_to_physical!(spec, phys)Transform spectral coefficients to physical space values (synthesis).
The Synthesis Operation
Given spherical harmonic coefficients fl^m, compute the physical field: f(θ,φ) = Σ{l,m} fl^m × Yl^m(θ,φ)
where Y_l^m are the spherical harmonics.
Implementation
Uses SHTnsKit's synthesis function which:
- Performs the Legendre transform (summing over l for each m)
- Performs the FFT along longitude (summing over m)
Arguments
spec::SHTnsSpectralField: Source spectral field with coefficientsphys::SHTnsPhysicalField: Destination physical field (modified in-place)
Side Effects
Modifies phys.data with the synthesized field values
GeoDynamo.shtnskit_synthesis_inplace! — Method
shtnskit_synthesis_inplace!(config::SHTnsKitConfig, alm::Matrix{ComplexF64},
f_out::Matrix{Float64})In-place spectral-to-physical synthesis using SHTnsKit v1.1.15. Writes result directly to f_out, avoiding allocation of temporary arrays.
Arguments
config: SHTnsKit configurationalm: Input spectral coefficients (lmax+1 × mmax+1)f_out: Output physical field (nlat × nlon), modified in-place
GeoDynamo.shtnskit_vector_analysis! — Method
shtnskit_vector_analysis!(vec_phys::SHTnsVectorField{T},
tor_spec::SHTnsSpectralField{T},
pol_spec::SHTnsSpectralField{T}) where TVector analysis using SHTnsKit with PencilArrays.
Toroidal-Poloidal Analysis
Decomposes a 3D velocity field into toroidal and poloidal scalars.
For a solenoidal vector field v (∇·v = 0): v = ∇×(T r̂) + ∇×∇×(P r̂)
Mathematical Note on Analysis
SHTnsKit.spattoSHsphtor takes (vθ, vφ) and returns (P, T).
This is mathematically valid for solenoidal fields because:
- The solenoidal constraint ∇·v = 0 couples vr to (vθ, v_φ)
- The decomposition into T (rotational) and P (potential) parts is unique
- The radial component v_r = l(l+1)/r * P is implicitly determined
However, this assumes EXACT solenoidality. In numerical simulations with finite precision, v_r may not exactly satisfy ∇·v = 0.
Alternative: Use Full 3-Component Analysis
For better numerical accuracy, one could use: Qcoeffs = analysis(vr * r / l(l+1)) # Recover P from vr S, T = spattoSHsphtor(vθ, v_φ) # Decompose tangential
Then check: Qcoeffs ≈ Scoeffs (should match for solenoidal field)
Current implementation uses 2-component analysis which is standard practice for solenoidal MHD simulations.
GeoDynamo.shtnskit_vector_synthesis! — Method
shtnskit_vector_synthesis!(tor_spec::SHTnsSpectralField{T},
pol_spec::SHTnsSpectralField{T},
vec_phys::SHTnsVectorField{T};
domain::Union{RadialDomain,Nothing}=nothing) where TVector synthesis using SHTnsKit spheroidal-toroidal decomposition with PencilArrays.
Toroidal-Poloidal Decomposition
For a solenoidal vector field v (∇·v = 0): v = ∇×(T r̂) + ∇×∇×(P r̂)
where T = toroidal scalar, P = poloidal scalar.
In spherical components: vr = l(l+1)/r * P * Ylm (from poloidal only) vθ, vφ from both T and P (computed by SHTnsKit.SHsphtortospat)
CRITICAL: SHTnsKit.SHsphtortospat returns ONLY tangential components. The radial component v_r MUST be computed separately from the poloidal scalar.
Parameters
domain: Optional RadialDomain needed for computing vr with correct radial scaling. If not provided, vr will be set to zero (suitable for tests).
GeoDynamo.spectral_gradient! — Method
spectral_gradient!(config::SHTnsKitConfig, Slm::Matrix{ComplexF64},
grad_theta::Matrix{Float64}, grad_phi::Matrix{Float64})Compute the horizontal gradient of a scalar field in spectral space. Uses SHTnsKit.SHtograd_spat for efficient computation.
Arguments
Slm: Spectral coefficients of the scalar fieldgrad_theta: Output θ-component of gradient (modified in-place)grad_phi: Output φ-component of gradient (modified in-place)
GeoDynamo.store_coefficients_from_shtnskit! — Method
store_coefficients_from_shtnskit!(spec_real, spec_imag, coeffs_matrix, r_local, config)Convert SHTnsKit coefficient matrix format back to our linear spectral storage.
This is the inverse of extract_coefficients_for_shtnskit!:
- Input: SHTnsKit's (lmax+1) × (mmax+1) coefficient matrix
- Output: Our linear-indexed spectral arrays (real and imaginary parts separate)
Physical Constraint
For real-valued physical fields, the m=0 coefficients must be purely real. This function enforces this by zeroing the imaginary part for m=0 modes.
GeoDynamo.store_physical_slice_generic! — Method
store_physical_slice_generic!(phys_data, phys_slice, r_local, config)Generic storage for any pencil orientation.
GeoDynamo.store_physical_slice_phi_local! — Method
store_physical_slice_phi_local!(phys_data, phys_slice, r_local, config)Copy a 2D physical field slice into a 3D array at a specific radial level.
Optimized for Phi-Local Layout
When the physical field is in phi-pencil orientation, the (θ, φ) indices correspond directly to the array's first two dimensions, making this a straightforward copy operation.
Arguments
phys_data: 3D destination array (θ × φ × r)phys_slice: 2D source array from SHTnsKit (θ × φ)r_local: Radial index to write toconfig: Configuration for grid dimensions
GeoDynamo.store_scalar_component_generic! — Method
store_scalar_component_generic!(v_component, field, r_local, config)Store a scalar field into a component array for any pencil orientation. Used for storing the radial component v_r from synthesized field.
GeoDynamo.store_vector_components_generic! — Method
store_vector_components_generic!(v_theta, v_phi, vt_field, vp_field, r_local, config)Store vector components for any pencil orientation.
GeoDynamo.store_zero_component_generic! — Method
store_zero_component_generic!(v_component, r_local, config)Set a component to zero at a given radial level. Used at r=0 (ball geometry) where v_r must be zero for regularity.
GeoDynamo.synchronize_halos! — Method
synchronize_halos!(arr::PencilArray; halo_width::Int=1, boundaries::Symbol=:all)Synchronize ghost/halo regions for parallel finite difference computations.
Parameters
arr: PencilArray to synchronizehalo_width: Width of halo region (number of ghost cells), default 1boundaries: Boundary handling (:all, :periodic, :nonperiodic), default :all
Notes
This function implements MPI point-to-point communication to exchange boundary data between neighboring processes in each decomposed dimension. It's essential for maintaining accuracy in finite difference stencil operations near subdomain boundaries.
For spectral methods, explicit halo exchange may not be needed as the global nature of spectral transforms handles boundary coupling through transpose operations.
GeoDynamo.synchronize_pencil_data! — Method
synchronize_pencil_data!(field)Synchronize PencilArray data across MPI processes to ensure consistency.
GeoDynamo.synchronize_pencil_transforms! — Method
synchronize_pencil_transforms!(field::SHTnsSpectralField{T}) where TEnsure all pending PencilFFTs operations are completed and data is consistent across processes.
GeoDynamo.test_halo_exchange — Method
test_halo_exchange(pencil::Pencil, ::Type{T}=Float64; halo_width::Int=1, verbose::Bool=true) where TTest halo exchange functionality by creating a test array with rank-based values. Returns true if halo exchange is working correctly.
Example
pencils = create_pencil_topology(shtns_config)
test_halo_exchange(pencils.θ, Float64; halo_width=1, verbose=true)GeoDynamo.transform_field_and_gradients_to_physical! — Method
transform_field_and_gradients_to_physical!(field::AbstractScalarField{T}) where TTransform scalar field and all gradient components to physical space in a single batched operation to minimize communication.
GeoDynamo.transpose_with_timer! — Function
transpose_with_timer!(dest, src, plan, label="")Perform transpose with optional timing and statistics.
GeoDynamo.truncate_spectral_modes! — Function
truncate_spectral_modes!(config::SHTnsKitConfig, alm::Matrix{ComplexF64},
lmax_new::Int, mmax_new::Int=lmax_new;
alm_out::Union{Matrix{ComplexF64},Nothing}=nothing)Truncate spectral coefficients to a lower resolution. Sets all modes with l > lmaxnew or m > mmaxnew to zero.
Arguments
config: SHTnsKit configurationalm: Input spectral coefficientslmax_new: New maximum degreemmax_new: New maximum order (default = lmax_new)alm_out: Optional output array
GeoDynamo.update_derived_parameters! — Method
update_derived_parameters!(params::GeoDynamoParameters)Update derived parameters based on primary parameters.
GeoDynamo.update_global_parameters! — Method
update_global_parameters!()Update all global parameter variables with values from the current parameter struct.
GeoDynamo.validate_magnetic_configuration — Method
validate_magnetic_configuration(mag_fields::SHTnsMagneticFields{T}, config::SHTnsKitConfig) where TValidate magnetic field configuration consistency with SHTns setup
GeoDynamo.validate_mpi_consistency! — Method
validate_mpi_consistency!(field::SHTnsSpectralField{T}) where TCheck that spectral field data is consistent across MPI processes after time stepping.
GeoDynamo.validate_output_compatibility — Method
validate_output_compatibility(field_info::FieldInfo, shtns_config::SHTnsKitConfig)Validate that output field information is compatible with SHTns configuration
GeoDynamo.validate_parameters — Method
validate_parameters(params::GeoDynamoParameters; strict::Bool=false)Validate all simulation parameters for physical correctness and numerical stability.
Arguments
params::GeoDynamoParameters: Parameters to validatestrict::Bool=false: If true, throw errors on invalid params; if false, issue warnings
Returns
(is_valid::Bool, errors::Vector{String}, warnings::Vector{String})
GeoDynamo.validate_pencil_decomposition — Method
validate_pencil_decomposition(config::SHTnsKitConfig)Validate that pencil decomposition is optimal for the problem size and MPI configuration.
GeoDynamo.validate_stress_free_boundary — Method
validate_stress_free_boundary(v_r, v_theta, v_phi, r_val, theta, phi; tolerance=0.05)Validate that velocity field satisfies stress-free boundary condition.
For stress-free boundaries with vr = 0, the condition is: ∂vθ/∂r - vθ/r = 0 (zero tangential stress in θ direction) ∂vφ/∂r - v_φ/r = 0 (zero tangential stress in φ direction)
Arguments
v_r, v_theta, v_phi: Velocity components at boundary [nlat, nlon]r_val: Radial position of boundarytheta, phi: Coordinate arraystolerance: Maximum allowed |stress| / |v|
Returns
is_valid: Boolean indicating if condition is satisfiedmax_violation: Maximum relative stress violation
GeoDynamo.validate_velocity_configuration — Method
validate_velocity_configuration(fields::SHTnsVelocityFields{T}, config::SHTnsKitConfig) where TValidate velocity field configuration consistency with SHTns setup
GeoDynamo.verify_all_ranks_wrote — Method
verify_all_ranks_wrote(output_dir::String, hist_number::Int, nprocs::Int;
file_type::String="hist", geometry::String="shell")Verify that all MPI ranks wrote their output files for a given history number.
Returns a tuple (success::Bool, missingranks::Vector{Int}, fileinfo::Dict)
GeoDynamo.write_enhanced_coordinates! — Method
write_enhanced_coordinates!(nc_file, field_info::FieldInfo, config::OutputConfig)Write coordinates with enhanced precision and metadata from SHTns config
GeoDynamo.write_grid_file! — Method
write_grid_file!(config::OutputConfig, field_info::FieldInfo,
shtns_config::Union{SHTnsKitConfig,Nothing},
metadata::Dict{String,Any})Write a separate grid file containing all coordinate and grid information. This is written only once by rank 0 at the start of the simulation.
GeoDynamo.write_single_spectral_component! — Method
write_single_spectral_component!(nc_file, component, field_data, config)Write a single spectral component with enhanced memory handling
GeoDynamo.write_spectral_data_parallel! — Method
write_spectral_data_parallel!(nc_file, real_name, imag_name, real_data, imag_data, field_info)Write spectral data using parallel I/O strategies based on pencil decomposition
GeoDynamo.zero_scalar_work_arrays! — Method
zero_scalar_work_arrays!(field::AbstractScalarField{T}) where TEfficiently zero all work arrays for a scalar field.
Boundary Conditions
GeoDynamo.BoundaryConditions.AbstractBoundaryCondition — Type
AbstractBoundaryCondition{T}Abstract base type for all boundary conditions.
GeoDynamo.BoundaryConditions.BoundaryCache — Type
BoundaryCache{T}Cache structure for storing processed boundary data.
GeoDynamo.BoundaryConditions.BoundaryConditionSet — Type
BoundaryConditionSet{T}Complete set of boundary conditions for inner and outer boundaries.
GeoDynamo.BoundaryConditions.BoundaryData — Type
BoundaryData{T}Common data structure for boundary condition data from any source.
GeoDynamo.BoundaryConditions.BoundaryLocation — Type
BoundaryLocationEnumeration for boundary locations.
GeoDynamo.BoundaryConditions.BoundaryType — Type
BoundaryTypeEnumeration for boundary condition types.
GeoDynamo.BoundaryConditions.FieldType — Type
FieldTypeEnumeration for different physical field types.
GeoDynamo.BoundaryConditions._get_cached_bc_shtns_config — Method
_get_cached_bc_shtns_config(lmax, mmax, nlat, nlon)Get or create a cached SHTnsKit configuration for boundary transforms. Reuses configurations to avoid repeated setup/teardown overhead.
GeoDynamo.BoundaryConditions.add_noise_to_boundary — Function
add_noise_to_boundary(boundary_data::BoundaryData, noise_amplitude::Real,
noise_type::Symbol=:gaussian)Add noise to existing boundary data.
GeoDynamo.BoundaryConditions.apply_boundary_conditions! — Method
apply_boundary_conditions!(field, field_type::FieldType, solver_state)Apply boundary conditions during solver operations.
This function integrates boundary conditions with the timestepping and solving process.
GeoDynamo.BoundaryConditions.apply_boundary_conditions_to_rhs! — Method
apply_boundary_conditions_to_rhs!(rhs, state, field_type::FieldType)Apply boundary conditions to right-hand side during timestepping.
This function modifies the RHS vector to enforce boundary conditions during implicit and explicit timestepping methods.
GeoDynamo.BoundaryConditions.apply_composition_bc_to_rhs! — Method
apply_composition_bc_to_rhs!(rhs, comp_field)Apply composition boundary conditions to RHS vector.
GeoDynamo.BoundaryConditions.apply_composition_boundaries! — Method
apply_composition_boundaries!(comp_field, boundary_set::BoundaryConditionSet; time::Float64=0.0)Apply composition boundary conditions from a BoundaryConditionSet to a composition field. This is a convenience wrapper that loads the boundary set and applies it.
GeoDynamo.BoundaryConditions.apply_composition_boundary_conditions! — Function
apply_composition_boundary_conditions!(comp_field, time_index::Int=1)Apply composition boundary conditions to the field.
GeoDynamo.BoundaryConditions.apply_gaussian_smoothing! — Method
apply_gaussian_smoothing!(data::AbstractMatrix, theta::Vector, phi::Vector, radius::Real)Apply Gaussian smoothing kernel to 2D data array.
GeoDynamo.BoundaryConditions.apply_magnetic_bc_to_rhs! — Method
apply_magnetic_bc_to_rhs!(rhs, magnetic_field)Apply magnetic field boundary conditions to RHS vector.
GeoDynamo.BoundaryConditions.apply_magnetic_boundary_conditions! — Function
apply_magnetic_boundary_conditions!(magnetic_field, time_index::Int=1)Apply magnetic field boundary conditions to the field.
GeoDynamo.BoundaryConditions.apply_temperature_bc_to_rhs! — Method
apply_temperature_bc_to_rhs!(rhs, temp_field)Apply temperature boundary conditions to RHS vector.
GeoDynamo.BoundaryConditions.apply_temperature_boundaries! — Method
apply_temperature_boundaries!(temp_field, boundary_set::BoundaryConditionSet; time::Float64=0.0)Apply temperature boundary conditions from a BoundaryConditionSet to a temperature field. This is a convenience wrapper that loads the boundary set and applies it.
GeoDynamo.BoundaryConditions.apply_temperature_boundary_conditions! — Function
apply_temperature_boundary_conditions!(temp_field, time_index::Int=1)Apply temperature boundary conditions to the field.
GeoDynamo.BoundaryConditions.apply_velocity_bc_to_rhs! — Method
apply_velocity_bc_to_rhs!(rhs, velocity_field)Apply velocity boundary conditions to RHS vector.
GeoDynamo.BoundaryConditions.apply_velocity_boundary_conditions! — Function
apply_velocity_boundary_conditions!(velocity_field, time_index::Int=1)Apply velocity boundary conditions to the field.
GeoDynamo.BoundaryConditions.bilinear_interpolate — Method
bilinear_interpolate(data::Matrix{T}, theta_idx::Tuple{Int, Int}, phi_idx::Tuple{Int, Int},
theta_weights::Tuple{T, T}, phi_weights::Tuple{T, T}) where TPerform bilinear interpolation on a 2D data array. Handles periodic boundary conditions in phi direction.
GeoDynamo.BoundaryConditions.cache_boundary_data! — Method
cache_boundary_data!(cache::BoundaryCache{T}, key::String, data::Array{T}) where TCache processed boundary data.
GeoDynamo.BoundaryConditions.calculate_potential_field_boundary — Method
calculate_potential_field_boundary(coeffs::Dict, theta::Vector, phi::Vector, lmax::Int)Calculate magnetic field from spherical harmonic coefficients of the potential.
GeoDynamo.BoundaryConditions.check_interpolation_bounds — Method
check_interpolation_bounds(boundary_data::BoundaryData, target_theta::Vector{T},
target_phi::Vector{T}) where TCheck if target grid is within the bounds of the source grid and warn if extrapolation is needed.
GeoDynamo.BoundaryConditions.clear_bc_shtns_config_cache! — Method
clear_bc_shtns_config_cache!()Clear the cached SHTnsKit configurations for boundary transforms. Call this when grid parameters change or to free memory.
GeoDynamo.BoundaryConditions.clear_boundary_cache! — Method
clear_boundary_cache!(cache::BoundaryCache)Clear all cached boundary data.
GeoDynamo.BoundaryConditions.combine_programmatic_patterns — Method
combine_programmatic_patterns(patterns::Vector{Tuple{Symbol, Real}}, config;
parameters::Vector{Dict}=Dict[], description::String="")Combine multiple programmatic patterns with different amplitudes.
GeoDynamo.BoundaryConditions.compute_boundary_condition_residual — Method
compute_boundary_condition_residual(field, field_type::FieldType)Compute residual to check how well boundary conditions are satisfied.
Returns a measure of how much the current field violates the boundary conditions. Useful for monitoring solution quality and debugging.
GeoDynamo.BoundaryConditions.compute_radial_curl_component — Method
compute_radial_curl_component(B_r, B_theta, B_phi, theta, phi)Compute the radial component of ∇×B to verify insulating boundary conditions.
For insulating boundaries, (∇×B)r should be zero. In spherical coordinates: (∇×B)r = (1/(r sin θ))[∂(Bφ sin θ)/∂θ - ∂Bθ/∂φ]
Arguments
B_r, B_theta, B_phi: Magnetic field components on boundary [nlat, nlon]theta, phi: Coordinate arrays
Returns
curl_r: Radial component of curl [nlat, nlon]max_curl: Maximum absolute value of (∇×B)_r
GeoDynamo.BoundaryConditions.copy_boundary_conditions! — Method
copy_boundary_conditions!(dest_field, src_field, field_type::FieldType)Copy boundary conditions from one field to another.
GeoDynamo.BoundaryConditions.create_boundary_data — Method
create_boundary_data(values::Array{T}, field_type::String;
theta=nothing, phi=nothing, time=nothing,
units="", description="", file_path="programmatic") where TCreate a BoundaryData structure from raw data.
GeoDynamo.BoundaryConditions.create_composition_interpolation_cache — Method
create_composition_interpolation_cache(boundary_set::BoundaryConditionSet, config)Create interpolation cache for composition boundaries.
GeoDynamo.BoundaryConditions.create_hybrid_composition_boundaries — Method
create_hybrid_composition_boundaries(file_spec::String, prog_spec::Tuple, config; swap_boundaries=false)Create hybrid composition boundaries (one from file, one programmatic).
GeoDynamo.BoundaryConditions.create_hybrid_magnetic_boundaries — Method
create_hybrid_magnetic_boundaries(file_spec::String, prog_spec::Tuple, config; swap_boundaries=false)Create hybrid magnetic boundaries (one from file, one programmatic).
GeoDynamo.BoundaryConditions.create_hybrid_temperature_boundaries — Method
create_hybrid_temperature_boundaries(file_spec::String, prog_spec::Tuple, config; swap_boundaries=false)Create hybrid temperature boundaries (one from file, one programmatic).
GeoDynamo.BoundaryConditions.create_hybrid_velocity_boundaries — Method
create_hybrid_velocity_boundaries(file_spec::String, prog_spec::Tuple, config; swap_boundaries=false)Create hybrid velocity boundaries (one from file, one programmatic).
GeoDynamo.BoundaryConditions.create_interpolation_cache — Method
create_interpolation_cache(boundary_data::BoundaryData, target_theta::Vector{T},
target_phi::Vector{T}) where TCreate interpolation cache for efficient repeated interpolations.
GeoDynamo.BoundaryConditions.create_layered_composition_boundary — Method
create_layered_composition_boundary(config, layer_specs::Vector{Tuple{Real, Real, Real}})Create layered composition boundary conditions.
Arguments
layer_specs: Vector of (colatitudestart, colatitudeend, composition) tuples
Example
# Create three-layer composition structure
layer_specs = [
(0.0, π/3, 0.8), # High composition in top layer
(π/3, 2π/3, 0.4), # Medium composition in middle layer
(2π/3, π, 0.1) # Low composition in bottom layer
]GeoDynamo.BoundaryConditions.create_layered_temperature_boundary — Method
create_layered_temperature_boundary(config, layer_specs::Vector{Tuple{Real, Real, Real}})Create layered temperature boundary conditions.
Arguments
layer_specs: Vector of (colatitudestart, colatitudeend, temperature) tuples
Example
# Create three-layer temperature structure
layer_specs = [
(0.0, π/3, 1000.0), # High temperature in top layer
(π/3, 2π/3, 500.0), # Medium temperature in middle layer
(2π/3, π, 100.0) # Low temperature in bottom layer
]GeoDynamo.BoundaryConditions.create_magnetic_interpolation_cache — Method
create_magnetic_interpolation_cache(boundary_set::BoundaryConditionSet, config)Create interpolation cache for magnetic boundaries.
GeoDynamo.BoundaryConditions.create_programmatic_boundary — Function
create_programmatic_boundary(pattern::Symbol, config, amplitude::Real=1.0;
parameters::Dict=Dict(), description::String="")Create programmatically generated boundary conditions.
Available patterns:
:uniform- Uniform value:y11- Y₁₁ spherical harmonic:plume- Gaussian plume pattern:hemisphere- Hemispherical pattern:dipole- Dipolar pattern (Y₁₀):quadrupole- Quadrupolar pattern:custom- User-defined function
GeoDynamo.BoundaryConditions.create_programmatic_composition_boundaries — Method
create_programmatic_composition_boundaries(inner_spec::Tuple, outer_spec::Tuple, config)Create fully programmatic composition boundaries.
GeoDynamo.BoundaryConditions.create_programmatic_magnetic_boundaries — Method
create_programmatic_magnetic_boundaries(inner_spec::Tuple, outer_spec::Tuple, config)Create fully programmatic magnetic boundaries.
GeoDynamo.BoundaryConditions.create_programmatic_magnetic_boundary — Function
create_programmatic_magnetic_boundary(pattern::Symbol, config, amplitude::Real=1.0;
parameters::Dict=Dict())Create programmatically generated magnetic boundary conditions.
Available patterns:
:insulating- Insulating boundary (Br = 0, ∂Btan/∂r = 0):perfect_conductor- Perfect conductor (B_tan = 0):dipole- Dipolar magnetic field pattern:quadrupole- Quadrupolar magnetic field pattern:potential_field- Potential field from spherical harmonic coefficients:uniform_field- Uniform magnetic field:custom- User-defined magnetic field function
GeoDynamo.BoundaryConditions.create_programmatic_temperature_boundaries — Method
create_programmatic_temperature_boundaries(inner_spec::Tuple, outer_spec::Tuple, config)Create fully programmatic temperature boundaries.
GeoDynamo.BoundaryConditions.create_programmatic_velocity_boundaries — Method
create_programmatic_velocity_boundaries(inner_spec::Tuple, outer_spec::Tuple, config)Create fully programmatic velocity boundaries.
GeoDynamo.BoundaryConditions.create_programmatic_velocity_boundary — Function
create_programmatic_velocity_boundary(pattern::Symbol, config, amplitude::Real=1.0;
parameters::Dict=Dict())Create programmatically generated velocity boundary conditions.
Available patterns:
:no_slip- Zero velocity at boundary (amplitude ignored):stress_free- Zero stress at boundary (amplitude ignored):uniform_rotation- Uniform rotation with angular velocity amplitude:differential_rotation- Differential rotation pattern:zonal_flow- Zonal (east-west) flow pattern:meridional_flow- Meridional (north-south) flow pattern:custom- User-defined velocity function
GeoDynamo.BoundaryConditions.create_temperature_interpolation_cache — Method
create_temperature_interpolation_cache(boundary_set::BoundaryConditionSet, config)Create interpolation cache for temperature boundaries.
GeoDynamo.BoundaryConditions.create_time_dependent_programmatic_boundary — Method
create_time_dependent_programmatic_boundary(pattern::Symbol, config, time_span::Tuple{Real, Real},
ntime::Int; amplitude::Real=1.0,
parameters::Dict=Dict(), description::String="",
field_type::String="temperature")Create time-dependent programmatically generated boundary conditions.
GeoDynamo.BoundaryConditions.create_velocity_interpolation_cache — Method
create_velocity_interpolation_cache(boundary_set::BoundaryConditionSet, config)Create interpolation cache for velocity boundaries.
GeoDynamo.BoundaryConditions.determine_field_type_from_name — Method
determine_field_type_from_name(field_name::String) -> FieldTypeDetermine field type from field name string.
GeoDynamo.BoundaryConditions.enforce_boundary_conditions_in_solution! — Method
enforce_boundary_conditions_in_solution!(solution, state, field_type::FieldType)Enforce boundary conditions in the solution vector after timestepping.
This function ensures that the solution satisfies the boundary conditions after each timestep, which may be necessary for certain discretization schemes.
GeoDynamo.BoundaryConditions.enforce_composition_bc_in_solution! — Method
enforce_composition_bc_in_solution!(solution, comp_field)Enforce composition boundary conditions in solution vector.
GeoDynamo.BoundaryConditions.enforce_composition_boundary_constraints! — Method
enforce_composition_boundary_constraints!(comp_field, bc_spec::Dict)Enforce specific composition boundary constraints based on user specification.
Arguments
comp_field: Composition field structurebc_spec: Dictionary specifying boundary condition types
BC Specification Format
bc_spec = Dict(
:inner => :dirichlet, # or :neumann, :flux
:outer => :dirichlet, # or :neumann, :flux
:inner_value => 1.0, # for Dirichlet (0.0-1.0)
:outer_value => 0.0, # for Dirichlet (0.0-1.0)
:inner_flux => 0.01, # for Neumann (∂C/∂r)
:outer_flux => 0.0 # for Neumann (∂C/∂r)
)Boundary Condition Types
:dirichlet- Fixed composition: C = C₀ at boundary:neumannor:flux- Fixed compositional flux: ∂C/∂r = q at boundary
Physical Interpretation
Dirichlet (Fixed C): Typical for prescribed composition boundaries
- Inner (ICB): Fixed light element concentration at inner core
- Outer (CMB): Fixed composition at core-mantle boundary
Neumann (Fixed flux): Typical for compositional flux boundaries
- Inner: Compositional release/freezing (∂C/∂r = q)
- Outer: Zero flux (no exchange, ∂C/∂r = 0)
Examples
# Fixed composition at both boundaries
enforce_composition_boundary_constraints!(comp_field, Dict(
:inner => :dirichlet, :inner_value => 1.0,
:outer => :dirichlet, :outer_value => 0.0
))
# Compositional release from below, sealed top
enforce_composition_boundary_constraints!(comp_field, Dict(
:inner => :flux, :inner_flux => 0.01,
:outer => :flux, :outer_flux => 0.0
))GeoDynamo.BoundaryConditions.enforce_magnetic_bc_in_solution! — Method
enforce_magnetic_bc_in_solution!(solution, magnetic_field)Enforce magnetic field boundary conditions in solution vector.
GeoDynamo.BoundaryConditions.enforce_magnetic_boundary_constraints! — Method
enforce_magnetic_boundary_constraints!(magnetic_field, bc_type::Symbol)Enforce magnetic boundary condition constraints based on magnetohydrodynamic physics.
Boundary condition types:
:insulating- Insulating boundary (σ = 0): No normal current (J_n = 0)- Physical interpretation: (∇×B)r = μ₀Jr = 0 at boundary
- Implementation: Potential field matching (B continuous, tangential current-free)
- Spectral: Typically Dirichlet BC for both components matching external potential
:perfect_conductor- Perfect conductor (σ → ∞): Zero tangential magnetic field- Physical interpretation: Btangential = 0, Br free (from ∇·B = 0)
- Implementation: Tangential components zero, radial component determined by matching
- Spectral: Toroidal (T) = 0 Dirichlet, Poloidal (Q) matches
:potential_field- General potential field matching- Implementation: Match external potential field at boundary
- Spectral: Dirichlet BC for both toroidal and poloidal components
Notes:
For most geodynamo applications:
- Inner boundary (ICB): Often insulating or potential field
- Outer boundary (CMB): Often insulating (matching Earth's mantle)
GeoDynamo.BoundaryConditions.enforce_temperature_bc_in_solution! — Method
enforce_temperature_bc_in_solution!(solution, temp_field)Enforce temperature boundary conditions in solution vector.
GeoDynamo.BoundaryConditions.enforce_temperature_boundary_constraints! — Method
enforce_temperature_boundary_constraints!(temp_field, bc_spec::Dict)Enforce specific temperature boundary constraints based on user specification.
Arguments
temp_field: Temperature field structurebc_spec: Dictionary specifying boundary condition types
BC Specification Format
bc_spec = Dict(
:inner => :dirichlet, # or :neumann, :flux
:outer => :dirichlet, # or :neumann, :flux
:inner_value => 1000.0, # for Dirichlet
:outer_value => 300.0, # for Dirichlet
:inner_flux => 0.1, # for Neumann (∂T/∂r)
:outer_flux => 0.0 # for Neumann (∂T/∂r)
)Boundary Condition Types
:dirichlet- Fixed temperature: T = T₀ at boundary:neumannor:flux- Fixed heat flux: ∂T/∂r = q at boundary:mixed- Mixed/Robin: α T + β ∂T/∂r = γ (future)
Physical Interpretation
Dirichlet (Fixed T): Typical for prescribed temperature boundaries
- Inner (CMB): Fixed temperature from core evolution
- Outer (surface): Fixed temperature from atmospheric coupling
Neumann (Fixed flux): Typical for heat flux boundaries
- Inner: Uniform heating from below (∂T/∂r = q)
- Outer: Zero flux (insulated, ∂T/∂r = 0)
Examples
# Fixed temperature at both boundaries
enforce_temperature_boundary_constraints!(temp_field, Dict(
:inner => :dirichlet, :inner_value => 1000.0,
:outer => :dirichlet, :outer_value => 300.0
))
# Uniform heating from below, insulated top
enforce_temperature_boundary_constraints!(temp_field, Dict(
:inner => :flux, :inner_flux => 0.1,
:outer => :flux, :outer_flux => 0.0
))GeoDynamo.BoundaryConditions.enforce_velocity_bc_in_solution! — Method
enforce_velocity_bc_in_solution!(solution, velocity_field)Enforce velocity boundary conditions in solution vector.
GeoDynamo.BoundaryConditions.enforce_velocity_boundary_constraints! — Function
enforce_velocity_boundary_constraints!(velocity_field, bc_type::Symbol=:no_slip)Enforce specific velocity boundary constraints based on boundary condition type.
NOTE: This function is for programmatically setting boundary constraints. For boundary conditions loaded from files or other sources, use loadvelocityboundary_conditions!() instead.
Arguments
velocity_field: Velocity field structure with toroidal and poloidal componentsbc_type: Type of boundary condition (:noslip, :stressfree, :impermeable)
Boundary Condition Mapping (for solenoidal/incompressible flows):
- No-slip: vr = vθ = v_φ = 0 → Q = T = 0 at boundaries (Dirichlet)
- Stress-free: v_r = 0 (Dirichlet), tangential stress = 0 → Q = 0 (Dirichlet), ∂T/∂r = 0 (Neumann)
- Impermeable: v_r = 0 → Q = 0 at boundaries (Dirichlet), T unconstrained
Field naming convention:
- velocity_field.poloidal actually stores Q (radial component)
- velocity_field.toroidal actually stores T (tangential toroidal component)
- S component (spheroidal) is zero for solenoidal flows
GeoDynamo.BoundaryConditions.estimate_interpolation_error — Method
estimate_interpolation_error(boundary_data::BoundaryData, target_theta::Vector{T},
target_phi::Vector{T}) where TEstimate interpolation error based on grid resolution differences.
GeoDynamo.BoundaryConditions.find_composition_boundary_time_index — Method
find_composition_boundary_time_index(boundary_set::BoundaryConditionSet, current_time::Float64)Find the appropriate time index for the current simulation time.
GeoDynamo.BoundaryConditions.find_grid_indices — Method
find_grid_indices(coords::Vector{T}, target::T; is_periodic::Bool=false) where TFind the two surrounding indices in a coordinate array for interpolation. Handles periodic coordinates (e.g., longitude) if is_periodic=true.
GeoDynamo.BoundaryConditions.find_temperature_boundary_time_index — Method
find_temperature_boundary_time_index(boundary_set::BoundaryConditionSet, current_time::Float64)Find the appropriate time index for the current simulation time.
GeoDynamo.BoundaryConditions.get_boundary_condition_summary — Method
get_boundary_condition_summary(field, field_type::FieldType)Get a summary of the current boundary condition state.
GeoDynamo.BoundaryConditions.get_boundary_data — Method
get_boundary_data(field, field_type::FieldType)Get boundary data from field using unified interface with fallback support.
GeoDynamo.BoundaryConditions.get_boundary_statistics — Method
get_boundary_statistics(boundary_data::BoundaryData)Get statistical information about boundary data.
GeoDynamo.BoundaryConditions.get_cached_data — Method
get_cached_data(cache::BoundaryCache{T}, key::String) where TRetrieve cached boundary data.
GeoDynamo.BoundaryConditions.get_comm — Method
get_comm()Get MPI communicator (with fallback).
GeoDynamo.BoundaryConditions.get_composition_boundary_data — Method
get_composition_boundary_data(comp_field)Get boundary data from field or fallback cache.
GeoDynamo.BoundaryConditions.get_composition_time_index — Method
get_composition_time_index(comp_field)Get current time index from field or fallback cache.
GeoDynamo.BoundaryConditions.get_current_boundaries — Method
get_current_boundaries(field, field_type::FieldType)Get current boundary values for any field type.
GeoDynamo.BoundaryConditions.get_current_composition_boundaries — Method
get_current_composition_boundaries(comp_field)Get current composition boundary conditions.
GeoDynamo.BoundaryConditions.get_current_magnetic_boundaries — Method
get_current_magnetic_boundaries(magnetic_field)Get current magnetic field boundary conditions.
GeoDynamo.BoundaryConditions.get_current_simulation_time — Method
get_current_simulation_time(solver_state)Extract current simulation time from solver state.
GeoDynamo.BoundaryConditions.get_current_temperature_boundaries — Method
get_current_temperature_boundaries(temp_field)Get current temperature boundary conditions.
GeoDynamo.BoundaryConditions.get_current_velocity_boundaries — Method
get_current_velocity_boundaries(velocity_field)Get current velocity boundary conditions.
GeoDynamo.BoundaryConditions.get_default_boundary_type — Method
get_default_boundary_type(field_type::FieldType, location::BoundaryLocation) -> BoundaryTypeGet default boundary condition type for a field at a specific location.
GeoDynamo.BoundaryConditions.get_default_units — Method
get_default_units(field_type::FieldType) -> StringGet default units for a field type.
GeoDynamo.BoundaryConditions.get_field_from_state — Method
get_field_from_state(state, field_type::FieldType)Extract the appropriate field from simulation state.
GeoDynamo.BoundaryConditions.get_interpolation_statistics — Method
get_interpolation_statistics(boundary_data::BoundaryData, interpolated_data::Array{T}) where TCompute statistics comparing original and interpolated data.
GeoDynamo.BoundaryConditions.get_interpolation_weights — Method
get_interpolation_weights(coords::Vector{T}, target::T, indices::Tuple{Int, Int}) where TCalculate interpolation weights for linear interpolation.
GeoDynamo.BoundaryConditions.get_magnetic_boundary_data — Method
get_magnetic_boundary_data(magnetic_field)Return (boundary_set, cache) for the magnetic field, falling back to a module-level cache when the field struct lacks boundary storage.
GeoDynamo.BoundaryConditions.get_magnetic_time_index — Method
get_magnetic_time_index(magnetic_field)Fetch the currently active boundary time index, honoring legacy cache storage.
GeoDynamo.BoundaryConditions.get_netcdf_file_info — Method
get_netcdf_file_info(filename::String)Get information about a NetCDF boundary condition file.
GeoDynamo.BoundaryConditions.get_nprocs — Method
get_nprocs()Get number of MPI processes (with fallback).
GeoDynamo.BoundaryConditions.get_rank — Method
get_rank()Get MPI rank (with fallback).
GeoDynamo.BoundaryConditions.get_temperature_boundary_data — Method
get_temperature_boundary_data(temp_field)Get boundary data from field or fallback cache.
GeoDynamo.BoundaryConditions.get_temperature_time_index — Method
get_temperature_time_index(temp_field)Get current time index from field or fallback cache.
GeoDynamo.BoundaryConditions.get_time_index — Method
get_time_index(field, field_type::FieldType)Get current time index from field using unified interface with fallback support.
GeoDynamo.BoundaryConditions.get_velocity_boundary_data — Method
get_velocity_boundary_data(velocity_field)Return (boundary_set, cache) for the provided velocity field, falling back to module-level storage when the struct does not carry boundary metadata.
GeoDynamo.BoundaryConditions.get_velocity_time_index — Method
get_velocity_time_index(velocity_field)Fetch the current boundary time index for a velocity field, honoring fallback storage.
GeoDynamo.BoundaryConditions.infer_composition_bc_type — Method
infer_composition_bc_type(boundary::BoundaryData)Infer boundary condition type (Dirichlet or Neumann) from boundary metadata.
Checks the description field for keywords:
- "flux", "neumann" → NEUMANN (∂C/∂r specified)
- Otherwise → DIRICHLET (C specified)
GeoDynamo.BoundaryConditions.infer_temperature_bc_type — Method
infer_temperature_bc_type(boundary::BoundaryData)Infer boundary condition type (Dirichlet or Neumann) from boundary metadata.
Checks the description field for keywords:
- "flux", "neumann", "heat flux" → NEUMANN (∂T/∂r specified)
- Otherwise → DIRICHLET (T specified)
GeoDynamo.BoundaryConditions.infer_velocity_bc_type — Method
infer_velocity_bc_type(boundary::BoundaryData)Infer boundary condition type (Dirichlet or Neumann) from boundary metadata.
GeoDynamo.BoundaryConditions.initialize_boundary_conditions! — Method
initialize_boundary_conditions!(field, field_type::FieldType, config)Initialize boundary condition support for a field structure.
Adds the necessary boundary condition fields to existing field structures without breaking compatibility with existing code.
GeoDynamo.BoundaryConditions.interpolate_boundary_to_grid — Method
interpolate_boundary_to_grid(boundary_data::BoundaryData, target_theta::Vector{T},
target_phi::Vector{T}, time_index::Int=1) where TInterpolate boundary data to a target grid using bilinear interpolation.
GeoDynamo.BoundaryConditions.interpolate_with_cache — Function
interpolate_with_cache(boundary_data::BoundaryData, cache::Dict, time_index::Int=1)Perform interpolation using pre-computed cache for efficiency.
GeoDynamo.BoundaryConditions.load_composition_boundaries_from_files — Method
load_composition_boundaries_from_files(inner_file::String, outer_file::String, config)Load composition boundary conditions from NetCDF files.
GeoDynamo.BoundaryConditions.load_composition_boundary_conditions! — Method
load_composition_boundary_conditions!(comp_field, boundary_specs::Dict)Load composition boundary conditions from various sources.
Arguments
comp_field: SHTnsCompositionField structureboundary_specs: Dictionary specifying boundary sources
Examples
# NetCDF files for both boundaries
boundary_specs = Dict(
:inner => "cmb_composition.nc",
:outer => "surface_composition.nc"
)
# Mixed NetCDF and programmatic
boundary_specs = Dict(
:inner => "cmb_composition.nc",
:outer => (:uniform, 0.1) # 10% concentration
)GeoDynamo.BoundaryConditions.load_magnetic_boundaries_from_files — Method
load_magnetic_boundaries_from_files(inner_file::String, outer_file::String, config)Load magnetic field boundary conditions from NetCDF files.
GeoDynamo.BoundaryConditions.load_magnetic_boundary_conditions! — Method
load_magnetic_boundary_conditions!(magnetic_field, boundary_specs::Dict)Load magnetic field boundary conditions from various sources.
Arguments
magnetic_field: SHTnsMagneticField structureboundary_specs: Dictionary specifying boundary sources
Examples
# Insulating inner, potential field outer
boundary_specs = Dict(
:inner => (:insulating, 0.0),
:outer => (:potential_field, "geomagnetic_coefficients.nc")
)
# Perfect conductor boundaries
boundary_specs = Dict(
:inner => (:perfect_conductor, 0.0),
:outer => (:perfect_conductor, 0.0)
)
# NetCDF files for both boundaries
boundary_specs = Dict(
:inner => "cmb_magnetic.nc",
:outer => "surface_magnetic.nc"
)GeoDynamo.BoundaryConditions.load_temperature_boundaries_from_files — Method
load_temperature_boundaries_from_files(inner_file::String, outer_file::String, config)Load temperature boundary conditions from NetCDF files.
GeoDynamo.BoundaryConditions.load_temperature_boundary_conditions! — Method
load_temperature_boundary_conditions!(temp_field, boundary_specs::Dict)Load temperature boundary conditions from various sources.
Arguments
temp_field: SHTnsTemperatureField structureboundary_specs: Dictionary specifying boundary sources
Examples
# NetCDF files for both boundaries
boundary_specs = Dict(
:inner => "cmb_temperature.nc",
:outer => "surface_temperature.nc"
)
# Mixed NetCDF and programmatic
boundary_specs = Dict(
:inner => "cmb_temperature.nc",
:outer => (:uniform, 300.0)
)GeoDynamo.BoundaryConditions.load_velocity_boundaries_from_files — Method
load_velocity_boundaries_from_files(inner_file::String, outer_file::String, config)Load velocity boundary conditions from NetCDF files.
GeoDynamo.BoundaryConditions.load_velocity_boundary_conditions! — Method
load_velocity_boundary_conditions!(velocity_field, boundary_specs::Dict)Load velocity boundary conditions from various sources.
Arguments
velocity_field: SHTnsVelocityField structureboundary_specs: Dictionary specifying boundary sources
Examples
# No-slip boundaries at both surfaces
boundary_specs = Dict(
:inner => (:no_slip, 0.0),
:outer => (:no_slip, 0.0)
)
# Stress-free boundaries
boundary_specs = Dict(
:inner => (:stress_free, 0.0),
:outer => (:stress_free, 0.0)
)
# NetCDF file for inner, no-slip for outer
boundary_specs = Dict(
:inner => "cmb_velocity.nc",
:outer => (:no_slip, 0.0)
)GeoDynamo.BoundaryConditions.log_boundary_condition_status — Function
log_boundary_condition_status(state, rank::Int=0)Log the status of all boundary conditions in the simulation state.
GeoDynamo.BoundaryConditions.magnetic_to_qst_coefficients — Method
magnetic_to_qst_coefficients(B_r, B_theta, B_phi, config)Convert physical magnetic field components to QST spectral coefficients.
For magnetic fields:
- Q: Radial component coefficients (B_r)
- S: Spheroidal tangential component coefficients
- T: Toroidal tangential component coefficients
GeoDynamo.BoundaryConditions.print_boundary_data_info — Function
print_boundary_data_info(boundary_data::BoundaryData, prefix::String="")Print detailed information about boundary data.
GeoDynamo.BoundaryConditions.print_boundary_info — Method
print_boundary_info(boundary_set::BoundaryConditionSet)Print comprehensive information about a boundary condition set.
GeoDynamo.BoundaryConditions.print_boundary_summary — Method
print_boundary_summary(field, field_type::FieldType)Print a summary of loaded boundary conditions for any field type.
GeoDynamo.BoundaryConditions.read_netcdf_boundary_data — Method
read_netcdf_boundary_data(filename::String; precision::Type{T}=Float64) where TRead boundary condition data from a NetCDF file.
Returns a BoundaryData structure containing all boundary information.
GeoDynamo.BoundaryConditions.reset_boundary_conditions! — Method
reset_boundary_conditions!(field, field_type::FieldType)Reset/clear boundary conditions for a field.
GeoDynamo.BoundaryConditions.set_programmatic_composition_boundaries! — Method
set_programmatic_composition_boundaries!(comp_field, inner_spec::Tuple, outer_spec::Tuple)Set programmatic composition boundary conditions.
GeoDynamo.BoundaryConditions.set_programmatic_magnetic_boundaries! — Method
set_programmatic_magnetic_boundaries!(magnetic_field, inner_spec::Tuple, outer_spec::Tuple)Set programmatic magnetic boundary conditions.
GeoDynamo.BoundaryConditions.set_programmatic_temperature_boundaries! — Method
set_programmatic_temperature_boundaries!(temp_field, inner_spec::Tuple, outer_spec::Tuple)Set programmatic temperature boundary conditions.
GeoDynamo.BoundaryConditions.set_programmatic_velocity_boundaries! — Method
set_programmatic_velocity_boundaries!(velocity_field, inner_spec::Tuple, outer_spec::Tuple)Set programmatic velocity boundary conditions.
GeoDynamo.BoundaryConditions.shtns_physical_to_spectral — Method
shtns_physical_to_spectral(physical_data::Matrix{T}, config; return_complex::Bool=false) where TTransform physical boundary data to spectral coefficients using SHTnsKit. This is a common utility function used by both thermal and composition modules.
Arguments
physical_data: 2D array of physical values on (nlat, nlon) gridconfig: SHTnsKit configuration with lmax, mmax, nlm fieldsreturn_complex: If true, returns complex coefficients; otherwise real part only
Returns
Vector of spectral coefficients of length nlm.
Performance (v1.1.15)
Uses cached SHTnsKit configurations to avoid repeated setup overhead.
GeoDynamo.BoundaryConditions.shtns_spectral_to_physical — Method
shtns_spectral_to_physical(coeffs::Vector, config, nlat::Int, nlon::Int)Transform spectral coefficients to physical boundary data using SHTnsKit. Inverse of shtnsphysicalto_spectral.
Arguments
coeffs: Vector of spectral coefficients of length nlmconfig: SHTnsKit configuration with lmax, mmax fieldsnlat, nlon: Output grid dimensions
Returns
Matrix of physical values on (nlat, nlon) grid.
GeoDynamo.BoundaryConditions.smooth_boundary_data — Method
smooth_boundary_data(boundary_data::BoundaryData, smoothing_radius::Real)Apply spatial smoothing to boundary data.
GeoDynamo.BoundaryConditions.spherical_harmonic — Method
spherical_harmonic(l::Int, m::Int, theta::Real, phi::Real)Compute spherical harmonic Y_l^m(θ, φ).
GeoDynamo.BoundaryConditions.spherical_harmonic_phi_derivative — Method
spherical_harmonic_phi_derivative(l::Int, m::Int, theta::Real, phi::Real)Compute ∂Y_l^m/∂φ.
GeoDynamo.BoundaryConditions.spherical_harmonic_theta_derivative — Method
spherical_harmonic_theta_derivative(l::Int, m::Int, theta::Real, phi::Real)Compute ∂Y_l^m/∂θ.
GeoDynamo.BoundaryConditions.update_boundary_conditions_for_timestep! — Method
update_boundary_conditions_for_timestep!(state, current_time::Float64)Update all boundary conditions for the current timestep.
This function should be called at the beginning of each timestep to ensure all fields have up-to-date boundary conditions.
GeoDynamo.BoundaryConditions.update_composition_time_index! — Method
update_composition_time_index!(comp_field, time_index::Int)Update time index in field or fallback cache.
GeoDynamo.BoundaryConditions.update_magnetic_time_index! — Method
update_magnetic_time_index!(magnetic_field, time_index)Persist the provided time index to both the magnetic field structure and the module-level cache when available.
GeoDynamo.BoundaryConditions.update_temperature_time_index! — Method
update_temperature_time_index!(temp_field, time_index::Int)Update time index in field or fallback cache.
GeoDynamo.BoundaryConditions.update_time_dependent_boundaries! — Method
update_time_dependent_boundaries!(field, field_type::FieldType, current_time::Float64)Update time-dependent boundary conditions for any field type.
GeoDynamo.BoundaryConditions.update_time_dependent_composition_boundaries! — Method
update_time_dependent_composition_boundaries!(comp_field, current_time::Float64)Update time-dependent composition boundary conditions.
GeoDynamo.BoundaryConditions.update_time_dependent_magnetic_boundaries! — Method
update_time_dependent_magnetic_boundaries!(magnetic_field, current_time::Float64)Update time-dependent magnetic boundary conditions.
GeoDynamo.BoundaryConditions.update_time_dependent_temperature_boundaries! — Method
update_time_dependent_temperature_boundaries!(temp_field, current_time::Float64)Update time-dependent temperature boundary conditions.
GeoDynamo.BoundaryConditions.update_time_dependent_velocity_boundaries! — Method
update_time_dependent_velocity_boundaries!(velocity_field, current_time::Float64)Update time-dependent velocity boundary conditions.
GeoDynamo.BoundaryConditions.update_velocity_time_index! — Method
update_velocity_time_index!(velocity_field, time_index)Update cached time indices for velocity boundary conditions in both the field and the module-level fallback cache (when present).
GeoDynamo.BoundaryConditions.validate_boundary_compatibility — Method
validate_boundary_compatibility(inner::BoundaryData, outer::BoundaryData, field_name::String)Validate that inner and outer boundary data are compatible.
GeoDynamo.BoundaryConditions.validate_boundary_files — Method
validate_boundary_files(field_type::FieldType, boundary_specs::Dict, config)Validate boundary condition files for any field type.
GeoDynamo.BoundaryConditions.validate_composition_boundary_files — Method
validate_composition_boundary_files(boundary_specs::Dict, config)Validate composition boundary condition files.
GeoDynamo.BoundaryConditions.validate_composition_range — Method
validate_composition_range(boundary_data::BoundaryData)Validate that composition values are in the physical range [0, 1].
GeoDynamo.BoundaryConditions.validate_field_boundary_compatibility — Method
validate_field_boundary_compatibility(field, field_type::FieldType, boundary_set::BoundaryConditionSet)Validate that a field structure is compatible with boundary conditions.
GeoDynamo.BoundaryConditions.validate_flux_boundary_values — Method
validate_flux_boundary_values(values::Array, field_type::String;
typical_value_range::Tuple=(0.0, 1e10),
check_units::Bool=true)Validate that boundary values are physically reasonable for flux boundary conditions.
For heat flux boundaries:
- Values should be in W/m² or dimensionless heat flux
- Typical range: 0.01 - 1000 W/m² for Earth
- Check that values aren't accidentally in Kelvin (which would be 100-1000× larger)
Arguments
values: Boundary data arrayfield_type: Type of field ("temperature", "composition")typical_value_range: Expected range for flux valuescheck_units: Whether to perform unit sanity checks
Returns
is_valid: Booleanwarnings: Array of warning messages
GeoDynamo.BoundaryConditions.validate_insulating_boundary — Method
validate_insulating_boundary(B_r, B_theta, B_phi, theta, phi; tolerance=1e-2)Validate that a magnetic field satisfies the insulating boundary condition (∇×B)_r = 0.
Arguments
B_r, B_theta, B_phi: Magnetic field components [nlat, nlon]theta, phi: Coordinate arraystolerance: Maximum allowed |(∇×B)_r| / |B|
Returns
is_valid: Boolean indicating if condition is satisfiedmax_violation: Maximum |(∇×B)_r| / |B|
GeoDynamo.BoundaryConditions.validate_interpolation_grids — Method
validate_interpolation_grids(src_theta::Vector, src_phi::Vector,
tgt_theta::Vector, tgt_phi::Vector)Validate that source and target grids are compatible for interpolation.
GeoDynamo.BoundaryConditions.validate_magnetic_boundary_files — Method
validate_magnetic_boundary_files(boundary_specs::Dict, config)Validate magnetic field boundary condition files.
GeoDynamo.BoundaryConditions.validate_netcdf_boundary_file — Function
validate_netcdf_boundary_file(filename::String, required_vars::Vector{String}=[])Validate that a NetCDF boundary condition file has the required structure.
GeoDynamo.BoundaryConditions.validate_temperature_boundary_files — Method
validate_temperature_boundary_files(boundary_specs::Dict, config)Validate temperature boundary condition files.
GeoDynamo.BoundaryConditions.validate_temperature_flux_boundary — Method
validate_temperature_flux_boundary(boundary::BoundaryData, bc_type::Int)Validate that a temperature boundary condition has correct data type for its BC type.
For Neumann (flux) BCs: ensures values represent heat flux, not temperature For Dirichlet BCs: ensures values represent temperature
GeoDynamo.BoundaryConditions.validate_temperature_range — Method
validate_temperature_range(boundary_data::BoundaryData)Validate that temperature values are in a reasonable physical range.
GeoDynamo.BoundaryConditions.validate_velocity_boundary_files — Method
validate_velocity_boundary_files(boundary_specs::Dict, config)Validate velocity boundary condition files.
GeoDynamo.BoundaryConditions.velocity_to_qst_coefficients — Method
velocity_to_qst_coefficients(v_r, v_theta, v_phi, config)Convert physical velocity components (vr, vθ, v_φ) to QST spectral coefficients by using proper SHTnsKit decomposition.
The QST decomposition used by SHTnsKit:
- Q: Radial component coefficients (transforms like scalar field)
- S: Spheroidal horizontal component coefficients (curl-free part)
- T: Toroidal horizontal component coefficients (divergence-free part)
Arguments
v_r: Radial velocity component [nlat, nlon]v_theta: Colatitude velocity component [nlat, nlon]v_phi: Azimuthal velocity component [nlat, nlon]config: SHTnsKit configuration
Returns
(Q_coeffs, S_coeffs, T_coeffs): QST spectral coefficients
GeoDynamo.BoundaryConditions.write_netcdf_boundary_data — Method
write_netcdf_boundary_data(filename::String, boundary_data::BoundaryData)Write boundary condition data to a NetCDF file.
Initial Conditions
GeoDynamo.InitialConditions — Module
InitialConditionsModule for loading and generating initial conditions for geodynamo simulations. Supports loading from NetCDF files, generating random fields, and setting prescribed analytical patterns.
GeoDynamo.InitialConditions.generate_random_composition! — Method
generate_random_composition!(comp_field, amplitude, modes_range)Generate random composition initial conditions.
GeoDynamo.InitialConditions.generate_random_initial_conditions! — Method
generate_random_initial_conditions!(field, field_type::Symbol;
amplitude=1.0, modes_range=1:10,
seed=nothing)Generate random initial conditions for any field type.
Arguments
field: Field structure to initializefield_type: Type of field (:temperature, :magnetic, :velocity, :composition)amplitude: Overall amplitude of random perturbationsmodes_range: Range of spherical harmonic modes to exciteseed: Random seed for reproducibility (optional)
Examples
# Random temperature field
generate_random_initial_conditions!(temp_field, :temperature, amplitude=0.1)
# Random magnetic field with specific modes
generate_random_initial_conditions!(mag_field, :magnetic,
amplitude=0.01, modes_range=1:20, seed=42)GeoDynamo.InitialConditions.generate_random_magnetic! — Method
generate_random_magnetic!(mag_field, amplitude, modes_range)Generate random magnetic initial conditions.
GeoDynamo.InitialConditions.generate_random_temperature! — Method
generate_random_temperature!(temp_field, amplitude, modes_range)Generate random temperature initial conditions.
GeoDynamo.InitialConditions.generate_random_velocity! — Method
generate_random_velocity!(vel_field, amplitude, modes_range)Generate random velocity initial conditions.
GeoDynamo.InitialConditions.load_composition_initial_conditions! — Method
load_composition_initial_conditions!(comp_field, file_path::String)Load composition initial conditions from NetCDF file.
GeoDynamo.InitialConditions.load_initial_conditions! — Method
load_initial_conditions!(field, field_type::Symbol, file_path::String)Load initial conditions from NetCDF file for any field type.
Arguments
field: Field structure (temperature, magnetic, velocity, or composition type)field_type: Field type (:temperature, :magnetic, :velocity, :composition)file_path: Path to NetCDF file containing initial conditions
File Format
NetCDF files should contain:
- For scalar fields: spectral coefficients array
- For vector fields: toroidal and poloidal spectral coefficients
- Coordinate arrays: lm indices, radial grid
GeoDynamo.InitialConditions.load_magnetic_initial_conditions! — Method
load_magnetic_initial_conditions!(mag_field, file_path::String)Load magnetic initial conditions from NetCDF file.
GeoDynamo.InitialConditions.load_temperature_initial_conditions! — Method
load_temperature_initial_conditions!(temp_field, file_path::String)Load temperature initial conditions from NetCDF file.
GeoDynamo.InitialConditions.load_velocity_initial_conditions! — Method
load_velocity_initial_conditions!(vel_field, file_path::String)Load velocity initial conditions from NetCDF file.
GeoDynamo.InitialConditions.randomize_magnetic_field! — Method
randomize_magnetic_field!(field; amplitude, lmax, domain=nothing)Populate magnetic toroidal/poloidal fields with random perturbations.
GeoDynamo.InitialConditions.randomize_scalar_field! — Method
randomize_scalar_field!(field; amplitude, lmax, domain=nothing)Populate a scalar spectral field (temperature/composition) with random perturbations up to degree lmax. If a radial domain is provided and includes r=0, ball regularity is enforced.
GeoDynamo.InitialConditions.randomize_vector_field! — Method
randomize_vector_field!(field; amplitude, lmax, domain=nothing)Populate velocity-like toroidal/poloidal fields with random perturbations up to degree lmax.
GeoDynamo.InitialConditions.save_initial_conditions — Method
save_initial_conditions(field, field_type::Symbol, file_path::String)Save current field state as initial conditions to NetCDF file.
This function is useful for saving generated or computed initial conditions for later use in simulations.
GeoDynamo.InitialConditions.set_analytical_composition! — Method
set_analytical_composition!(comp_field, pattern, amplitude; parameters...)Set analytical composition patterns.
GeoDynamo.InitialConditions.set_analytical_initial_conditions! — Method
set_analytical_initial_conditions!(field, field_type::Symbol, pattern::Symbol;
amplitude=1.0, parameters...)Set analytical initial conditions based on predefined patterns.
Patterns
:conductive- Conductive temperature profile:dipole- Dipolar magnetic field:convective- Small convective velocity pattern:stratified- Stratified composition profile
Examples
# Conductive temperature profile
set_analytical_initial_conditions!(temp_field, :temperature, :conductive)
# Earth-like dipolar magnetic field
set_analytical_initial_conditions!(mag_field, :magnetic, :dipole, amplitude=1.0)GeoDynamo.InitialConditions.set_analytical_magnetic! — Method
set_analytical_magnetic!(mag_field, pattern, amplitude; parameters...)Set analytical magnetic field patterns.
GeoDynamo.InitialConditions.set_analytical_temperature! — Method
set_analytical_temperature!(temp_field, pattern, amplitude; parameters...)Set analytical temperature patterns.
GeoDynamo.InitialConditions.set_analytical_velocity! — Method
set_analytical_velocity!(vel_field, pattern, amplitude; parameters...)Set analytical velocity patterns.
Spherical Shell Geometry
GeoDynamo.GeoDynamoShell.apply_shell_composition_boundaries! — Method
apply_shell_composition_boundaries!(comp_field, boundary_set; time=0)GeoDynamo.GeoDynamoShell.apply_shell_temperature_boundaries! — Method
apply_shell_temperature_boundaries!(temp_field, boundary_set; time=0)Wrapper around core boundary application for shell geometry.
GeoDynamo.GeoDynamoShell.create_shell_composition_field — Method
create_shell_composition_field(T, cfg::ShellConfig; nr=GeoDynamo.i_N)GeoDynamo.GeoDynamoShell.create_shell_hybrid_composition_boundaries — Method
create_shell_hybrid_composition_boundaries(inner_spec, outer_spec, cfg::ShellConfig; precision=Float64)Create composition boundaries for shell geometry. Dispatches to appropriate function based on spec types:
- Both Tuple: fully programmatic boundaries
- String + Tuple: hybrid (one from file, one programmatic)
- Both String: both from files
GeoDynamo.GeoDynamoShell.create_shell_hybrid_temperature_boundaries — Method
create_shell_hybrid_temperature_boundaries(inner_spec, outer_spec, cfg::ShellConfig; precision=Float64)Create temperature boundaries for shell geometry. Dispatches to appropriate function based on spec types:
- Both Tuple: fully programmatic boundaries
- String + Tuple: hybrid (one from file, one programmatic)
- Both String: both from files
GeoDynamo.GeoDynamoShell.create_shell_magnetic_fields — Method
create_shell_magnetic_fields(T, cfg::ShellConfig; nr_oc=GeoDynamo.i_N, nr_ic=GeoDynamo.i_Nic)GeoDynamo.GeoDynamoShell.create_shell_pencils — Method
create_shell_pencils(cfg::ShellConfig; optimize=true)Create a shell-oriented pencil decomposition using the core topology helper.
GeoDynamo.GeoDynamoShell.create_shell_physical_field — Method
create_shell_physical_field(T, cfg::ShellConfig, domain::GeoDynamo.RadialDomain, pencil)GeoDynamo.GeoDynamoShell.create_shell_radial_domain — Function
create_shell_radial_domain(nr=i_N) -> RadialDomainCreate a radial domain suitable for a spherical shell using the global parameter d_rratio for inner radius ratio. This is a thin wrapper over GeoDynamo.create_radial_domain.
GeoDynamo.GeoDynamoShell.create_shell_spectral_field — Method
create_shell_spectral_field(T, cfg::ShellConfig, domain::GeoDynamo.RadialDomain, pencil)GeoDynamo.GeoDynamoShell.create_shell_temperature_field — Method
create_shell_temperature_field(T, cfg::ShellConfig; nr=GeoDynamo.i_N)GeoDynamo.GeoDynamoShell.create_shell_vector_field — Method
create_shell_vector_field(T, cfg::ShellConfig, domain::GeoDynamo.RadialDomain, pencils)GeoDynamo.GeoDynamoShell.create_shell_velocity_fields — Method
create_shell_velocity_fields(T, cfg::ShellConfig; nr=GeoDynamo.i_N)Solid Ball Geometry
GeoDynamo.GeoDynamoBall.apply_ball_composition_regularity! — Method
apply_ball_composition_regularity!(comp_field)GeoDynamo.GeoDynamoBall.apply_ball_temperature_regularity! — Method
apply_ball_temperature_regularity!(temp_field)Convenience to enforce scalar regularity on the temperature spectral field. Call after assembling or updating temp_field.spectral.
GeoDynamo.GeoDynamoBall.ball_physical_to_spectral! — Method
ball_physical_to_spectral!(phys::GeoDynamo.SHTnsPhysicalField,
spec::GeoDynamo.SHTnsSpectralField)Wrapper for transforms in a solid sphere that enforces scalar regularity at r=0 after analysis. Use this for scalar fields (temperature, composition, etc.).
GeoDynamo.GeoDynamoBall.ball_vector_analysis! — Method
ball_vector_analysis!(vec::GeoDynamo.SHTnsVectorField,
tor::GeoDynamo.SHTnsSpectralField,
pol::GeoDynamo.SHTnsSpectralField)Wrapper for vector analysis in a solid sphere; enforces vector regularity at r=0 after transforming to spectral toroidal/poloidal.
GeoDynamo.GeoDynamoBall.create_ball_composition_field — Method
create_ball_composition_field(T, cfg::BallConfig; nr=GeoDynamo.i_N)GeoDynamo.GeoDynamoBall.create_ball_hybrid_composition_boundaries — Method
create_ball_hybrid_composition_boundaries(inner_spec, outer_spec, cfg::BallConfig; precision=Float64)GeoDynamo.GeoDynamoBall.create_ball_hybrid_temperature_boundaries — Method
create_ball_hybrid_temperature_boundaries(inner_spec, outer_spec, cfg::BallConfig; precision=Float64)GeoDynamo.GeoDynamoBall.create_ball_magnetic_fields — Method
create_ball_magnetic_fields(T, cfg::BallConfig; nr=GeoDynamo.i_N)Create magnetic fields for a solid sphere. Since a "core" split is not used in a ball, we pass the same domain for both oc and ic to reuse the core implementation.
GeoDynamo.GeoDynamoBall.create_ball_pencils — Method
create_ball_pencils(cfg::BallConfig; optimize=true)GeoDynamo.GeoDynamoBall.create_ball_physical_field — Method
create_ball_physical_field(T, cfg::BallConfig, domain::GeoDynamo.RadialDomain, pencil)GeoDynamo.GeoDynamoBall.create_ball_radial_domain — Function
create_ball_radial_domain(nr=i_N) -> RadialDomainCreate a radial domain for a solid sphere (inner radius = 0). Uses a cosine-stretched grid similar to the shell for compatibility, but sets the inner radius to zero and adjusts the coordinate columns to match expectations of downstream operators.
GeoDynamo.GeoDynamoBall.create_ball_spectral_field — Method
create_ball_spectral_field(T, cfg::BallConfig, domain::GeoDynamo.RadialDomain, pencil)GeoDynamo.GeoDynamoBall.create_ball_temperature_field — Method
create_ball_temperature_field(T, cfg::BallConfig; nr=GeoDynamo.i_N)GeoDynamo.GeoDynamoBall.create_ball_vector_field — Method
create_ball_vector_field(T, cfg::BallConfig, domain::GeoDynamo.RadialDomain, pencils)GeoDynamo.GeoDynamoBall.create_ball_velocity_fields — Method
create_ball_velocity_fields(T, cfg::BallConfig; nr=GeoDynamo.i_N)GeoDynamo.GeoDynamoBall.enforce_ball_scalar_regularity! — Method
enforce_ball_scalar_regularity!(spec::GeoDynamo.SHTnsSpectralField)Enforce scalar regularity at r=0 for solid sphere: for l>0, the scalar amplitude must vanish at r=0. Sets inner radial plane to zero for all nonzero l modes (both real and imaginary parts).
GeoDynamo.GeoDynamoBall.enforce_ball_vector_regularity! — Method
enforce_ball_vector_regularity!(tor_spec::GeoDynamo.SHTnsSpectralField,
pol_spec::GeoDynamo.SHTnsSpectralField)Enforce vector-field regularity at r=0 for solid sphere. For smooth fields, both toroidal and poloidal potentials behave like r^{l+1}, so they vanish at r=0 for all l ≥ 1. Zeros the inner radial plane for l≥1.
For lower-level packages used internally (SHTnsKit, PencilArrays, MPI), refer to their respective documentation.