mf6adj classes and helper functions

Public package interface for mf6adj.

class mf6adj.Mf6Adj(adj_filename, lib_name, logging_level='INFO', logging_filename=None, working_directory=None)[source]

Bases: object

MODFLOW 6 adjoint solver interface.

Parameters:
  • adj_filename (str) – Adjoint input filename.

  • lib_name (str) – MODFLOW 6 shared library path.

  • logging_level (str or int, optional) – Logging level (DEBUG, INFO, WARNING, ERROR, or CRITICAL).

  • logging_filename (str or pl.Path, optional) – Optional log filename. If omitted, logging is limited to the console.

  • working_directory (str or pl.Path, optional) – Working directory. If omitted, the current directory is used.

finalize()[source]

Close the API and file handles.

perturbation_method(pert_mult=1.01)[source]

Calculate finite-difference perturbation sensitivities.

This utility perturbs active parameter entries one at a time, reruns the forward simulation, and estimates sensitivity using a forward-difference quotient. The resulting sensitivities can be compared directly with adjoint-based sensitivities for verification during development.

Parameters:

pert_mult (float, default 1.01) – Multiplicative perturbation factor applied to each parameter value. The perturbation increment is computed as epsilon = value * (pert_mult - 1.0).

Returns:

Dataframe with one row per perturbation and columns containing perturbation metadata (for example parameter, index, epsilon, and node/layer labels where applicable) plus finite-difference sensitivities for each configured performance measure.

Return type:

DataFrame

solve_adjoint(hdf5_adjoint_solution_fname=None, skip_solve=False, csv_summary=False, linear_solver=None, linear_solver_kwargs={}, use_precon=True, jacobi_preconditioner=None, precon_kwargs={}, singular_test=False, tikhonov=0.0, dvclose=1e-06, rclose=0.001, dvscale=False)[source]

Solve for the adjoint state, one performance measure at a time.

Parameters:
  • hdf5_adjoint_solution_fname (PathLike, optional) – HDF5 file to write the adjoint solution. If omitted, a default name based on the performance-measure name is used.

  • skip_solve (bool, optional) – Skip the adjoint solve for time steps with no performance-measure entries.

  • csv_summary (bool, optional) – Write a CSV summary of the sensitivity information.

  • linear_solver (str or callable, optional) – Sparse linear solver to use. If None, either a direct solver or bicgstab is selected based on model size. If a string, supported values are "direct" and "bicgstab". A compatible solver callable may also be supplied.

  • linear_solver_kwargs (dict, optional) – Keyword arguments passed to linear_solver.

  • use_precon (bool, optional) – Use a preconditioner with the iterative linear solver.

  • jacobi_preconditioner (str, optional) – Use Jacobi preconditioner with the iterative linear solver. If None, the ILU preconditioner will be used. If a string, supported values are "point" and "block".

  • precon_kwargs (dict, optional) – Keyword arguments passed to the preconditioner setup. For the default ILU preconditioner, these are passed to spilu. When jacobi_preconditioner="block", the block_size key sets the block size.

  • singular_test (bool, optional) – Test for a singular matrix and apply Tikhonov regularization when needed.

  • tikhonov (float, optional) – Tikhonov regularization value.

  • dvclose (float, optional) – Custom convergence criterion based on the maximum absolute change between consecutive iterates.

  • rclose (float, optional) – Custom convergence criterion based on the maximum absolute residual.

  • dvscale (bool, optional) – Scale lambda and the right-hand side to improve iterative solver convergence for large lambda values.

Returns:

Composite sensitivity summaries keyed by performance-measure name.

Return type:

dict[str, DataFrame]

solve_forward_model(verbose=True, force_k_update=False, sp_pert_dict=None, pert_save=False, hdf5_name=None, solve_func_ptr=None, presolve_func_ptr=None, postsolve_func_ptr=None)[source]

Solve the forward model and store adjoint inputs in HDF5.

The forward model is run for all MODFLOW 6 time steps, and the solution components needed for the adjoint solve are harvested and written to the HDF5 file.

Parameters:
  • verbose (bool, optional) – Whether to report progress to stdout.

  • force_k_update (bool, optional) – Force MODFLOW 6 to reprocess the K and K33 arrays. Used only during perturbation testing.

  • sp_pert_dict (dict, optional) – Perturbed boundary information used during perturbation testing.

  • pert_save (bool, optional) – Save additional information for perturbation testing.

  • hdf5_name (PathLike, optional) – Output HDF5 filename for forward-solution components. If omitted, a generic time-stamped filename is created.

  • solve_func_ptr (callable, optional) – Callback invoked with the modflowapi.ModflowApi instance before each solver iteration. If omitted, no callback is run.

  • presolve_func_ptr (callable, optional) – Callback invoked with the modflowapi.ModflowApi instance at the start of each time step, before the solve loop begins. If omitted, no callback is run.

  • postsolve_func_ptr (callable, optional) – Callback invoked with the modflowapi.ModflowApi instance after each time step is finalized. If omitted, no callback is run.

Returns:

Perturbation-testing data when pert_save is True; otherwise None.

Return type:

tuple[dict, dict] or None

class mf6adj.PerfMeas(pm_name, pm_entries, logging_level='INFO', logger=None)[source]

Bases: object

Performance-measure container and adjoint-solve helper.

Parameters:
  • pm_name (str) – Name of the performance measure.

  • pm_entries (list[PerfMeasRecord]) – Performance-measure entries.

  • logging_level (str or int, optional) – Logging level.

  • logger (logging.Logger, optional) – Logger instance. If omitted, a new logger is created.

solve_adjoint(hdf5_forward_solution_fname, hdf5_adjoint_solution_fname=None, skip_solve=False, csv_summary=False, linear_solver=None, linear_solver_kwargs=None, use_precon=True, jacobi_preconditioner=None, precon_kwargs=None, singular_test=False, tikhonov=0.0, dvclose=1e-06, rclose=0.001, dvscale=False)[source]

Solve for the adjoint state for the performance measure.

This method writes an adjoint-solution HDF5 file and, when requested, writes a CSV summary file.

Parameters:
  • hdf5_forward_solution_fname (PathLike) – HDF5 file created by Mf6Adj.solve_forward_model() containing the forward-solution information needed for the adjoint solve.

  • hdf5_adjoint_solution_fname (PathLike, optional) – HDF5 file to write the adjoint solution. If omitted, a default name based on the performance-measure name is used. If the target file already exists, it is removed before writing.

  • skip_solve (bool, optional) – Skip the adjoint solve for time steps with no performance-measure entries.

  • csv_summary (bool, optional) – Write a CSV summary of the sensitivity information beside the adjoint HDF5 output file.

  • linear_solver (str or callable, optional) – Sparse linear solver to use. Supported string values are "direct", "bicgstab", "cg", "gmres", "lgmres", and "lsqr".

  • linear_solver_kwargs (dict, optional) – Keyword arguments passed to the configured linear solver callable.

  • use_precon (bool, optional) – Use a preconditioner with the iterative linear solver.

  • jacobi_preconditioner (str, optional) – Use a Jacobi preconditioner with the iterative linear solver. If None, the ILU preconditioner is used. Supported string values are "point" and "block".

  • precon_kwargs (dict, optional) – Keyword arguments passed to the preconditioner setup. For the default ILU preconditioner, these are passed to spilu. When jacobi_preconditioner="block", the block_size key sets the block size.

  • singular_test (bool, optional) – Test for a singular matrix and apply Tikhonov regularization when needed.

  • tikhonov (float, optional) – Tikhonov regularization value.

  • dvclose (float, optional) – Custom convergence criterion based on the maximum absolute change between consecutive iterates.

  • rclose (float, optional) – Custom convergence criterion based on the maximum absolute residual.

  • dvscale (bool, optional) – Scale lambda and the right-hand side to improve iterative solver convergence for large lambda values.

Returns:

Summary of composite sensitivity information.

Return type:

DataFrame

class mf6adj.PerfMeasRecord(kper, kstp, inode, pm_type, pm_form, weight, obsval, k=None, i=None, j=None)[source]

Bases: object

Single record from a performance-measure block.

Parameters:
  • kper (int) – Zero-based stress period.

  • kstp (int) – Zero-based time step.

  • inode (int) – Zero-based node number.

  • pm_type (str) – Either head or a boundary package name from the GWF name file.

  • pm_form (str) – Either direct or residual.

  • weight (float) – Weight value.

  • obsval (float) – Observed counterpart; used only for residual form.

  • k (int, optional) – Zero-based layer index for structured-grid reporting.

  • i (int, optional) – Zero-based row index for structured-grid reporting.

  • j (int, optional) – Zero-based column index for structured-grid reporting.

mf6adj.get_conda_mf6_paths(bin_path='bin', lib_path='lib')[source]

Locate the MODFLOW 6 executable and shared library in the active conda environment.

Resolves platform-specific paths for the mf6 executable and libmf6 shared library using the CONDA_PREFIX environment variable. On Windows, bin_path is overridden to "Scripts" and the appropriate extensions (.exe, .dll) are applied automatically.

Parameters:
  • bin_path (str, optional) – Subdirectory of the conda environment containing executables. Default is "bin". Overridden to "Scripts" on Windows.

  • lib_path (str, optional) – Subdirectory of the conda environment to search first for the shared library. Default is "lib". Falls back to bin_path if the library is not found there.

Returns:

  • mf6_path (pl.Path or None) – Absolute path to the mf6 executable, or None if not found.

  • libmf6_path (pl.Path or None) – Absolute path to the libmf6 shared library, or None if not found.

Raises:

RuntimeError – If the CONDA_PREFIX environment variable is not set.