Source code for mfexport.zbud

"""Functions for working with zone budget.
"""
import os
from pathlib import Path
import numpy as np
from flopy.mf6.utils.binarygrid_util import MfGrdFile


[docs] def write_zonebudget6_input(zones, budgetfile, binary_grid_file=None, zone_arrays_subfolder='external', outname=None): # make sure zones is the right shape bgf = MfGrdFile(binary_grid_file) nlay, nrow, ncol = bgf.modelgrid.nlay, bgf.modelgrid.nrow, bgf.modelgrid.ncol layered = False if len(zones.shape) == 3: layered = True assert zones.shape == (nlay, nrow, ncol) elif len(zones.shape) == 2: assert zones.shape == (nrow, ncol) # if zones is 2d and multiple layers # broadcast zones to all layers if nlay > 1: layered = True zones = np.broadcast_to(zones, (nlay, nrow, ncol)) else: assert len(zones) == nlay * nrow * ncol assert zones.shape[-2:] == (nrow, ncol) budgetfile = Path(budgetfile) if outname is None: outpath = budgetfile.parent outname = budgetfile.stem else: outpath = Path(outname).parent outname = Path(outname).stem output_namefile = outpath / (outname + '.zbud.nam') output_zonefile = outpath / (outname + '.zbud.zon') output_zone_array_format = outpath # relative path to budget file from zone budget input #budgetfile = budgetfile.relative_to(outpath.absolute()) # use os.path.relpath because pathlib relative_to() # only works with strings and therefore doesn't handle two paths that branch budgetfile = os.path.relpath(budgetfile, outpath.absolute()) # relative path to grb file if binary_grid_file is not None: binary_grid_file = os.path.relpath(binary_grid_file, outpath.absolute()) # write the name file with open(output_namefile, 'w') as dest: dest.write('begin zonebudget\n') dest.write(f' bud {budgetfile}\n') dest.write(f' zon {output_zonefile.name}\n') dest.write(f' grb {binary_grid_file}\n') dest.write('end zonebudget\n') print(f'wrote {output_namefile}') # write the zone arrays zone_arrays_path = outpath / zone_arrays_subfolder zone_arrays_path.mkdir(exist_ok=True) zone_array_format = 'budget-zones_{:03d}.dat' open_close_text = '' if not layered: array_fname = zone_arrays_path / zone_array_format.format(0) np.savetxt(array_fname, zones, fmt='%d') array_fname = array_fname.relative_to(outpath) print(f'wrote {array_fname}') open_close_text += f' open/close {array_fname}\n' else: for k, layer_zones in enumerate(zones): array_fname = zone_arrays_path / zone_array_format.format(k) np.savetxt(array_fname, layer_zones, fmt='%d') array_fname = array_fname.relative_to(outpath) open_close_text += f' open/close {array_fname}\n' print(f'wrote {array_fname}') # write the zone file with open(output_zonefile, 'w') as dest: dest.write('begin dimensions\n') dest.write(f' ncells {zones.size}\n') dest.write('end dimensions\n') dest.write('\n') dest.write('begin griddata\n') izone_text = 'izone' if layered: izone_text += ' layered' dest.write(f' {izone_text}\n') dest.write(open_close_text) dest.write('end griddata\n') print(f'wrote {output_zonefile}')