使用软盘截断 CBB 文件

Truncate CBB File using Flopy

我有兴趣在一定数量的压力周期后截断二进制 MODFLOW CBB 文件。使用 Flopy 二进制文件实用程序,我已经能够理解如何解压缩二进制文件并将值提取到数组中。但是,不清楚我是否可以直接使用 Flopy 实用程序来创建新的二进制文件。 Flopy 是否有一个实用程序可以帮助将 CBB 文件的一部分写入新的二进制文件?新的 CBB 文件将用作 MODPATH 的输入,因此 CBB 文件的格式需要保持不变。

单独使用 Flopy,我觉得我已经接近获得我需要的结果了。我确定有 Python 个特定的库可用于获得所需的结果,但我想我会先看看是否可以使用 Flopy 实现。

以下是我目前调查的内容:

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

CBB.list_records() 的第一个和最后一个压力周期的输出:

(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, '', '', '', '')

我希望将所有这些预算条款保留在新的二进制文件中,但希望删除上一个压力期(本例中为压力期 6)的所有条款。

我尝试将压力周期数据查询到数组中,然后使用以下代码将此数据写入新的二进制文件。我 运行 遇到此代码的内存问题。此处处理的示例 CBB 文件 (~460 mb) 比我最终要处理的 CBB (~55 gb) 小得多。对于我正在尝试做的事情,似乎不需要将文件读入数组。

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)

我的另一个想法是读取 CBB 文件 line-by-line 并只写出我需要的数据。这将需要解码 header 行以确定当前的压力周期,以了解何时停止写入数据。我无法解码 header 信息。

谢谢!

没有任何用于重写二进制预算文件的特定软盘实用程序。 flopy develop branch 有一个方法 (.get_position()) 用于确定二进制预算文件中记录的数据开始位置(和 header 信息)。 .get_position()方法将在未来的软盘版本(版本> 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

位置数据可用于使用标准 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