-1

I am interested in truncating a binary MODFLOW CBB file after a certain number of stress periods. Using the Flopy binary file utilities, I have been able to understand how to unpack a binary file and extract values into an array. However, it is unclear if I can use the Flopy utilities directly to create a new binary file. Does Flopy have a utility that would help facilitate writing out a portion of the CBB file to a new binary file? The new CBB file will serve as input to MODPATH, so the formatting of the CBB file would need to remain intact.

With Flopy alone, I feel like I am close to getting the results I need. I'm sure there are Python specific libraries that could be used to get the desired results, but I figured I would see if I can get there with Flopy first.

Here is what I have looked into so far:

import flopy.utils.binaryfile as bf
CBBFile = 'PRE_WT_WP3_PREISS_MidK.cbb'
CBB = bf.CellBudgetFile(CBBFile)
CBB.list_records()

Output from CBB.list_records() for first and last stress periods:

(1, 1, '         STORAGE', 537, 341, 12, 0, 0.0, 0.0, -1.0, '', '', '', '')
(1, 1, '   CONSTANT HEAD', 537, 341, 12, 0, 0.0, 0.0, -1.0, '', '', '', '')
(1, 1, 'FLOW RIGHT FACE ', 537, 341, 12, 0, 0.0, 0.0, -1.0, '', '', '', '')
(1, 1, 'FLOW FRONT FACE ', 537, 341, 12, 0, 0.0, 0.0, -1.0, '', '', '', '')
(1, 1, 'FLOW LOWER FACE ', 537, 341, 12, 0, 0.0, 0.0, -1.0, '', '', '', '')
(1, 1, '          DRAINS', 537, 341, 12, 0, 0.0, 0.0, -1.0, '', '', '', '')
(1, 1, '   RIVER LEAKAGE', 537, 341, 12, 0, 0.0, 0.0, -1.0, '', '', '', '')
(1, 1, ' HEAD DEP BOUNDS', 537, 341, 12, 0, 0.0, 0.0, -1.0, '', '', '', '')
(1, 1, '        RECHARGE', 537, 341, 12, 0, 0.0, 0.0, -1.0, '', '', '', '')

....

(1, 6, '         STORAGE', 537, 341, 12, 0, 0.0, 0.0, -1.0, '', '', '', '')
(1, 6, '   CONSTANT HEAD', 537, 341, 12, 0, 0.0, 0.0, -1.0, '', '', '', '')
(1, 6, 'FLOW RIGHT FACE ', 537, 341, 12, 0, 0.0, 0.0, -1.0, '', '', '', '')
(1, 6, 'FLOW FRONT FACE ', 537, 341, 12, 0, 0.0, 0.0, -1.0, '', '', '', '')
(1, 6, 'FLOW LOWER FACE ', 537, 341, 12, 0, 0.0, 0.0, -1.0, '', '', '', '')
(1, 6, '          DRAINS', 537, 341, 12, 0, 0.0, 0.0, -1.0, '', '', '', '')
(1, 6, '   RIVER LEAKAGE', 537, 341, 12, 0, 0.0, 0.0, -1.0, '', '', '', '')
(1, 6, ' HEAD DEP BOUNDS', 537, 341, 12, 0, 0.0, 0.0, -1.0, '', '', '', '')
(1, 6, '        RECHARGE', 537, 341, 12, 0, 0.0, 0.0, -1.0, '', '', '', '')

I am looking to keep all of these budget terms in the new binary file, but would like to drop all terms from the last stress period (Stress Period 6 in this example).

I tried to query stress period data into an array and then write this data to a new binary file with the code below. I am running into memory issues with this code. The example CBB file being processed here is considerably smaller (~460 mb) than the CBB I would ultimately like to process (~55 gb). It seems that reading the file to an array may be unnecessary for what I am trying to do.

allRec = CBB.get_data(kstpkper = (0,1))
i = 1
while i < 45:
   rec = CBB.get_data(kstpkper = (0,i))
   allRec = np.append(allRec, rec)
   i += 1
np.save('StrippedCBBFile', allRec)

My other idea was to read the CBB file line-by-line and write out only the data I need. This would require decoding the header line to determine the current stress period to know when to stop writing data. I have not been able to decode the header information to do so.

Thanks!

cmc104
  • 13
  • 3
  • Hi, you should post a sample of your actual output and your desired output - see [here](https://stackoverflow.com/help/mcve). Most flopy utilities handle data in numpy arrays. Once you access them you can manipulate them accordingly. Have you tried [this](https://modflowpy.github.io/flopydoc/binaryfile.html#flopy.utils.binaryfile.CellBudgetFile.get_data)? – Tarifazo Dec 21 '18 at 12:40

1 Answers1

0

There are not any specific flopy utilities for rewriting binary budget files. The flopy develop branch has a method (.get_position()) for determining the position of the start of the data (and the header information) for a record in a binary budget file. The .get_position() method will be available in future flopy versions (version > 3.2.10).

>>> import flopy 
>>> cobj = flopy.utils.CellBudgetFile('freyberg.gitcbc')
>>> cobj.get_indices(text='CONSTANT HEAD')
array([   0,    8,   16, ..., 8752, 8760, 8767])
>>> cobj.get_position(8767)
50235424
>>> cobj.get_position(8767, header=True)
50235372

The position data could be used to create a binary file with a slice of the binary budget file using standard python.

fin = open('freyberg.gitcbc', 'rb')
fin.seek(50235372)
length = os.path.getsize(fpth) - 50235372

buffsize = 32
with open('end.cbc', 'wb') as fout:
    while length:
        chunk = min(buffsize, length)
        data = fin.read(chunk)
        fout.write(data)
        length -= chunk 
jdhughes
  • 140
  • 6
  • jdhughes, thank you for your reply! The method you proposed looks great. Any idea when the get_position() method will be made available? – cmc104 Jan 07 '19 at 16:03
  • ccooledge you can install flopy from the development branch following instructions on the [flopy github site - Installing from the git repository - Development version of FloPy](https://github.com/modflowpy/flopy). I would imagine the next flopy version will be released by 3/2019. – jdhughes Jan 08 '19 at 17:09