or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

discretization.mdexport.mdfile-io.mdindex.mdmodflow2005.mdmodflow6.mdparticle-tracking.mdplotting.mdtransport.mdutilities.md

transport.mddocs/

0

# MT3DMS Transport Modeling

1

2

This module provides comprehensive support for MT3DMS and MT3D-USGS transport models with advection, dispersion, reactions, and specialized packages for complex transport scenarios. MT3DMS is the multi-species transport model for simulating contaminant fate and transport in groundwater systems.

3

4

## Core Model Class

5

6

### Mt3dms

7

8

Main MT3DMS model class that serves as a container for transport packages.

9

10

```python { .api }

11

class Mt3dms:

12

"""MT3DMS transport model container and execution manager"""

13

def __init__(

14

self,

15

modelname: str = 'mt3dtest',

16

namefile_ext: str = 'nam',

17

modflowmodel: object = None,

18

ftlfilename: str = 'mt3d_link.ftl',

19

ftlfree: bool = False,

20

version: str = 'mt3dms',

21

exe_name: str = 'mt3dms5',

22

structured: bool = True,

23

listunit: int = 16,

24

ftlunit: int = 10,

25

model_ws: str = '.',

26

external_path: str = None,

27

verbose: bool = False,

28

load: bool = True,

29

silent: int = 0,

30

**kwargs

31

): ...

32

33

def write_input(self, SelPackList: list = None, check: bool = True) -> None:

34

"""Write MT3DMS input files"""

35

...

36

37

def run_model(

38

self,

39

silent: bool = False,

40

pause: bool = False,

41

report: bool = False,

42

normal_msg: str = 'program completed'

43

) -> tuple[bool, list[str]]:

44

"""Run the MT3DMS model and return success status and output"""

45

...

46

47

@classmethod

48

def load(

49

cls,

50

f: str,

51

version: str = 'mt3dms',

52

exe_name: str = 'mt3dms5',

53

verbose: bool = False,

54

model_ws: str = '.',

55

load_only: list = None,

56

forgive: bool = False,

57

check: bool = True

58

) -> 'Mt3dms':

59

"""Load existing MT3DMS model from files"""

60

...

61

62

def add_package(self, p: object) -> None:

63

"""Add package to model"""

64

...

65

66

def remove_package(self, pname: str) -> None:

67

"""Remove package from model"""

68

...

69

70

def get_package(self, name: str) -> object:

71

"""Get package by name"""

72

...

73

74

@property

75

def modelgrid(self) -> object:

76

"""Model grid object"""

77

...

78

79

@property

80

def packages(self) -> list[object]:

81

"""List of model packages"""

82

...

83

84

@property

85

def ncomp(self) -> int:

86

"""Number of chemical components"""

87

...

88

89

@property

90

def nlay(self) -> int:

91

"""Number of layers"""

92

...

93

94

@property

95

def nrow(self) -> int:

96

"""Number of rows"""

97

...

98

99

@property

100

def ncol(self) -> int:

101

"""Number of columns"""

102

...

103

```

104

105

## Core Transport Packages

106

107

### Mt3dBtn

108

109

Basic transport package that defines fundamental transport parameters and component setup.

110

111

```python { .api }

112

class Mt3dBtn:

113

"""MT3DMS basic transport package"""

114

def __init__(

115

self,

116

model: Mt3dms,

117

nlay: int = 1,

118

nrow: int = 2,

119

ncol: int = 2,

120

nper: int = 1,

121

ncomp: int = 1,

122

mcomp: int = 1,

123

tunit: str = 'D',

124

lunit: str = 'M',

125

munit: str = 'KG',

126

laycon: ArrayData = 0,

127

delr: ArrayData = 1.0,

128

delc: ArrayData = 1.0,

129

htop: ArrayData = 1.0,

130

dz: ArrayData = 1.0,

131

prsity: ArrayData = 0.30,

132

icbund: ArrayData = 1,

133

sconc: ArrayData = 0.0,

134

cinact: float = -1e30,

135

thkmin: float = 0.01,

136

ifmtcn: int = 0,

137

ifmtnp: int = 0,

138

ifmtrf: int = 0,

139

ifmtdp: int = 0,

140

savucn: bool = True,

141

nprs: int = 0,

142

timprs: ArrayData = None,

143

obs: ArrayData = None,

144

nprobs: int = 1,

145

chkmas: bool = True,

146

nprmas: int = 1,

147

dt0: float = 0,

148

mxstrn: int = 50000,

149

ttsmult: float = 1.0,

150

ttsmax: float = 0,

151

species_names: list[str] = None,

152

extension: str = 'btn',

153

unitnumber: int = None,

154

filenames: str = None,

155

**kwargs

156

): ...

157

```

158

159

**Parameters:**

160

- `ncomp` (int): Number of mobile species

161

- `mcomp` (int): Total number of species (mobile + immobile)

162

- `tunit` (str): Time unit ('S', 'M', 'H', 'D', 'Y')

163

- `lunit` (str): Length unit ('CM', 'M', 'KM', 'FT', 'MI')

164

- `munit` (str): Mass unit ('G', 'KG', 'LB', 'TON')

165

- `prsity` (ArrayData): Effective porosity

166

- `icbund` (ArrayData): Boundary condition array

167

- `sconc` (ArrayData): Starting concentration

168

169

## Process Packages

170

171

### Mt3dAdv

172

173

Advection package for simulating solute transport by groundwater flow.

174

175

```python { .api }

176

class Mt3dAdv:

177

"""MT3DMS advection package"""

178

def __init__(

179

self,

180

model: Mt3dms,

181

mixelm: int = 3,

182

percel: float = 0.75,

183

mxpart: int = 800000,

184

nadvfd: int = 1,

185

itrack: int = 3,

186

wd: float = 0.5,

187

dceps: float = 1e-5,

188

nplane: int = 2,

189

npl: int = 10,

190

nph: int = 40,

191

npmin: int = 5,

192

npmax: int = 80,

193

nlsink: int = None,

194

npsink: int = None,

195

dchmoc: float = 1e-3,

196

extension: str = 'adv',

197

unitnumber: int = None,

198

filenames: str = None,

199

**kwargs

200

): ...

201

```

202

203

**Parameters:**

204

- `mixelm` (int): Advection solution method

205

- -1: Implicit finite difference

206

- 0: Method of characteristics (MOC)

207

- 1: Modified method of characteristics (MMOC)

208

- 2: Hybrid method of characteristics (HMOC)

209

- 3: Third-order TVD scheme (default)

210

- `percel` (float): Courant number for advection

211

- `mxpart` (int): Maximum number of particles

212

213

### Mt3dDsp

214

215

Dispersion package for modeling mechanical dispersion and molecular diffusion.

216

217

```python { .api }

218

class Mt3dDsp:

219

"""MT3DMS dispersion package"""

220

def __init__(

221

self,

222

model: Mt3dms,

223

al: ArrayData = 0.01,

224

trpt: ArrayData = 0.1,

225

trpv: ArrayData = 0.01,

226

dmcoef: ArrayData = 0.0,

227

multiDiff: bool = False,

228

extension: str = 'dsp',

229

unitnumber: int = None,

230

filenames: str = None,

231

**kwargs

232

): ...

233

```

234

235

**Parameters:**

236

- `al` (ArrayData): Longitudinal dispersivity

237

- `trpt` (ArrayData): Ratio of horizontal transverse to longitudinal dispersivity

238

- `trpv` (ArrayData): Ratio of vertical transverse to longitudinal dispersivity

239

- `dmcoef` (ArrayData): Molecular diffusion coefficient

240

241

### Mt3dSsm

242

243

Source/sink mixing package for handling mass loading from boundary conditions.

244

245

```python { .api }

246

class Mt3dSsm:

247

"""MT3DMS source/sink mixing package"""

248

def __init__(

249

self,

250

model: Mt3dms,

251

crch: ArrayData = None,

252

cevt: ArrayData = None,

253

mxss: int = None,

254

stress_period_data: dict = None,

255

dtype: np.dtype = None,

256

extension: str = 'ssm',

257

unitnumber: int = None,

258

filenames: str = None,

259

**kwargs

260

): ...

261

```

262

263

**Parameters:**

264

- `crch` (ArrayData): Concentration in recharge

265

- `cevt` (ArrayData): Concentration in evapotranspiration

266

- `stress_period_data` (dict): Source/sink data by stress period

267

- Format: {period: [[k, i, j, css, itype, (cssm)], ...]}

268

- `css`: Source/sink concentration

269

- `itype`: Source/sink type

270

271

### Mt3dRct

272

273

Chemical reactions package for simulating decay, sorption, and other reactions.

274

275

```python { .api }

276

class Mt3dRct:

277

"""MT3DMS chemical reactions package"""

278

def __init__(

279

self,

280

model: Mt3dms,

281

isothm: int = 0,

282

ireact: int = 0,

283

igetsc: int = 0,

284

rhob: ArrayData = 1.8,

285

prsity2: ArrayData = None,

286

srconc: ArrayData = None,

287

sp1: ArrayData = None,

288

sp2: ArrayData = None,

289

rc1: ArrayData = None,

290

rc2: ArrayData = None,

291

extension: str = 'rct',

292

unitnumber: int = None,

293

filenames: str = None,

294

**kwargs

295

): ...

296

```

297

298

**Parameters:**

299

- `isothm` (int): Sorption isotherm type

300

- 0: No sorption

301

- 1: Linear isotherm

302

- 2: Freundlich isotherm

303

- 3: Langmuir isotherm

304

- 4: First-order kinetic sorption

305

- `ireact` (int): Kinetic rate reaction type

306

- `rhob` (ArrayData): Bulk density

307

- `sp1` (ArrayData): First sorption parameter

308

- `sp2` (ArrayData): Second sorption parameter

309

- `rc1` (ArrayData): First-order reaction rate

310

311

## Solver Package

312

313

### Mt3dGcg

314

315

Generalized conjugate gradient solver for the matrix equations.

316

317

```python { .api }

318

class Mt3dGcg:

319

"""MT3DMS generalized conjugate gradient solver"""

320

def __init__(

321

self,

322

model: Mt3dms,

323

mxiter: int = 1,

324

iter1: int = 50,

325

isolve: int = 3,

326

ncrs: int = 0,

327

accl: float = 1.0,

328

cclose: float = 1e-5,

329

iprgcg: int = 0,

330

extension: str = 'gcg',

331

unitnumber: int = None,

332

filenames: str = None,

333

**kwargs

334

): ...

335

```

336

337

**Parameters:**

338

- `mxiter` (int): Maximum outer iterations

339

- `iter1` (int): Maximum inner iterations

340

- `isolve` (int): Solver type

341

- 1: Jacobi

342

- 2: SSOR

343

- 3: Modified incomplete Cholesky (MIC)

344

- `cclose` (float): Closure criterion

345

- `accl` (float): Acceleration parameter

346

347

## Observation Package

348

349

### Mt3dTob

350

351

Transport observation package for model calibration and analysis.

352

353

```python { .api }

354

class Mt3dTob:

355

"""MT3DMS transport observations package"""

356

def __init__(

357

self,

358

model: Mt3dms,

359

outnam: str = 'mt3d_obs.out',

360

CScale: float = 1.0,

361

FluxGroups: int = 0,

362

FScale: float = 1.0,

363

iOutFlux: int = 0,

364

obs_data: list = None,

365

extension: str = 'tob',

366

no_print: bool = False,

367

unitnumber: int = None,

368

filenames: str = None,

369

**kwargs

370

): ...

371

```

372

373

## Advanced Transport Packages

374

375

### Mt3dSft

376

377

Streamflow transport package for stream-aquifer solute exchange.

378

379

```python { .api }

380

class Mt3dSft:

381

"""MT3DMS streamflow transport package"""

382

def __init__(

383

self,

384

model: Mt3dms,

385

nsfinit: int = 0,

386

mxsfbc: int = 0,

387

icbcsf: int = 0,

388

ioutobs: int = 0,

389

ietsfr: int = 0,

390

isfsolv: int = 1,

391

cclosesf: float = 1e-6,

392

mxitersf: int = 10,

393

crntsf: float = 1.0,

394

iprtxmd: int = 0,

395

coldsf: ArrayData = 0.0,

396

dispsf: ArrayData = 0.0,

397

nobssf: int = 0,

398

obs_sf: list = None,

399

sf_stress_period_data: dict = None,

400

extension: str = 'sft',

401

unitnumber: int = None,

402

filenames: str = None,

403

**kwargs

404

): ...

405

```

406

407

### Mt3dLkt

408

409

Lake transport package for lake-aquifer solute exchange.

410

411

```python { .api }

412

class Mt3dLkt:

413

"""MT3DMS lake transport package"""

414

def __init__(

415

self,

416

model: Mt3dms,

417

nlkinit: int = 0,

418

mxlkbc: int = 0,

419

icbclk: int = 0,

420

ietlak: int = 0,

421

coldlk: ArrayData = 0.0,

422

lk_stress_period_data: dict = None,

423

extension: str = 'lkt',

424

unitnumber: int = None,

425

filenames: str = None,

426

**kwargs

427

): ...

428

```

429

430

### Mt3dUzt

431

432

Unsaturated zone transport package.

433

434

```python { .api }

435

class Mt3dUzt:

436

"""MT3DMS unsaturated zone transport package"""

437

def __init__(

438

self,

439

model: Mt3dms,

440

iuzfbnd: ArrayData = None,

441

cuzinf: ArrayData = 0.0,

442

cuzet: ArrayData = 0.0,

443

cgwet: ArrayData = 0.0,

444

extension: str = 'uzt',

445

unitnumber: int = None,

446

filenames: str = None,

447

**kwargs

448

): ...

449

```

450

451

### Mt3dPhc

452

453

PHC3D reactions package for advanced geochemical modeling.

454

455

```python { .api }

456

class Mt3dPhc:

457

"""MT3DMS PHC3D reactions package"""

458

def __init__(

459

self,

460

model: Mt3dms,

461

os: int = 2,

462

temp: ArrayData = 25.0,

463

asbin: ArrayData = None,

464

Prime: ArrayData = None,

465

extension: str = 'phc',

466

unitnumber: int = None,

467

filenames: str = None,

468

**kwargs

469

): ...

470

```

471

472

## Usage Examples

473

474

### Basic Single-Species Transport Model

475

476

```python

477

import flopy

478

import numpy as np

479

480

# Create MODFLOW model first (required for transport)

481

mf = flopy.modflow.Modflow(modelname='transport_base')

482

483

# Basic MODFLOW setup

484

nlay, nrow, ncol = 1, 50, 100

485

dis = flopy.modflow.ModflowDis(

486

mf, nlay=nlay, nrow=nrow, ncol=ncol,

487

delr=10.0, delc=10.0, top=10.0, botm=0.0

488

)

489

bas = flopy.modflow.ModflowBas(mf, ibound=1, strt=5.0)

490

lpf = flopy.modflow.ModflowLpf(mf, hk=1.0, sy=0.1, ss=1e-5)

491

pcg = flopy.modflow.ModflowPcg(mf)

492

oc = flopy.modflow.ModflowOc(mf)

493

494

# Write and run MODFLOW

495

mf.write_input()

496

success, buff = mf.run_model()

497

498

# Create MT3DMS model

499

mt = flopy.mt3d.Mt3dms(

500

modelname='transport',

501

modflowmodel=mf,

502

ftlfilename='mt3d_link.ftl'

503

)

504

505

# Basic transport package

506

btn = flopy.mt3d.Mt3dBtn(

507

mt,

508

ncomp=1, # Single species

509

prsity=0.25,

510

icbund=1, # Active transport cells

511

sconc=0.0, # Starting concentration

512

timprs=np.array([100.0, 200.0, 500.0, 1000.0]), # Output times

513

nprs=4,

514

chkmas=True,

515

nprmas=1

516

)

517

518

# Advection package

519

adv = flopy.mt3d.Mt3dAdv(

520

mt,

521

mixelm=3, # TVD scheme

522

percel=0.75,

523

nadvfd=1

524

)

525

526

# Dispersion package

527

dsp = flopy.mt3d.Mt3dDsp(

528

mt,

529

al=0.5, # Longitudinal dispersivity

530

trpt=0.1, # Transverse/longitudinal ratio

531

dmcoef=1e-9 # Molecular diffusion

532

)

533

534

# Source/sink mixing - contaminant source

535

ssm_data = {}

536

# Injection well at center with contamination

537

ssm_data[0] = [

538

[0, 25, 50, 1000.0, 2] # Layer, row, col, concentration, type (2=well)

539

]

540

ssm = flopy.mt3d.Mt3dSsm(mt, stress_period_data=ssm_data)

541

542

# Solver

543

gcg = flopy.mt3d.Mt3dGcg(mt, mxiter=1, iter1=50, cclose=1e-5)

544

545

# Write and run MT3DMS

546

mt.write_input()

547

success, buff = mt.run_model()

548

```

549

550

### Multi-Species Reactive Transport Model

551

552

```python

553

import flopy

554

import numpy as np

555

556

# Create base MODFLOW model (abbreviated)

557

mf = flopy.modflow.Modflow(modelname='reactive_transport')

558

# ... MODFLOW setup code ...

559

560

# Multi-species MT3DMS model

561

mt = flopy.mt3d.Mt3dms(

562

modelname='reactive_mt',

563

modflowmodel=mf

564

)

565

566

# Multiple species setup

567

ncomp = 3 # Parent compound + 2 decay products

568

species_names = ['PCE', 'TCE', 'DCE']

569

570

btn = flopy.mt3d.Mt3dBtn(

571

mt,

572

ncomp=ncomp,

573

mcomp=ncomp,

574

species_names=species_names,

575

prsity=0.30,

576

icbund=1,

577

sconc=[[0.0] * ncol * nrow] * ncomp, # Zero initial concentration

578

timprs=np.logspace(0, 3, 20), # Logarithmic time spacing

579

savucn=True

580

)

581

582

# Advection

583

adv = flopy.mt3d.Mt3dAdv(

584

mt,

585

mixelm=0, # MOC for accuracy with reactions

586

percel=0.5,

587

mxpart=100000

588

)

589

590

# Dispersion - different for each species

591

al = [1.0, 0.8, 0.6] # Decreasing dispersivity with molecular size

592

dsp = flopy.mt3d.Mt3dDsp(

593

mt,

594

al=al,

595

trpt=0.1,

596

dmcoef=[1e-9, 1.2e-9, 1.5e-9] # Increasing diffusion

597

)

598

599

# Reactions - sequential decay chain

600

# PCE -> TCE -> DCE

601

rct = flopy.mt3d.Mt3dRct(

602

mt,

603

isothm=1, # Linear sorption

604

ireact=1, # First-order decay

605

rhob=1.8, # Bulk density

606

sp1=[[0.5, 0.3, 0.1]], # Kd values (decreasing sorption)

607

rc1=[

608

[0.01, 0.0, 0.0], # PCE decay rate

609

[0.0, 0.02, 0.0], # TCE decay rate

610

[0.0, 0.0, 0.05] # DCE decay rate

611

],

612

rc2=[

613

[0.0, 0.01, 0.0], # PCE -> TCE yield

614

[0.0, 0.0, 0.02], # TCE -> DCE yield

615

[0.0, 0.0, 0.0] # DCE -> end products

616

]

617

)

618

619

# Source with declining concentration

620

ssm_data = {}

621

for kper in range(10): # 10 stress periods

622

# Exponentially declining source

623

conc = 1000.0 * np.exp(-0.1 * kper)

624

ssm_data[kper] = [

625

[0, 10, 20, conc, 2, 0.0, 0.0] # Only PCE injected

626

]

627

628

ssm = flopy.mt3d.Mt3dSsm(mt, stress_period_data=ssm_data)

629

630

# Solver

631

gcg = flopy.mt3d.Mt3dGcg(

632

mt,

633

mxiter=1,

634

iter1=100,

635

isolve=3,

636

cclose=1e-6

637

)

638

639

# Observations at multiple locations

640

obs_data = []

641

# Monitoring wells at different distances

642

for i, dist in enumerate([50, 100, 200]):

643

row = 25

644

col = 20 + dist // 10

645

obs_data.append(['MW_{}'.format(i+1), 0, row, col])

646

647

tob = flopy.mt3d.Mt3dTob(

648

mt,

649

obs_data=obs_data,

650

outnam='reactive_obs.out'

651

)

652

653

# Write and run

654

mt.write_input()

655

success, buff = mt.run_model()

656

```

657

658

### Stream-Aquifer Transport Interaction

659

660

```python

661

import flopy

662

import numpy as np

663

664

# MODFLOW model with SFR package (abbreviated setup)

665

mf = flopy.modflow.Modflow(modelname='stream_transport')

666

# ... discretization, basic, lpf packages ...

667

668

# Add SFR package for stream routing

669

# Stream reaches along model diagonal

670

reach_data = []

671

segment_data = {}

672

for i in range(50): # 50 reaches

673

row = i

674

col = i

675

reach_data.append([

676

1, i+1, row, col, 5.0, 1.0, 0.001, 2.0, 1.0, 0.03, 0.5, 0.5

677

])

678

679

segment_data[0] = {

680

1: [1, 1, 0, 100.0, 0.0, 0.0, 0.0, 'stream_seg']

681

}

682

683

sfr = flopy.modflow.ModflowSfr2(

684

mf,

685

nstrm=50,

686

nss=1,

687

reach_data=np.array(reach_data, dtype=flopy.modflow.ModflowSfr2.get_default_reach_dtype()),

688

segment_data=segment_data

689

)

690

691

# Run MODFLOW

692

mf.write_input()

693

success, buff = mf.run_model()

694

695

# MT3DMS with stream transport

696

mt = flopy.mt3d.Mt3dms(

697

modelname='stream_mt',

698

modflowmodel=mf

699

)

700

701

# Basic transport

702

btn = flopy.mt3d.Mt3dBtn(

703

mt,

704

ncomp=1,

705

prsity=0.25,

706

sconc=0.0,

707

timprs=np.array([10.0, 30.0, 100.0, 365.0])

708

)

709

710

# Advection and dispersion

711

adv = flopy.mt3d.Mt3dAdv(mt, mixelm=3)

712

dsp = flopy.mt3d.Mt3dDsp(mt, al=2.0, trpt=0.1)

713

714

# Stream transport package

715

sf_data = {}

716

# Initial stream concentration and dispersion

717

nsfinit = 50 # Number of stream reaches

718

coldsf = np.ones(nsfinit) * 500.0 # Initial stream concentration

719

dispsf = np.ones(nsfinit) * 10.0 # Stream dispersion coefficient

720

721

# Stream boundary conditions by stress period

722

sf_stress_data = {}

723

for kper in range(4):

724

# Upstream inflow concentration varies seasonally

725

if kper == 0: # Spring - high concentration

726

inflow_conc = 800.0

727

elif kper == 1: # Summer - medium concentration

728

inflow_conc = 400.0

729

elif kper == 2: # Fall - low concentration

730

inflow_conc = 200.0

731

else: # Winter - medium concentration

732

inflow_conc = 500.0

733

734

sf_stress_data[kper] = [

735

[1, 1, inflow_conc, 2] # Segment, reach, concentration, type

736

]

737

738

sft = flopy.mt3d.Mt3dSft(

739

mt,

740

nsfinit=nsfinit,

741

mxsfbc=20,

742

coldsf=coldsf,

743

dispsf=dispsf,

744

sf_stress_period_data=sf_stress_data

745

)

746

747

# Source/sink mixing for groundwater-stream interaction

748

ssm_data = {}

749

# Point source in aquifer

750

ssm_data[0] = [

751

[0, 10, 10, 2000.0, 2] # High concentration injection

752

]

753

ssm = flopy.mt3d.Mt3dSsm(mt, stress_period_data=ssm_data)

754

755

# Solver

756

gcg = flopy.mt3d.Mt3dGcg(mt)

757

758

# Run transport model

759

mt.write_input()

760

success, buff = mt.run_model()

761

```

762

763

### Advanced Geochemical Modeling with PHC3D

764

765

```python

766

import flopy

767

import numpy as np

768

769

# Complex reactive transport with PHC3D

770

mf = flopy.modflow.Modflow(modelname='geochemical_model')

771

# ... MODFLOW setup ...

772

773

# Multi-component reactive system

774

mt = flopy.mt3d.Mt3dms(modelname='geochemical_mt', modflowmodel=mf)

775

776

# Multiple chemical species

777

ncomp = 6 # Multiple interacting species

778

species_names = ['Ca', 'CO3', 'H', 'CaCO3', 'CaHCO3', 'HCO3']

779

780

btn = flopy.mt3d.Mt3dBtn(

781

mt,

782

ncomp=ncomp,

783

mcomp=ncomp,

784

species_names=species_names,

785

prsity=0.25,

786

# Initial concentrations from equilibrium calculations

787

sconc=[

788

[1.0e-3] * (nrow * ncol), # Ca concentration

789

[1.0e-4] * (nrow * ncol), # CO3 concentration

790

[1.0e-7] * (nrow * ncol), # H concentration (pH 7)

791

[0.0] * (nrow * ncol), # CaCO3 (mineral)

792

[1.0e-4] * (nrow * ncol), # CaHCO3 complex

793

[1.0e-3] * (nrow * ncol) # HCO3 concentration

794

]

795

)

796

797

# Transport processes

798

adv = flopy.mt3d.Mt3dAdv(mt, mixelm=3)

799

dsp = flopy.mt3d.Mt3dDsp(mt, al=1.0, trpt=0.1)

800

801

# PHC3D for geochemical reactions

802

# Temperature field

803

temp = np.ones((nlay, nrow, ncol)) * 25.0 # 25°C

804

805

# Specify which species are in equilibrium vs kinetic

806

os_flag = 2 # Mixed equilibrium-kinetic system

807

808

phc = flopy.mt3d.Mt3dPhc(

809

mt,

810

os=os_flag,

811

temp=temp

812

)

813

814

# Source with varying chemistry

815

ssm_data = {}

816

for kper in range(5):

817

# Injection with different pH values

818

ca_conc = 2.0e-3

819

co3_conc = 5.0e-4

820

h_conc = 1.0e-6 * (10 ** (kper - 2)) # pH 4-8 range

821

822

ssm_data[kper] = [

823

[0, 25, 50, ca_conc, 2, co3_conc, h_conc, 0.0, 0.0, 0.0]

824

]

825

826

ssm = flopy.mt3d.Mt3dSsm(mt, stress_period_data=ssm_data)

827

828

# Specialized solver for reactive transport

829

gcg = flopy.mt3d.Mt3dGcg(

830

mt,

831

mxiter=1,

832

iter1=200, # More iterations for convergence

833

isolve=3,

834

cclose=1e-7 # Tighter convergence

835

)

836

837

# Write and run

838

mt.write_input()

839

success, buff = mt.run_model()

840

```

841

842

## Common Types

843

844

```python { .api }

845

# Transport-specific types

846

ConcentrationArray = Union[float, list[float], np.ndarray]

847

ReactionParameter = Union[float, list[float], np.ndarray]

848

SpeciesData = list[ConcentrationArray]

849

850

# Boundary condition types

851

SourceSinkData = list[list[Union[int, float]]]

852

StreamTransportData = dict[int, list[list[Union[int, float]]]]

853

ObservationData = list[list[Union[str, int, float]]]

854

855

# Reaction types

856

IsothermType = Literal[0, 1, 2, 3, 4] # None, Linear, Freundlich, Langmuir, Kinetic

857

ReactionType = int

858

SolverType = Literal[1, 2, 3] # Jacobi, SSOR, MIC

859

860

# Advection methods

861

AdvectionMethod = Literal[-1, 0, 1, 2, 3] # FD, MOC, MMOC, HMOC, TVD

862

863

# Time and mass units

864

TimeUnit = Literal['S', 'M', 'H', 'D', 'Y']

865

LengthUnit = Literal['CM', 'M', 'KM', 'FT', 'MI']

866

MassUnit = Literal['G', 'KG', 'LB', 'TON']

867

868

# File format types

869

FileFormat = Literal['formatted', 'unformatted']

870

OutputFormat = int

871

```

872

873

This comprehensive documentation covers the complete MT3DMS transport modeling API including all packages, reaction types, and usage patterns. The examples demonstrate basic to advanced transport scenarios including multi-species systems, reactive transport, and coupled surface water-groundwater transport.