-1

我有兴趣在一定数量的压力期后截断二进制 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 文件并只写出我需要的数据。这将需要对标题行进行解码以确定当前的压力期,以了解何时停止写入数据。我无法解码标题信息来做到这一点。

谢谢!

4

1 回答 1

0

没有用于重写二进制预算文件的任何特定软盘实用程序。flopy开发分支有一个方法 ( .get_position()) 用于确定二进制预算文件中记录的数据(和头信息)的开始位置。该.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 
于 2019-01-04T19:34:23.010 回答