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

export.mddocs/

0

# Data Export Capabilities

1

2

This module provides comprehensive export functionality for model grids, arrays, and results to various formats including NetCDF, VTK, shapefiles, and other GIS-compatible formats. These tools enable interoperability with other modeling software, GIS systems, and visualization platforms.

3

4

## NetCDF Export

5

6

### NetCdf

7

8

Primary class for exporting MODFLOW models and results to NetCDF format.

9

10

```python { .api }

11

class NetCdf:

12

"""NetCDF export functionality for MODFLOW models"""

13

def __init__(

14

self,

15

output_filename: str,

16

model: object,

17

array_dict: dict = None,

18

meshtype: str = None,

19

**kwargs

20

): ...

21

22

def write(self) -> None:

23

"""Write model and data to NetCDF file"""

24

...

25

26

def add_model(self, model: object) -> None:

27

"""Add model to NetCDF file"""

28

...

29

30

def add_package(

31

self,

32

package: object,

33

text: str = None,

34

**kwargs

35

) -> None:

36

"""Add package data to NetCDF file"""

37

...

38

39

def add_transient_array(

40

self,

41

array: np.ndarray,

42

name: str,

43

units: str = None,

44

**kwargs

45

) -> None:

46

"""Add time-varying array data"""

47

...

48

49

def add_array(

50

self,

51

array: np.ndarray,

52

name: str,

53

units: str = None,

54

**kwargs

55

) -> None:

56

"""Add array data to NetCDF file"""

57

...

58

59

def add_grid(

60

self,

61

grid: object,

62

**kwargs

63

) -> None:

64

"""Add grid information to NetCDF file"""

65

...

66

67

def add_coordinate_system(

68

self,

69

epsg: int = None,

70

proj4_str: str = None,

71

**kwargs

72

) -> None:

73

"""Add coordinate reference system"""

74

...

75

76

@property

77

def nc(self) -> object:

78

"""NetCDF4 Dataset object"""

79

...

80

81

@property

82

def logger(self) -> object:

83

"""Export logger"""

84

...

85

```

86

87

### Logger

88

89

Logging functionality for export operations.

90

91

```python { .api }

92

class Logger:

93

"""Logging for export operations"""

94

def __init__(

95

self,

96

level: str = 'INFO',

97

filename: str = None,

98

**kwargs

99

): ...

100

101

def info(self, message: str) -> None:

102

"""Log info message"""

103

...

104

105

def warning(self, message: str) -> None:

106

"""Log warning message"""

107

...

108

109

def error(self, message: str) -> None:

110

"""Log error message"""

111

...

112

113

def debug(self, message: str) -> None:

114

"""Log debug message"""

115

...

116

```

117

118

## VTK Export

119

120

### Vtk

121

122

VTK format export for 3D visualization and analysis.

123

124

```python { .api }

125

class Vtk:

126

"""VTK format export for MODFLOW models"""

127

def __init__(

128

self,

129

model: object = None,

130

modelgrid: object = None,

131

vertical_exageration: float = 1.0,

132

binary: bool = True,

133

smooth: bool = False,

134

point_scalars: bool = False,

135

fmt: str = None,

136

**kwargs

137

): ...

138

139

def add_model(self, model: object) -> None:

140

"""Add model to VTK export"""

141

...

142

143

def add_array(

144

self,

145

array: np.ndarray,

146

name: str,

147

**kwargs

148

) -> None:

149

"""Add array data for export"""

150

...

151

152

def add_transient_array(

153

self,

154

d: dict,

155

name: str,

156

**kwargs

157

) -> None:

158

"""Add time-varying array data"""

159

...

160

161

def add_vector(

162

self,

163

vectors: tuple[np.ndarray, np.ndarray, np.ndarray],

164

name: str,

165

**kwargs

166

) -> None:

167

"""Add vector field data"""

168

...

169

170

def add_pathline_points(

171

self,

172

pathlines: list,

173

**kwargs

174

) -> None:

175

"""Add MODPATH pathline data"""

176

...

177

178

def add_endpoint_points(

179

self,

180

endpoints: np.ndarray,

181

**kwargs

182

) -> None:

183

"""Add MODPATH endpoint data"""

184

...

185

186

def write(

187

self,

188

filename: str,

189

**kwargs

190

) -> None:

191

"""Write VTK file"""

192

...

193

194

@property

195

def arrays(self) -> dict:

196

"""Dictionary of arrays for export"""

197

...

198

```

199

200

### Pvd

201

202

ParaView data file management for time series VTK files.

203

204

```python { .api }

205

class Pvd:

206

"""ParaView data file management"""

207

def __init__(

208

self,

209

filename: str,

210

**kwargs

211

): ...

212

213

def add_dataset(

214

self,

215

filename: str,

216

timestep: float,

217

**kwargs

218

) -> None:

219

"""Add VTK dataset to time series"""

220

...

221

222

def write(self) -> None:

223

"""Write PVD file"""

224

...

225

```

226

227

## Shapefile Export

228

229

### Shapefile Utilities

230

231

Functions for exporting model data to ESRI shapefile format.

232

233

```python { .api }

234

def write_grid_shapefile(

235

filename: str,

236

mg: object,

237

array_dict: dict = None,

238

**kwargs

239

) -> None:

240

"""Export model grid to shapefile"""

241

...

242

243

def write_shapefile(

244

filename: str,

245

geoms: list,

246

attribute_dict: dict = None,

247

**kwargs

248

) -> None:

249

"""Write geometries and attributes to shapefile"""

250

...

251

252

def model_attributes_to_shapefile(

253

filename: str,

254

ml: object,

255

package_names: list = None,

256

array_dict: dict = None,

257

**kwargs

258

) -> None:

259

"""Export model attributes to shapefile"""

260

...

261

262

def package_export_shapefile(

263

pak: object,

264

filename: str,

265

**kwargs

266

) -> None:

267

"""Export package data to shapefile"""

268

...

269

270

def boundary_condition_export(

271

filename: str,

272

pak: object,

273

kper: int = 0,

274

**kwargs

275

) -> None:

276

"""Export boundary condition data to shapefile"""

277

...

278

```

279

280

## Metadata Standards

281

282

### acdd

283

284

Attribute Convention for Data Discovery (ACDD) metadata standards.

285

286

```python { .api }

287

class acdd:

288

"""ACDD metadata standards for export files"""

289

290

@staticmethod

291

def get_standard_attributes() -> dict:

292

"""Get standard ACDD attributes"""

293

...

294

295

@staticmethod

296

def create_attributes(

297

title: str,

298

summary: str,

299

institution: str = None,

300

source: str = None,

301

**kwargs

302

) -> dict:

303

"""Create ACDD-compliant attribute dictionary"""

304

...

305

306

@staticmethod

307

def add_global_attributes(

308

nc_file: object,

309

attributes: dict,

310

**kwargs

311

) -> None:

312

"""Add global attributes to NetCDF file"""

313

...

314

```

315

316

## High-Level Export Functions

317

318

```python { .api }

319

def model_export(

320

filename: str,

321

model: object,

322

fmt: str = 'netcdf',

323

**kwargs

324

) -> None:

325

"""Export complete model to specified format"""

326

...

327

328

def package_export(

329

filename: str,

330

package: object,

331

fmt: str = 'netcdf',

332

**kwargs

333

) -> None:

334

"""Export individual package to specified format"""

335

...

336

337

def array2d_export(

338

filename: str,

339

array: np.ndarray,

340

modelgrid: object,

341

**kwargs

342

) -> None:

343

"""Export 2D array with grid information"""

344

...

345

346

def array3d_export(

347

filename: str,

348

array: np.ndarray,

349

modelgrid: object,

350

**kwargs

351

) -> None:

352

"""Export 3D array with grid information"""

353

...

354

355

def export_array(

356

filename: str,

357

array: np.ndarray,

358

fmt: str = 'netcdf',

359

**kwargs

360

) -> None:

361

"""Generic array export function"""

362

...

363

364

def export_contours(

365

filename: str,

366

array: np.ndarray,

367

levels: list = None,

368

modelgrid: object = None,

369

**kwargs

370

) -> None:

371

"""Export contour data to shapefile"""

372

...

373

```

374

375

## Usage Examples

376

377

### Basic NetCDF Export

378

379

```python

380

import flopy

381

import flopy.export as fpe

382

import numpy as np

383

384

# Load or create MODFLOW model

385

mf = flopy.modflow.Modflow.load('model.nam')

386

387

# Basic NetCDF export

388

nc_file = fpe.NetCdf('model_export.nc', mf)

389

390

# Add model grid and packages

391

nc_file.add_model(mf)

392

393

# Add arrays from packages

394

if hasattr(mf, 'lpf'):

395

nc_file.add_array(mf.lpf.hk.array, 'hydraulic_conductivity', units='m/day')

396

nc_file.add_array(mf.lpf.sy.array, 'specific_yield', units='dimensionless')

397

398

if hasattr(mf, 'dis'):

399

nc_file.add_array(mf.dis.top.array, 'top_elevation', units='m')

400

nc_file.add_array(mf.dis.botm.array, 'bottom_elevation', units='m')

401

402

# Add coordinate system information

403

nc_file.add_coordinate_system(epsg=32633) # UTM Zone 33N

404

405

# Write the NetCDF file

406

nc_file.write()

407

408

print("NetCDF export completed: model_export.nc")

409

```

410

411

### Advanced NetCDF Export with Results

412

413

```python

414

import flopy

415

import flopy.export as fpe

416

import flopy.utils as fpu

417

import numpy as np

418

419

# Load model and results

420

mf = flopy.modflow.Modflow.load('model.nam')

421

422

# Read head and budget files

423

hds = fpu.HeadFile('model.hds')

424

cbb = fpu.CellBudgetFile('model.cbb')

425

426

# Create NetCDF export with metadata

427

nc_file = fpe.NetCdf(

428

'complete_model_export.nc',

429

mf,

430

array_dict=None,

431

meshtype='structured'

432

)

433

434

# Add ACDD metadata

435

metadata = fpe.acdd.create_attributes(

436

title='Regional Groundwater Flow Model',

437

summary='Three-dimensional groundwater flow model for water resource assessment',

438

institution='University Research Center',

439

source='MODFLOW-2005',

440

creator_name='Jane Doe',

441

creator_email='jane.doe@university.edu',

442

project='Regional Water Study',

443

geospatial_bounds='POLYGON((...))'

444

)

445

446

fpe.acdd.add_global_attributes(nc_file.nc, metadata)

447

448

# Add model structure

449

nc_file.add_model(mf)

450

451

# Add static arrays

452

array_dict = {

453

'hydraulic_conductivity': (mf.lpf.hk.array, 'm/day'),

454

'specific_yield': (mf.lpf.sy.array, 'dimensionless'),

455

'specific_storage': (mf.lpf.ss.array, '1/m'),

456

'top_elevation': (mf.dis.top.array, 'm'),

457

'bottom_elevation': (mf.dis.botm.array, 'm'),

458

'porosity': (np.ones(mf.dis.botm.array.shape) * 0.25, 'dimensionless')

459

}

460

461

for name, (array, units) in array_dict.items():

462

nc_file.add_array(array, name, units=units)

463

464

# Add transient results

465

# Heads for all time steps

466

head_dict = {}

467

times = hds.get_times()

468

kstpkper_list = hds.get_kstpkper()

469

470

for i, (time, kstpkper) in enumerate(zip(times, kstpkper_list)):

471

head = hds.get_data(kstpkper=kstpkper)

472

head_dict[time] = head

473

474

nc_file.add_transient_array(head_dict, 'head', units='m')

475

476

# Add budget components

477

budget_components = ['STORAGE', 'CONSTANT HEAD', 'WELLS', 'RECHARGE']

478

for comp in budget_components:

479

try:

480

budget_dict = {}

481

for i, (time, kstpkper) in enumerate(zip(times, kstpkper_list)):

482

budget_data = cbb.get_data(text=comp, kstpkper=kstpkper)

483

if budget_data is not None:

484

budget_dict[time] = budget_data[0]

485

486

if budget_dict:

487

nc_file.add_transient_array(

488

budget_dict,

489

f'budget_{comp.lower().replace(" ", "_")}',

490

units='m3/day'

491

)

492

except:

493

print(f"Could not export {comp} budget data")

494

495

# Add coordinate system and finish

496

nc_file.add_coordinate_system(epsg=4326) # WGS84

497

nc_file.write()

498

499

print("Complete NetCDF export finished")

500

501

# Close files

502

hds.close()

503

cbb.close()

504

```

505

506

### VTK Export for 3D Visualization

507

508

```python

509

import flopy

510

import flopy.export as fpe

511

import flopy.utils as fpu

512

import numpy as np

513

514

# Load model

515

mf = flopy.modflow.Modflow.load('model.nam')

516

517

# Create VTK export object

518

vtk_file = fpe.Vtk(

519

model=mf,

520

vertical_exageration=10.0, # Exaggerate vertical for better visualization

521

binary=True, # Binary format for smaller files

522

smooth=True # Smooth surfaces

523

)

524

525

# Add model structure

526

vtk_file.add_model(mf)

527

528

# Add hydraulic conductivity

529

if hasattr(mf, 'lpf'):

530

vtk_file.add_array(mf.lpf.hk.array, 'K_horizontal')

531

vtk_file.add_array(mf.lpf.vka.array, 'K_vertical')

532

533

# Add head results

534

try:

535

hds = fpu.HeadFile('model.hds')

536

537

# Add steady-state heads

538

head_ss = hds.get_data(kstpkper=(0, 0))

539

vtk_file.add_array(head_ss, 'head_steady_state')

540

541

# Add transient heads (multiple time steps)

542

head_transient = {}

543

times = hds.get_times()

544

kstpkper_list = hds.get_kstpkper()

545

546

for time, kstpkper in zip(times, kstpkper_list):

547

head = hds.get_data(kstpkper=kstpkper)

548

head_transient[time] = head

549

550

vtk_file.add_transient_array(head_transient, 'head_transient')

551

552

hds.close()

553

554

except FileNotFoundError:

555

print("Head file not found")

556

557

# Add velocity vectors

558

try:

559

cbb = fpu.CellBudgetFile('model.cbb')

560

561

# Get face flows

562

frf = cbb.get_data(text='FLOW RIGHT FACE')[0]

563

fff = cbb.get_data(text='FLOW FRONT FACE')[0]

564

flf = cbb.get_data(text='FLOW LOWER FACE')[0]

565

566

# Convert to cell-centered velocities (simplified)

567

# Proper conversion would account for cell dimensions and porosity

568

qx = np.zeros_like(frf)

569

qy = np.zeros_like(fff)

570

qz = np.zeros_like(flf)

571

572

# Simple averaging (not rigorous)

573

qx[:, :, :-1] = frf[:, :, :-1]

574

qy[:, :-1, :] = fff[:, :-1, :]

575

qz[:-1, :, :] = flf[:-1, :, :]

576

577

vtk_file.add_vector((qx, qy, qz), 'velocity_vectors')

578

579

cbb.close()

580

581

except FileNotFoundError:

582

print("Budget file not found")

583

584

# Add MODPATH results if available

585

try:

586

# Pathlines

587

pth_file = fpu.PathlineFile('model.mppth')

588

pathlines = pth_file.get_alldata()

589

vtk_file.add_pathline_points(pathlines[:100]) # First 100 pathlines

590

591

# Endpoints

592

ep_file = fpu.EndpointFile('model.mpend')

593

endpoints = ep_file.get_alldata()

594

vtk_file.add_endpoint_points(endpoints)

595

596

except FileNotFoundError:

597

print("MODPATH files not found")

598

599

# Write VTK file

600

vtk_file.write('model_3d.vtu')

601

602

print("VTK export completed: model_3d.vtu")

603

604

# For time series, create PVD file

605

pvd_file = fpe.Pvd('model_timeseries.pvd')

606

607

for i, time in enumerate(times[:10]): # First 10 time steps

608

# Create individual VTK files for each time step

609

vtk_time = fpe.Vtk(model=mf)

610

vtk_time.add_model(mf)

611

612

# Add head for this time step

613

head = hds.get_data(idx=i)

614

vtk_time.add_array(head, f'head_t{i}')

615

616

filename = f'model_t{i:03d}.vtu'

617

vtk_time.write(filename)

618

619

# Add to PVD file

620

pvd_file.add_dataset(filename, time)

621

622

# Write PVD file

623

pvd_file.write()

624

625

print("Time series VTK export completed")

626

```

627

628

### Shapefile Export for GIS Integration

629

630

```python

631

import flopy

632

import flopy.export as fpe

633

import flopy.utils as fpu

634

import numpy as np

635

636

# Load model

637

mf = flopy.modflow.Modflow.load('model.nam')

638

639

# Export model grid to shapefile

640

grid_dict = {

641

'layer': np.repeat(range(mf.dis.nlay), mf.dis.nrow * mf.dis.ncol),

642

'row': np.tile(np.repeat(range(mf.dis.nrow), mf.dis.ncol), mf.dis.nlay),

643

'column': np.tile(range(mf.dis.ncol), mf.dis.nlay * mf.dis.nrow)

644

}

645

646

# Add hydraulic properties

647

if hasattr(mf, 'lpf'):

648

grid_dict['k_horizontal'] = mf.lpf.hk.array.ravel()

649

grid_dict['k_vertical'] = mf.lpf.vka.array.ravel()

650

grid_dict['specific_yield'] = mf.lpf.sy.array.ravel()

651

652

# Add elevations

653

grid_dict['top_elev'] = np.repeat(mf.dis.top.array.ravel(), mf.dis.nlay)

654

botm_3d = np.broadcast_to(mf.dis.botm.array, (mf.dis.nlay, mf.dis.nrow, mf.dis.ncol))

655

grid_dict['bot_elev'] = botm_3d.ravel()

656

657

# Export grid with attributes

658

fpe.write_grid_shapefile('model_grid.shp', mf.modelgrid, array_dict=grid_dict)

659

660

print("Grid shapefile exported: model_grid.shp")

661

662

# Export head results

663

try:

664

hds = fpu.HeadFile('model.hds')

665

666

# Final heads

667

head_final = hds.get_data(kstpkper=(-1, -1))

668

669

head_dict = {

670

'head_final': head_final.ravel(),

671

'layer': grid_dict['layer'],

672

'row': grid_dict['row'],

673

'column': grid_dict['column']

674

}

675

676

fpe.write_grid_shapefile('model_heads.shp', mf.modelgrid, array_dict=head_dict)

677

678

hds.close()

679

680

except FileNotFoundError:

681

print("Head file not found")

682

683

# Export boundary conditions

684

bc_packages = ['WEL', 'RIV', 'GHB', 'DRN', 'CHD']

685

686

for bc_name in bc_packages:

687

try:

688

package = mf.get_package(bc_name)

689

if package is not None:

690

fpe.package_export_shapefile(package, f'{bc_name.lower()}_bc.shp')

691

print(f"Exported {bc_name} package to shapefile")

692

except:

693

print(f"Could not export {bc_name} package")

694

695

# Export well data with detailed attributes

696

if hasattr(mf, 'wel'):

697

wel_package = mf.wel

698

699

# Get well data for stress period 0

700

wel_data = wel_package.stress_period_data[0]

701

702

# Create well points with attributes

703

well_geoms = []

704

well_attrs = {

705

'well_id': [],

706

'layer': [],

707

'row': [],

708

'column': [],

709

'pump_rate': [],

710

'x_coord': [],

711

'y_coord': []

712

}

713

714

for i, well in enumerate(wel_data):

715

lay, row, col, rate = well[0], well[1], well[2], well[3]

716

717

# Get coordinates from model grid

718

x, y = mf.modelgrid.get_coords(row, col)

719

720

# Create point geometry (simplified - would use shapely in practice)

721

well_geoms.append((x, y))

722

723

well_attrs['well_id'].append(f'WELL_{i+1:03d}')

724

well_attrs['layer'].append(lay + 1) # 1-based indexing

725

well_attrs['row'].append(row + 1)

726

well_attrs['column'].append(col + 1)

727

well_attrs['pump_rate'].append(rate)

728

well_attrs['x_coord'].append(x)

729

well_attrs['y_coord'].append(y)

730

731

# Export wells (would need actual shapefile writing function)

732

# fpe.write_shapefile('wells.shp', well_geoms, well_attrs)

733

734

print(f"Found {len(wel_data)} wells for export")

735

736

# Export contours

737

try:

738

hds = fpu.HeadFile('model.hds')

739

head = hds.get_data(kstpkper=(0, 0))

740

741

# Define contour levels

742

levels = np.linspace(head.min(), head.max(), 20)

743

744

fpe.export_contours(

745

'head_contours.shp',

746

head[0, :, :], # Top layer only

747

levels=levels,

748

modelgrid=mf.modelgrid

749

)

750

751

print("Head contours exported")

752

753

hds.close()

754

755

except FileNotFoundError:

756

print("Head file not found for contour export")

757

```

758

759

### Multi-Format Export Workflow

760

761

```python

762

import flopy

763

import flopy.export as fpe

764

import flopy.utils as fpu

765

import os

766

767

def export_model_complete(model_name: str, export_formats: list = None):

768

"""Complete model export to multiple formats"""

769

770

if export_formats is None:

771

export_formats = ['netcdf', 'vtk', 'shapefile']

772

773

# Load model

774

mf = flopy.modflow.Modflow.load(f'{model_name}.nam')

775

776

# Create export directory

777

export_dir = f'{model_name}_export'

778

os.makedirs(export_dir, exist_ok=True)

779

780

print(f"Exporting model {model_name} to formats: {export_formats}")

781

782

# NetCDF export

783

if 'netcdf' in export_formats:

784

print("Exporting to NetCDF...")

785

786

nc_file = fpe.NetCdf(

787

os.path.join(export_dir, f'{model_name}.nc'),

788

mf

789

)

790

791

# Add comprehensive metadata

792

metadata = {

793

'title': f'MODFLOW Model: {model_name}',

794

'summary': 'Groundwater flow model with complete package and result data',

795

'source': 'MODFLOW-2005',

796

'Conventions': 'CF-1.6, ACDD-1.3',

797

'date_created': '2024-01-01',

798

'geospatial_bounds_crs': 'EPSG:4326'

799

}

800

801

fpe.acdd.add_global_attributes(nc_file.nc, metadata)

802

803

nc_file.add_model(mf)

804

805

# Add results if available

806

try:

807

hds = fpu.HeadFile(f'{model_name}.hds')

808

head_dict = {}

809

for i, time in enumerate(hds.get_times()):

810

head = hds.get_data(idx=i)

811

head_dict[time] = head

812

nc_file.add_transient_array(head_dict, 'head', units='m')

813

hds.close()

814

except:

815

pass

816

817

nc_file.write()

818

print(f" NetCDF export complete: {model_name}.nc")

819

820

# VTK export

821

if 'vtk' in export_formats:

822

print("Exporting to VTK...")

823

824

vtk_file = fpe.Vtk(model=mf, binary=True)

825

vtk_file.add_model(mf)

826

827

# Add results

828

try:

829

hds = fpu.HeadFile(f'{model_name}.hds')

830

head = hds.get_data(kstpkper=(0, 0))

831

vtk_file.add_array(head, 'head')

832

hds.close()

833

except:

834

pass

835

836

vtk_output = os.path.join(export_dir, f'{model_name}.vtu')

837

vtk_file.write(vtk_output)

838

print(f" VTK export complete: {model_name}.vtu")

839

840

# Shapefile export

841

if 'shapefile' in export_formats:

842

print("Exporting to Shapefiles...")

843

844

# Grid with attributes

845

grid_dict = {

846

'layer': np.repeat(range(mf.dis.nlay), mf.dis.nrow * mf.dis.ncol),

847

'k_horiz': mf.lpf.hk.array.ravel() if hasattr(mf, 'lpf') else None,

848

'top_elev': np.repeat(mf.dis.top.array.ravel(), mf.dis.nlay)

849

}

850

851

# Filter out None values

852

grid_dict = {k: v for k, v in grid_dict.items() if v is not None}

853

854

grid_output = os.path.join(export_dir, f'{model_name}_grid.shp')

855

fpe.write_grid_shapefile(grid_output, mf.modelgrid, array_dict=grid_dict)

856

857

# Boundary conditions

858

bc_packages = ['WEL', 'RIV', 'GHB', 'DRN']

859

for bc_name in bc_packages:

860

try:

861

package = mf.get_package(bc_name)

862

if package is not None:

863

bc_output = os.path.join(export_dir, f'{model_name}_{bc_name.lower()}.shp')

864

fpe.package_export_shapefile(package, bc_output)

865

except:

866

continue

867

868

print(f" Shapefile export complete in directory: {export_dir}")

869

870

print(f"Model export completed. Files saved in: {export_dir}")

871

872

# Example usage

873

export_model_complete('regional_model', ['netcdf', 'vtk', 'shapefile'])

874

```

875

876

### Custom Export Functions

877

878

```python

879

import flopy

880

import flopy.export as fpe

881

import numpy as np

882

import json

883

884

def export_model_summary_json(model: object, filename: str):

885

"""Export model summary information to JSON"""

886

887

summary = {

888

'model_info': {

889

'name': model.name,

890

'version': model.version,

891

'workspace': model.model_ws,

892

'executable': model.exe_name

893

},

894

'discretization': {

895

'nlay': model.dis.nlay,

896

'nrow': model.dis.nrow,

897

'ncol': model.dis.ncol,

898

'nper': model.dis.nper,

899

'total_cells': model.dis.nlay * model.dis.nrow * model.dis.ncol

900

},

901

'packages': [pak.name[0] for pak in model.packagelist],

902

'grid_info': {

903

'delr_min': float(np.min(model.dis.delr.array)),

904

'delr_max': float(np.max(model.dis.delr.array)),

905

'delc_min': float(np.min(model.dis.delc.array)),

906

'delc_max': float(np.max(model.dis.delc.array)),

907

'extent': model.modelgrid.extent

908

}

909

}

910

911

# Add package-specific information

912

if hasattr(model, 'lpf'):

913

summary['hydraulic_properties'] = {

914

'k_horizontal_range': [float(np.min(model.lpf.hk.array)),

915

float(np.max(model.lpf.hk.array))],

916

'porosity_range': [float(np.min(model.lpf.sy.array)),

917

float(np.max(model.lpf.sy.array))]

918

}

919

920

if hasattr(model, 'wel'):

921

wel_data = model.wel.stress_period_data[0]

922

summary['wells'] = {

923

'count': len(wel_data),

924

'total_pumping': float(np.sum([w[3] for w in wel_data if w[3] < 0])),

925

'total_injection': float(np.sum([w[3] for w in wel_data if w[3] > 0]))

926

}

927

928

# Write JSON file

929

with open(filename, 'w') as f:

930

json.dump(summary, f, indent=2)

931

932

print(f"Model summary exported to: {filename}")

933

934

def export_budget_csv(cbb_file: str, output_file: str):

935

"""Export budget components to CSV format"""

936

937

import pandas as pd

938

939

cbb = fpu.CellBudgetFile(cbb_file)

940

941

# Get all available records

942

records = cbb.list_unique_records()

943

times = cbb.get_times()

944

945

# Create DataFrame

946

budget_data = []

947

948

for time in times:

949

for record in records:

950

try:

951

data = cbb.get_data(text=record, totim=time)

952

if data is not None:

953

total_flow = np.sum(data[0])

954

budget_data.append({

955

'time': time,

956

'component': record,

957

'total_flow': total_flow

958

})

959

except:

960

continue

961

962

df = pd.DataFrame(budget_data)

963

df.to_csv(output_file, index=False)

964

965

cbb.close()

966

print(f"Budget data exported to: {output_file}")

967

968

# Example usage

969

mf = flopy.modflow.Modflow.load('model.nam')

970

export_model_summary_json(mf, 'model_summary.json')

971

export_budget_csv('model.cbb', 'budget_summary.csv')

972

```

973

974

## Common Types

975

976

```python { .api }

977

# Export format types

978

ExportFormat = Literal['netcdf', 'vtk', 'shapefile', 'csv', 'json']

979

FileFormat = Literal['binary', 'ascii']

980

CompressionLevel = int # 0-9 for compression

981

982

# Data types for export

983

ArrayData = np.ndarray

984

TransientData = dict[float, np.ndarray] # Time -> Array

985

VectorData = tuple[np.ndarray, np.ndarray, np.ndarray] # (vx, vy, vz)

986

987

# Geometry types

988

GeometryType = Literal['Point', 'LineString', 'Polygon']

989

ShapefileGeometry = list[tuple[float, ...]]

990

AttributeDict = dict[str, list]

991

992

# Metadata types

993

MetadataDict = dict[str, Union[str, int, float]]

994

ACDDAttributes = dict[str, str]

995

CoordinateSystem = Union[int, str] # EPSG code or proj4 string

996

997

# File and path types

998

FilePath = Union[str, os.PathLike]

999

OutputDirectory = str

1000

FileExtension = str

1001

1002

# VTK specific types

1003

VTKDataType = Literal['SCALARS', 'VECTORS', 'TENSORS']

1004

VTKFormat = Literal['ascii', 'binary']

1005

TimeStepData = dict[float, str] # Time -> filename mapping

1006

1007

# NetCDF specific types

1008

NCVariable = str

1009

NCDimension = str

1010

NCAttributes = dict[str, Union[str, int, float, list]]

1011

1012

# Shapefile specific types

1013

FieldType = Literal['C', 'N', 'F', 'L', 'D'] # Character, Numeric, Float, Logical, Date

1014

FieldDefinition = tuple[str, str, int, int] # (name, type, width, precision)

1015

```

1016

1017

This comprehensive documentation covers the complete data export API for FloPy including NetCDF, VTK, and shapefile export capabilities. The examples demonstrate basic to advanced export scenarios including complete model export workflows, multi-format exports, and custom export functions for various use cases.