Overview

uw.Params provides a clean way to define configurable parameters that can be:

  1. Set in notebooks - Just assign new values

  2. Overridden from command line - Via PETSc options (-uw_param_name value)

This makes scripts portable between interactive development and HPC batch execution.

Basic Usage

import underworld3 as uw

# Define parameters with defaults
params = uw.Params(
    uw_resolution = 0.05,    # Cell size for mesh
    uw_diffusivity = 1.0,    # Material property
    uw_max_steps = 100,      # Integer parameter
    uw_verbose = True,       # Boolean flag
    uw_solver = "mumps",     # String option
)

# Use in your model
mesh = uw.meshing.Box(cellSize=params.uw_resolution)

Naming Convention

Use the uw_ prefix for parameter names. This:

  • Avoids collisions with PETSc solver options

  • Makes it clear these are underworld example parameters

  • The CLI flag matches the Python name exactly

Command Line Override

# Override resolution and solver
python script.py -uw_resolution 0.025 -uw_solver superlu_dist

# Works with mpirun
mpirun -np 4 python script.py -uw_resolution 0.01

Why Single-Dash Options?

Underworld uses PETSc-style command-line options, not Python’s standard argparse conventions. The key differences:

Convention

Long option

Short option

Word separator

PETSc (Underworld)

-uw_resolution

underscore _

argparse (Python)

--resolution

-r

hyphen -

Underworld inherits PETSc’s options database, which uses a single dash followed by a descriptive name with underscores. This is by design:

  • PETSc solver options (e.g., -ksp_type gmres, -pc_type lu) use this format

  • Underworld user parameters share the same options database

  • The uw_ prefix prevents collisions with PETSc’s own options

This means standard Python option parsers (argparse, click) do not support this style of options by default and may require custom handling if you try to parse -uw_* flags yourself. Use uw.Params instead — it reads from PETSc’s options database automatically.

Tip

If you’re writing a wrapper script that also needs argparse-style options, parse those with argparse first (for example using parse_known_args), then pass only the remaining/unparsed arguments to PETSc via petsc4py.init(remaining_argv) before importing underworld.

Notebook Override

# Just assign a new value
params.uw_resolution = 0.025

Unit-Aware Parameters

For physical quantities with units, use the uw.Param() wrapper:

params = uw.Params(
    # Physical quantities with units
    uw_cell_size = uw.Param(0.5, units="km", description="Mesh cell size"),
    uw_viscosity = uw.Param(1e21, units="Pa*s"),
    uw_latitude = uw.Param(45.0, units="degree"),

    # Dimensionless ratios
    uw_rayleigh = uw.Param(1e5, type=uw.ParamType.RATIO,
                           description="Rayleigh number"),

    # Plain types still work
    uw_elements = 32,
)

CLI with Units

Units must be provided on the command line for unit-aware parameters:

# These work
python script.py -uw_cell_size "500 m"
python script.py -uw_cell_size 0.5km
python script.py -uw_viscosity "1e22 Pa*s"
python script.py -uw_latitude "0.785 radian"  # Converts to degrees

# These fail with helpful errors
python script.py -uw_cell_size 500        # ERROR: Units required
python script.py -uw_cell_size "500 s"    # ERROR: Dimension mismatch

Accessing Values

Unit-aware parameters return UWQuantity objects that integrate with the scaling system:

cell_size = params.uw_cell_size      # UWQuantity(0.5, "km")
cell_size_m = cell_size.to("meter")  # Convert to meters

# For mesh creation (handles unit conversion automatically)
mesh = uw.meshing.Box(cellSize=params.uw_cell_size)

Parameter Options

The uw.Param() wrapper supports:

Option

Description

value

Default value (required)

units

Unit string, e.g., "km", "Pa*s", "degree"

type

Explicit type: uw.ParamType.QUANTITY, RATIO, INTEGER, etc.

bounds

Tuple (min, max) for validation

description

Help text shown in cli_help()

Bounds Validation

params = uw.Params(
    uw_cell_size = uw.Param(0.5, units="km",
                            bounds=(0.01, 100),
                            description="Must be 0.01-100 km"),
)

# This would raise ValueError
# python script.py -uw_cell_size "0.001 km"  # Below minimum

Inspecting Parameters

Display in Notebooks

Params has rich display with source tracking:

params  # Shows table with values, units, types, and sources

Parameter

Value

Units

Type

Source

uw_cell_size

0.5 kilometer

km

quantity

default

uw_viscosity

1e+21 pascal * second

Pa*s

quantity

CLI

CLI Help

print(params.cli_help())
Command-line options (PETSc format):

  -uw_cell_size <quantity>   Units: km
                             Must be 0.01-100 km
                             (default: 0.5 km)

  -uw_viscosity <quantity>   Units: Pa*s
                             (default: 1e+21 Pa*s)

  -uw_rayleigh <ratio>       Dimensionless ratio
                             Rayleigh number
                             (default: 100000.0)

Example:
  python script.py -uw_cell_size 0.5km -uw_viscosity 1e+21Pa*s

Complete Example

import underworld3 as uw

# Define all configurable parameters at the top
params = uw.Params(
    # Mesh parameters
    uw_cell_size = uw.Param(50.0, units="km",
                            bounds=(10, 200),
                            description="Target cell size"),
    uw_depth = uw.Param(660.0, units="km",
                        description="Model depth"),

    # Physical properties
    uw_viscosity = uw.Param(1e21, units="Pa*s"),
    uw_density_diff = uw.Param(50.0, units="kg/m^3"),

    # Solver settings
    uw_max_iterations = 50,
    uw_tolerance = 1e-6,
)

# Show help (useful at script start)
if uw.mpi.rank == 0:
    print(params.cli_help())

# Build model using parameters
mesh = uw.meshing.Box(
    minCoords=(0, 0),
    maxCoords=(uw.quantity(2000, "km"), params.uw_depth),
    cellSize=params.uw_cell_size,
)

# ... rest of model setup

Run with:

# Default parameters
python convection.py

# Override for higher resolution
python convection.py -uw_cell_size 25km -uw_depth 1000km

# HPC run with many overrides
mpirun -np 256 python convection.py \
    -uw_cell_size 10km \
    -uw_viscosity "5e20 Pa*s" \
    -uw_max_iterations 100

Angle Units

Angles work naturally - you can define in degrees and provide radians (or vice versa):

params = uw.Params(
    uw_latitude = uw.Param(45.0, units="degree"),
)

# CLI accepts any angle unit
# python script.py -uw_latitude "0.785 radian"
# python script.py -uw_latitude "45 deg"

# Convert as needed
lat_rad = params.uw_latitude.to("radian")