Quickstart: 1D dissolution fronts with from_mf6¶
This quickstart reproduces the classic Engesgaard & Kipp (1992) benchmark: a one-dimensional column initially filled with water in equilibrium with calcite is flushed by an inflowing MgCl$_2$ solution. The incoming water dissolves calcite and briefly precipitates dolomite, producing a set of sharp, migrating mineral fronts.
It also shows the recommended transport-first workflow: you build an
ordinary MODFLOW 6 flow + (single, conservative) transport model with FloPy,
then hand it to :meth:~mf6rtm.mup3d.base.Mup3d.from_mf6, which clones the
tracer transport model into one reactive transport model per chemical
component and couples it to PhreeqcRM.
import os
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import flopy
from mf6rtm import utils, mup3d
# Resolve paths whether executed from the notebook dir or the repo root.
BASE = "." if os.path.isdir("data") else os.path.join("docs", "tutorials")
DATA = os.path.join(BASE, "data")
1. Spatial and temporal discretization¶
A 0.5 m column split into 50 cells, simulated for 0.24 days.
length_units = "meters"
time_units = "days"
nlay, nrow, ncol = 1, 1, 50
Lx = 0.5
delr = Lx / ncol
delc = 1.0
top, botm = 0.0, -1.0
k11 = 1.0 # hydraulic conductivity (m/d)
prsity = 0.32 # porosity
dispersivity = 0.0067 # longitudinal dispersivity (m)
q = 0.259 # injection rate at the inlet (m3/d)
perlen = 0.24 # simulation length (days)
tstep = 0.01
nstp = int(perlen / tstep)
tdis_rc = [(perlen, nstp, 1.0)]
2. Build the flow + tracer transport model with FloPy¶
We build a single conservative tracer GWT model. The inlet well carries a
tracer auxiliary variable; from_mf6 uses that boundary to inject the
inflow solution’s chemistry once the model becomes reactive.
sim_ws = os.path.join(BASE, "_tutorial01_run")
sim = flopy.mf6.MFSimulation(sim_name="quickstart", sim_ws=sim_ws, exe_name="mf6")
flopy.mf6.ModflowTdis(sim, nper=1, perioddata=tdis_rc, time_units=time_units)
# --- GWF flow model ---
gwf = flopy.mf6.ModflowGwf(sim, modelname="gwf", save_flows=True)
ims_gwf = flopy.mf6.ModflowIms(sim, linear_acceleration="CG", filename="gwf.ims")
sim.register_ims_package(ims_gwf, ["gwf"])
flopy.mf6.ModflowGwfdis(
gwf, length_units=length_units, nlay=nlay, nrow=nrow, ncol=ncol,
delr=delr, delc=delc, top=top, botm=botm, filename="gwf.dis",
)
flopy.mf6.ModflowGwfnpf(gwf, save_specific_discharge=True, icelltype=1, k=k11,
save_saturation=True, filename="gwf.npf")
flopy.mf6.ModflowGwfic(gwf, strt=1.0, filename="gwf.ic")
# constant head at the outlet (last column)
flopy.mf6.ModflowGwfchd(
gwf, stress_period_data=[[(0, 0, ncol - 1), 1.0]],
pname="chd", filename="gwf.chd",
)
# injection well at the inlet, carrying a tracer auxiliary
flopy.mf6.ModflowGwfwel(
gwf, stress_period_data=[[(0, 0, 0), q, 1.0]],
auxiliary=["tracer"], pname="wel", filename="gwf.wel",
)
flopy.mf6.ModflowGwfoc(
gwf, head_filerecord="gwf.hds", budget_filerecord="gwf.cbb",
saverecord=[("HEAD", "ALL"), ("BUDGET", "ALL")],
)
# --- GWT conservative tracer model (template for from_mf6) ---
gwt = flopy.mf6.ModflowGwt(sim, modelname="gwt")
ims_gwt = flopy.mf6.ModflowIms(sim, linear_acceleration="BICGSTAB", filename="gwt.ims")
sim.register_ims_package(ims_gwt, ["gwt"])
flopy.mf6.ModflowGwtdis(
gwt, length_units=length_units, nlay=nlay, nrow=nrow, ncol=ncol,
delr=delr, delc=delc, top=top, botm=botm, filename="gwt.dis",
)
flopy.mf6.ModflowGwtic(gwt, strt=0.0, filename="gwt.ic")
flopy.mf6.ModflowGwtssm(gwt, sources=[["wel", "aux", "tracer"]], filename="gwt.ssm")
flopy.mf6.ModflowGwtadv(gwt, scheme="UPSTREAM")
flopy.mf6.ModflowGwtdsp(gwt, xt3d_off=True, alh=dispersivity, ath1=0.0,
filename="gwt.dsp")
flopy.mf6.ModflowGwtmst(gwt, porosity=prsity, filename="gwt.mst")
flopy.mf6.ModflowGwtoc(
gwt, concentration_filerecord="gwt.ucn",
saverecord=[("CONCENTRATION", "ALL")],
)
flopy.mf6.ModflowGwfgwt(sim, exgtype="GWF6-GWT6", exgmnamea="gwf",
exgmnameb="gwt", filename="gwf-gwt.gwfgwt")
package_name = gwf-gwt.gwfgwt
filename = gwf-gwt.gwfgwt
package_type = gwfgwt
model_or_simulation_package = simulation
simulation_name = quickstart
3. Define the geochemistry¶
mf6rtm expresses PHREEQC chemistry as mup3d classes. For each input you
(1) load the data (here from CSV via a utils helper), (2) wrap it in the
matching class, and (3) call .set_ic(...) to place it — an integer zone
number for uniform chemistry, or a (nlay, nrow, ncol) array to vary it in
space. The object is then given to the model: Solutions goes into
from_mf6; the phases are attached with set_* methods.
Solutions — the aqueous waters. Column 1 is the background pore water
(placed everywhere with set_ic(1)); column 2 is the inflow water the
boundary ChemStress injects.
solutionsdf = pd.read_csv(os.path.join(DATA, "tut01_solutions.csv"),
comment="#", index_col=0)
solutions = utils.solution_df_to_dict(solutionsdf)
solution = mup3d.Solutions(solutions)
solution.set_ic(1) # background solution everywhere
solutionsdf
| sol_bck | sol_in | |
|---|---|---|
| comp | ||
| pH | 9.910000 | 7.000 |
| pe | 4.000000 | 4.000 |
| C(+4) | 0.000123 | 0.000 |
| Ca | 0.000123 | 0.000 |
| Cl | 0.000000 | 0.002 |
| Mg | 0.000000 | 0.001 |
Equilibrium phases — minerals held at equilibrium each step (PHREEQC
EQUILIBRIUM_PHASES): calcite and dolomite. set_ic(1) applies the same
assemblage to every cell.
eqp_df = pd.read_csv(os.path.join(DATA, "tut01_equilibrium_phases.csv"))
eqp_dict = utils.parse_equilibriums_dataframe(eqp_df)
equilibrium_phases = mup3d.EquilibriumPhases(eqp_dict)
equilibrium_phases.set_ic(1)
eqp_df
| phase | sat_index | conc_mol_lb | num | |
|---|---|---|---|---|
| 0 | Calcite | 0.0 | 0.000122 | 1 |
| 1 | Dolomite | 0.0 | 0.000000 | 1 |
4. Couple chemistry to the MF6 model with from_mf6¶
from_mf6 reads the grid from the GWF model and stores the tracer GWT model
as the template that will be cloned per component.
model = mup3d.Mup3d.from_mf6(sim, solution, name="quickstart", gwt_name="gwt")
model.set_wd(sim_ws)
model.set_database(os.path.join(DATA, "pht3d_datab.dat"))
model.set_equilibrium_phases(equilibrium_phases)
model.set_postfix(os.path.join(DATA, "tut01_postfix.phqr"))
model.initialize()
Using temperatue of 25.0 for all cells
MF6RTM will run with the following configuration:
Reactive: True
Reaction timing: all
External files flag: False
Emulator flag: False
Min concentration: None (no clipping)
Reactions calculated at all time steps
Phreeqc initialized
WARNING: Element Mg is contained in Dolomite (which has 0.0 mass),
but is not in solution or other phases.
WARNING: Element Mg is contained in Dolomite (which has 0.0 mass),
but is not in solution or other phases.
WARNING: Element Mg is contained in Dolomite (which has 0.0 mass),
but is not in solution or other phases.
WARNING: Element Mg is contained in Dolomite (which has 0.0 mass),
but is not in solution or other phases.
WARNING: Element Mg is contained in Dolomite (which has 0.0 mass),
but is not in solution or other phases.
WARNING: Element Mg is contained in Dolomite (which has 0.0 mass),
but is not in solution or other phases.
WARNING: Element Mg is contained in Dolomite (which has 0.0 mass),
but is not in solution or other phases.
WARNING: Element Mg is contained in Dolomite (which has 0.0 mass),
but is not in solution or other phases.
WARNING: Element Mg is contained in Dolomite (which has 0.0 mass),
but is not in solution or other phases.
WARNING: Element Mg is contained in Dolomite (which has 0.0 mass),
but is not in solution or other phases.
WARNING: Element Mg is contained in Dolomite (which has 0.0 mass),
but is not in solution or other phases.
WARNING: Element Mg is contained in Dolomite (which has 0.0 mass),
but is not in solution or other phases.
WARNING: Element Mg is contained in Dolomite (which has 0.0 mass),
but is not in solution or other phases.
WARNING: Element Mg is contained in Dolomite (which has 0.0 mass),
but is not in solution or other phases.
WARNING: Element Mg is contained in Dolomite (which has 0.0 mass),
but is not in solution or other phases.
WARNING: Element Mg is contained in Dolomite (which has 0.0 mass),
but is not in solution or other phases.
WARNING: Element Mg is contained in Dolomite (which has 0.0 mass),
but is not in solution or other phases.
WARNING: Element Mg is contained in Dolomite (which has 0.0 mass),
but is not in solution or other phases.
WARNING: Element Mg is contained in Dolomite (which has 0.0 mass),
but is not in solution or other phases.
WARNING: Element Mg is contained in Dolomite (which has 0.0 mass),
but is not in solution or other phases.
WARNING: Element Mg is contained in Dolomite (which has 0.0 mass),
but is not in solution or other phases.
WARNING: Element Mg is contained in Dolomite (which has 0.0 mass),
but is not in solution or other phases.
WARNING: Element Mg is contained in Dolomite (which has 0.0 mass),
but is not in solution or other phases.
WARNING: Element Mg is contained in Dolomite (which has 0.0 mass),
but is not in solution or other phases.
WARNING: Element Mg is contained in Dolomite (which has 0.0 mass),
but is not in solution or other phases.
WARNING: Element Mg is contained in Dolomite (which has 0.0 mass),
but is not in solution or other phases.
WARNING: Element Mg is contained in Dolomite (which has 0.0 mass),
but is not in solution or other phases.
WARNING: Element Mg is contained in Dolomite (which has 0.0 mass),
but is not in solution or other phases.
WARNING: Element Mg is contained in Dolomite (which has 0.0 mass),
but is not in solution or other phases.
WARNING: Element Mg is contained in Dolomite (which has 0.0 mass),
but is not in solution or other phases.
WARNING: Element Mg is contained in Dolomite (which has 0.0 mass),
but is not in solution or other phases.
WARNING: Element Mg is contained in Dolomite (which has 0.0 mass),
but is not in solution or other phases.
WARNING: Element Mg is contained in Dolomite (which has 0.0 mass),
but is not in solution or other phases.
WARNING: Element Mg is contained in Dolomite (which has 0.0 mass),
but is not in solution or other phases.
WARNING: Element Mg is contained in Dolomite (which has 0.0 mass),
but is not in solution or other phases.
WARNING: Element Mg is contained in Dolomite (which has 0.0 mass),
but is not in solution or other phases.
WARNING: Element Mg is contained in Dolomite (which has 0.0 mass),
but is not in solution or other phases.
WARNING: Element Mg is contained in Dolomite (which has 0.0 mass),
but is not in solution or other phases.
WARNING: Element Mg is contained in Dolomite (which has 0.0 mass),
but is not in solution or other phases.
WARNING: Element Mg is contained in Dolomite (which has 0.0 mass),
but is not in solution or other phases.
WARNING: Element Mg is contained in Dolomite (which has 0.0 mass),
but is not in solution or other phases.
WARNING: Element Mg is contained in Dolomite (which has 0.0 mass),
but is not in solution or other phases.
WARNING: Element Mg is contained in Dolomite (which has 0.0 mass),
but is not in solution or other phases.
WARNING: Element Mg is contained in Dolomite (which has 0.0 mass),
but is not in solution or other phases.
WARNING: Element Mg is contained in Dolomite (which has 0.0 mass),
but is not in solution or other phases.
WARNING: Element Mg is contained in Dolomite (which has 0.0 mass),
but is not in solution or other phases.
WARNING: Element Mg is contained in Dolomite (which has 0.0 mass),
but is not in solution or other phases.
WARNING: Element Mg is contained in Dolomite (which has 0.0 mass),
but is not in solution or other phases.
WARNING: Element Mg is contained in Dolomite (which has 0.0 mass),
but is not in solution or other phases.
WARNING: Element Mg is contained in Dolomite (which has 0.0 mass),
but is not in solution or other phases.
5. Assign the inflow chemistry to the boundary¶
The wel package injects solution 2 (the MgCl$_2$ water). type='aux'
routes it through the GWF stress package + GWT SSM.
wellchem = mup3d.ChemStress("wel", type="aux")
wellchem.set_spd([2])
model.set_chem_stress(wellchem)
Initializing ChemStress
ChemStress wel initialized
6. Write and run the reactive transport simulation¶
model.write_simulation()
# Stage the platform's MODFLOW 6 binaries (mf6 + libmf6) into the run directory
# so the solver finds the shared library locally. pixi fetches them into
# ``benchmark/bin`` via the ``install-benchmark-bins`` task.
utils.prep_bins(model.wd, src_path=os.path.join(BASE, "..", "..", "benchmark", "bin"))
model.run()
writing simulation...
writing simulation name file...
writing simulation tdis package...
writing solution package ims_-1...
writing solution package ims_1...
writing solution package ims_2...
writing solution package ims_3...
writing solution package ims_4...
writing solution package ims_5...
writing solution package ims_6...
writing solution package ims_7...
writing package H.gwfgwt...
writing package O.gwfgwt...
writing package Charge.gwfgwt...
writing package C.gwfgwt...
writing package Ca.gwfgwt...
writing package Cl.gwfgwt...
writing package Mg.gwfgwt...
writing model gwf...
writing model name file...
writing package dis...
writing package npf...
writing package ic...
writing package chd...
INFORMATION: maxbound in ('gwf6', 'chd', 'dimensions') changed to 1 based on size of stress_period_data
writing package wel...
INFORMATION: maxbound in ('gwf6', 'wel', 'dimensions') changed to 1 based on size of stress_period_data
writing package oc...
writing model H...
writing model name file...
writing package dis...
writing package adv...
writing package dsp...
writing package ic...
writing package mst...
writing package ssm...
writing package oc...
writing model O...
writing model name file...
writing package dis...
writing package adv...
writing package dsp...
writing package ic...
writing package mst...
writing package ssm...
writing package oc...
writing model Charge...
writing model name file...
writing package dis...
writing package adv...
writing package dsp...
writing package ic...
writing package mst...
writing package ssm...
writing package oc...
writing model C...
writing model name file...
writing package dis...
writing package adv...
writing package dsp...
writing package ic...
writing package mst...
writing package ssm...
writing package oc...
writing model Ca...
writing model name file...
writing package dis...
writing package adv...
writing package dsp...
writing package ic...
writing package mst...
writing package ssm...
writing package oc...
writing model Cl...
writing model name file...
writing package dis...
writing package adv...
writing package dsp...
writing package ic...
writing package mst...
writing package ssm...
writing package oc...
writing model Mg...
writing model name file...
writing package dis...
writing package adv...
writing package dsp...
writing package ic...
writing package mst...
writing package ssm...
writing package oc...
MF6RTM will run with the following configuration:
Reactive: True
Reaction timing: all
External files flag: False
Emulator flag: False
Min concentration: None (no clipping)
Reactions calculated at all time steps
Simulation saved in /Users/portega/dev/code/mf6rtm/mf6rtm-main/docs/tutorials/_tutorial01_run
Running mf6rtm
Using libmf6 found in model directory: libmf6.dylib
Processing initial chemistry configuration
Starting Solution at 2026-07-18 09:49:28
Transport | Stress period: 1 | Time step: 1 | Completed in : 0 min 2.08e-06 sec
Reactions | Stress period: 1 | Time step: 1 | Completed in : 0 min 2.56e-04 sec
Transport | Stress period: 1 | Time step: 2 | Completed in : 0 min 1.50e-06 sec
Reactions | Stress period: 1 | Time step: 2 | Completed in : 0 min 5.06e-05 sec
Transport | Stress period: 1 | Time step: 3 | Completed in : 0 min 1.48e-06 sec
Reactions | Stress period: 1 | Time step: 3 | Completed in : 0 min 4.95e-05 sec
Transport | Stress period: 1 | Time step: 4 | Completed in : 0 min 1.43e-06 sec
Reactions | Stress period: 1 | Time step: 4 | Completed in : 0 min 4.70e-05 sec
Transport | Stress period: 1 | Time step: 5 | Completed in : 0 min 1.43e-06 sec
Reactions | Stress period: 1 | Time step: 5 | Completed in : 0 min 4.59e-05 sec
Transport | Stress period: 1 | Time step: 6 | Completed in : 0 min 1.45e-06 sec
Reactions | Stress period: 1 | Time step: 6 | Completed in : 0 min 4.56e-05 sec
Transport | Stress period: 1 | Time step: 7 | Completed in : 0 min 1.45e-06 sec
Reactions | Stress period: 1 | Time step: 7 | Completed in : 0 min 4.55e-05 sec
Transport | Stress period: 1 | Time step: 8 | Completed in : 0 min 1.52e-06 sec
Reactions | Stress period: 1 | Time step: 8 | Completed in : 0 min 4.53e-05 sec
Transport | Stress period: 1 | Time step: 9 | Completed in : 0 min 1.47e-06 sec
Reactions | Stress period: 1 | Time step: 9 | Completed in : 0 min 4.64e-05 sec
Transport | Stress period: 1 | Time step: 10 | Completed in : 0 min 1.53e-06 sec
Reactions | Stress period: 1 | Time step: 10 | Completed in : 0 min 4.62e-05 sec
Transport | Stress period: 1 | Time step: 11 | Completed in : 0 min 1.93e-06 sec
Reactions | Stress period: 1 | Time step: 11 | Completed in : 0 min 4.65e-05 sec
Transport | Stress period: 1 | Time step: 12 | Completed in : 0 min 1.73e-06 sec
Reactions | Stress period: 1 | Time step: 12 | Completed in : 0 min 4.63e-05 sec
Transport | Stress period: 1 | Time step: 13 | Completed in : 0 min 1.45e-06 sec
Reactions | Stress period: 1 | Time step: 13 | Completed in : 0 min 4.73e-05 sec
Transport | Stress period: 1 | Time step: 14 | Completed in : 0 min 1.43e-06 sec
Reactions | Stress period: 1 | Time step: 14 | Completed in : 0 min 4.68e-05 sec
Transport | Stress period: 1 | Time step: 15 | Completed in : 0 min 1.43e-06 sec
Reactions | Stress period: 1 | Time step: 15 | Completed in : 0 min 4.66e-05 sec
Transport | Stress period: 1 | Time step: 16 | Completed in : 0 min 1.45e-06 sec
Reactions | Stress period: 1 | Time step: 16 | Completed in : 0 min 4.85e-05 sec
Transport | Stress period: 1 | Time step: 17 | Completed in : 0 min 1.55e-06 sec
Reactions | Stress period: 1 | Time step: 17 | Completed in : 0 min 5.62e-05 sec
Transport | Stress period: 1 | Time step: 18 | Completed in : 0 min 1.52e-06 sec
Reactions | Stress period: 1 | Time step: 18 | Completed in : 0 min 5.24e-05 sec
Transport | Stress period: 1 | Time step: 19 | Completed in : 0 min 1.82e-06 sec
Reactions | Stress period: 1 | Time step: 19 | Completed in : 0 min 4.96e-05 sec
Transport | Stress period: 1 | Time step: 20 | Completed in : 0 min 1.60e-06 sec
Reactions | Stress period: 1 | Time step: 20 | Completed in : 0 min 4.93e-05 sec
Transport | Stress period: 1 | Time step: 21 | Completed in : 0 min 1.45e-06 sec
Reactions | Stress period: 1 | Time step: 21 | Completed in : 0 min 5.02e-05 sec
Transport | Stress period: 1 | Time step: 22 | Completed in : 0 min 1.82e-06 sec
Reactions | Stress period: 1 | Time step: 22 | Completed in : 0 min 4.99e-05 sec
Transport | Stress period: 1 | Time step: 23 | Completed in : 0 min 1.55e-06 sec
Reactions | Stress period: 1 | Time step: 23 | Completed in : 0 min 5.13e-05 sec
Transport | Stress period: 1 | Time step: 24 | Completed in : 0 min 1.48e-06 sec
Reactions | Stress period: 1 | Time step: 24 | Completed in : 0 min 5.04e-05 sec
MODFLOW 6 converged successfully without any fails
WARNING: Element Mg is contained in Dolomite (which has 0.0 mass),
but is not in solution or other phases.
WARNING: Element Mg is contained in Dolomite (which has 0.0 mass),
but is not in solution or other phases.
WARNING: Element Mg is contained in Dolomite (which has 0.0 mass),
but is not in solution or other phases.
WARNING: Element Mg is contained in Dolomite (which has 0.0 mass),
but is not in solution or other phases.
WARNING: Element Mg is contained in Dolomite (which has 0.0 mass),
but is not in solution or other phases.
WARNING: Element Mg is contained in Dolomite (which has 0.0 mass),
but is not in solution or other phases.
WARNING: Element Mg is contained in Dolomite (which has 0.0 mass),
but is not in solution or other phases.
WARNING: Element Mg is contained in Dolomite (which has 0.0 mass),
but is not in solution or other phases.
WARNING: Element Mg is contained in Dolomite (which has 0.0 mass),
but is not in solution or other phases.
WARNING: Element Mg is contained in Dolomite (which has 0.0 mass),
but is not in solution or other phases.
WARNING: Element Mg is contained in Dolomite (which has 0.0 mass),
but is not in solution or other phases.
WARNING: Element Mg is contained in Dolomite (which has 0.0 mass),
but is not in solution or other phases.
WARNING: Element Mg is contained in Dolomite (which has 0.0 mass),
but is not in solution or other phases.
WARNING: Element Mg is contained in Dolomite (which has 0.0 mass),
but is not in solution or other phases.
WARNING: Element Mg is contained in Dolomite (which has 0.0 mass),
but is not in solution or other phases.
WARNING: Element Mg is contained in Dolomite (which has 0.0 mass),
but is not in solution or other phases.
WARNING: Element Mg is contained in Dolomite (which has 0.0 mass),
but is not in solution or other phases.
WARNING: Element Mg is contained in Dolomite (which has 0.0 mass),
but is not in solution or other phases.
WARNING: Element Mg is contained in Dolomite (which has 0.0 mass),
but is not in solution or other phases.
WARNING: Element Mg is contained in Dolomite (which has 0.0 mass),
but is not in solution or other phases.
WARNING: Element Mg is contained in Dolomite (which has 0.0 mass),
but is not in solution or other phases.
WARNING: Element Mg is contained in Dolomite (which has 0.0 mass),
but is not in solution or other phases.
WARNING: Element Mg is contained in Dolomite (which has 0.0 mass),
but is not in solution or other phases.
WARNING: Element Mg is contained in Dolomite (which has 0.0 mass),
but is not in solution or other phases.
WARNING: Element Mg is contained in Dolomite (which has 0.0 mass),
but is not in solution or other phases.
WARNING: Element Mg is contained in Dolomite (which has 0.0 mass),
but is not in solution or other phases.
WARNING: Element Mg is contained in Dolomite (which has 0.0 mass),
but is not in solution or other phases.
WARNING: Element Mg is contained in Dolomite (which has 0.0 mass),
but is not in solution or other phases.
WARNING: Element Mg is contained in Dolomite (which has 0.0 mass),
but is not in solution or other phases.
WARNING: Element Mg is contained in Dolomite (which has 0.0 mass),
but is not in solution or other phases.
WARNING: Element Mg is contained in Dolomite (which has 0.0 mass),
but is not in solution or other phases.
WARNING: Element Mg is contained in Dolomite (which has 0.0 mass),
but is not in solution or other phases.
WARNING: Element Mg is contained in Dolomite (which has 0.0 mass),
but is not in solution or other phases.
WARNING: Element Mg is contained in Dolomite (which has 0.0 mass),
but is not in solution or other phases.
WARNING: Element Mg is contained in Dolomite (which has 0.0 mass),
but is not in solution or other phases.
WARNING: Element Mg is contained in Dolomite (which has 0.0 mass),
but is not in solution or other phases.
WARNING: Element Mg is contained in Dolomite (which has 0.0 mass),
but is not in solution or other phases.
WARNING: Element Mg is contained in Dolomite (which has 0.0 mass),
but is not in solution or other phases.
WARNING: Element Mg is contained in Dolomite (which has 0.0 mass),
but is not in solution or other phases.
WARNING: Element Mg is contained in Dolomite (which has 0.0 mass),
but is not in solution or other phases.
WARNING: Element Mg is contained in Dolomite (which has 0.0 mass),
but is not in solution or other phases.
WARNING: Element Mg is contained in Dolomite (which has 0.0 mass),
but is not in solution or other phases.
WARNING: Element Mg is contained in Dolomite (which has 0.0 mass),
but is not in solution or other phases.
WARNING: Element Mg is contained in Dolomite (which has 0.0 mass),
but is not in solution or other phases.
WARNING: Element Mg is contained in Dolomite (which has 0.0 mass),
but is not in solution or other phases.
WARNING: Element Mg is contained in Dolomite (which has 0.0 mass),
but is not in solution or other phases.
WARNING: Element Mg is contained in Dolomite (which has 0.0 mass),
but is not in solution or other phases.
WARNING: Element Mg is contained in Dolomite (which has 0.0 mass),
but is not in solution or other phases.
WARNING: Element Mg is contained in Dolomite (which has 0.0 mass),
but is not in solution or other phases.
WARNING: Element Mg is contained in Dolomite (which has 0.0 mass),
but is not in solution or other phases.
WARNING: Maximum iterations exceeded, 100
WARNING: Numerical method failed with this set of convergence parameters.
WARNING: Trying smaller step size, pe step size 10, 5 ...
WARNING: Maximum iterations exceeded, 200
WARNING: Numerical method failed with this set of convergence parameters.
WARNING: Trying reduced tolerance 1e-16 ...
WARNING: Maximum iterations exceeded, 100
WARNING: Numerical method failed with this set of convergence parameters.
WARNING: Trying smaller step size, pe step size 10, 5 ...
WARNING: Maximum iterations exceeded, 200
WARNING: Numerical method failed with this set of convergence parameters.
WARNING: Trying reduced tolerance 1e-16 ...
WARNING: Maximum iterations exceeded, 100
WARNING: Numerical method failed with this set of convergence parameters.
WARNING: Trying smaller step size, pe step size 10, 5 ...
WARNING: Maximum iterations exceeded, 200
WARNING: Numerical method failed with this set of convergence parameters.
WARNING: Trying reduced tolerance 1e-16 ...
WARNING: Maximum iterations exceeded, 100
WARNING: Numerical method failed with this set of convergence parameters.
WARNING: Trying smaller step size, pe step size 10, 5 ...
WARNING: Maximum iterations exceeded, 200
WARNING: Numerical method failed with this set of convergence parameters.
WARNING: Trying reduced tolerance 1e-16 ...
WARNING: Maximum iterations exceeded, 200
WARNING: Numerical method failed with this set of convergence parameters.
WARNING: Trying increased tolerance 1e-14 ...
WARNING: Maximum iterations exceeded, 200
WARNING: Numerical method failed with this set of convergence parameters.
WARNING: Trying diagonal scaling ...
WARNING: Maximum iterations exceeded, 100
WARNING: Numerical method failed with this set of convergence parameters.
WARNING: Trying smaller step size, pe step size 10, 5 ...
WARNING: Maximum iterations exceeded, 200
WARNING: Numerical method failed with this set of convergence parameters.
WARNING: Trying reduced tolerance 1e-16 ...
WARNING: Maximum iterations exceeded, 200
WARNING: Numerical method failed with this set of convergence parameters.
WARNING: Trying increased tolerance 1e-14 ...
WARNING: Maximum iterations exceeded, 200
WARNING: Numerical method failed with this set of convergence parameters.
WARNING: Trying diagonal scaling ...
WARNING: Maximum iterations exceeded, 100
WARNING: Numerical method failed with this set of convergence parameters.
WARNING: Trying smaller step size, pe step size 10, 5 ...
WARNING: Maximum iterations exceeded, 200
WARNING: Numerical method failed with this set of convergence parameters.
WARNING: Trying reduced tolerance 1e-16 ...
WARNING: Maximum iterations exceeded, 200
WARNING: Numerical method failed with this set of convergence parameters.
WARNING: Trying increased tolerance 1e-14 ...
WARNING: Maximum iterations exceeded, 200
WARNING: Numerical method failed with this set of convergence parameters.
WARNING: Trying diagonal scaling ...
WARNING: Maximum iterations exceeded, 100
WARNING: Numerical method failed with this set of convergence parameters.
WARNING: Trying smaller step size, pe step size 10, 5 ...
WARNING: Maximum iterations exceeded, 200
WARNING: Numerical method failed with this set of convergence parameters.
WARNING: Trying reduced tolerance 1e-16 ...
WARNING: Maximum iterations exceeded, 200
WARNING: Numerical method failed with this set of convergence parameters.
WARNING: Trying increased tolerance 1e-14 ...
WARNING: Maximum iterations exceeded, 200
WARNING: Numerical method failed with this set of convergence parameters.
WARNING: Trying diagonal scaling ...
WARNING: Maximum iterations exceeded, 100
WARNING: Numerical method failed with this set of convergence parameters.
WARNING: Trying smaller step size, pe step size 10, 5 ...
WARNING: Maximum iterations exceeded, 200
WARNING: Numerical method failed with this set of convergence parameters.
WARNING: Trying reduced tolerance 1e-16 ...
WARNING: Maximum iterations exceeded, 200
WARNING: Numerical method failed with this set of convergence parameters.
WARNING: Trying increased tolerance 1e-14 ...
WARNING: Maximum iterations exceeded, 200
WARNING: Numerical method failed with this set of convergence parameters.
WARNING: Trying diagonal scaling ...
MODEL RUN FINISHED BUT CHECK THE RESULTS
Solution finished at 2026-07-18 09:49:28. Running time: 0.0030139 mins
True
7. Results¶
Read the selected-output table and plot the aqueous species and mineral amounts along the column at the final time.
sout = pd.read_csv(os.path.join(model.wd, "sout.csv"))
sout["x"] = (sout["col"] - 0.5) * delr # cell-center distance (m)
final = sout[sout["time_d"] == sout["time_d"].max()]
plot_vars = ["Ca", "Mg", "Cl", "C4", "Calcite", "Dolomite", "pH"]
fig, axs = plt.subplots(len(plot_vars), 1, figsize=(7, 1.9 * len(plot_vars)),
sharex=True)
for ax, var in zip(axs, plot_vars):
ax.plot(final["x"], final[var], color="tab:blue")
ax.set_ylabel(var)
ax.grid(alpha=0.3)
axs[-1].set_xlabel("distance (m)")
fig.suptitle("Dissolution fronts at t = %.2f d" % sout["time_d"].max())
fig.tight_layout()