FlopyとPHREEQCで熱水地球化学シミュレーション #1:
モデル設計編

MODFLOW 6(Flopy)とPHREEQC(phreeqpy)をPythonでカップリングし、1次元カラムの熱水流動と地球化学反応を統合解析するシリーズ。第1回はなぜこのカップリングが必要なのか、モデル全体の設計思想と構成を解説します。
Groundwater
Python
MODFLOW
Geochemistry
Simulation
地下水
地球化学
作者

DeepFlow

公開

2026年4月3日

なぜ「カップリング」が必要なのか

地下水の流動を計算するだけなら、MODFLOW 6単体で十分です。しかし現実の地下環境では、水が流れると同時に岩石と反応し、鉱物が溶けたり沈殿したりします。熱水系では温度・圧力が高く、この反応がさらに複雑になります。

この熱水系において、流動モデルと反応モデルを切り離して使うと、岩石-水反応を正しく追うことができなくなり(溶解・沈殿現象)、観測データの再現性は保証されません。

そこで本シリーズでは、MODFLOW 6(流動計算)とPHREEQC(地球化学反応計算)をPythonで結合し、1次元カラムスケールでの熱水流動と地球化学反応を同時にシミュレーションする手法を段階的に解説します。


モデルの全体像

本シミュレーションは3つのコアコンポーネントで構成されます。

                  ┌─────────────────┐
                  │  MODFLOW 6      │  💧 流動計算
                  │  (Flopy)        │  ・カラム内の圧力・流量
                  │                 │  ・Darcy流速の算出
                  └────────┬────────┘
                           │  Darcy流速 (v)
                           ▼
                  ┌─────────────────┐
                  │  PHREEQC        │  🧪 反応輸送計算
                  │  (phreeqpy)     │  ・移流(TRANSPORT)
                  │                 │  ・鉱物溶解・沈殿(KINETICS)
                  └────────┬────────┘
                           │  濃度・pH・SI・鉱物量
                           ▼
                  ┌─────────────────┐
                  │  Python         │  📊 統合・可視化
                  │  (numpy +       │  ・時系列プロット
                  │   matplotlib)   │  ・破過曲線の解析
                  └─────────────────┘

3つのコンポーネントの役割を整理すると以下のようになります:

コンポーネント ライブラリ 担当
流動計算 flopy カラム内の流量・水頭・Darcy流速
反応輸送計算 phreeqpy pH・鉱物量・元素濃度の時間変化
統合・可視化 numpy, matplotlib データ受け渡し・結果の描画

ポイントはMODFLOWが計算したDarcy流速を、そのままPHREEQCの移流速度パラメータに渡すという橋渡しの仕組みです。これがカップリングの核心となります(詳細は第2回で実装します)。


使用ライブラリ

# 流動モデル
import flopy                          # MODFLOW 6 の Python インターフェース

# 反応計算
from phreeqpy.iphreeqc.phreeqc import IPhreeqc  # PHREEQC エンジン

# 数値・可視化
import numpy as np
import matplotlib.pyplot as plt

# ファイル操作
import csv, os, shutil

インストールは以下:

pip install flopy
pip install phreeqpy
pip install numpy matplotlib
ヒントPHREEQCデータベースについて

本シリーズでは高温高圧条件(150℃、100atm)に対応した llnl.dat を使用します。これもUSGS/USGS提供のPHREEQCパッケージに含まれているので、同じく作業ディレクトリに配置しておきます。


カラムモデルの設計

物理的なイメージ

円柱形のコアサンプル(あるいは地層の1断面)を想定します。水は一端から注入され、他端から排出されます。内部では岩石鉱物と反応しながら流れます。

Model Discretization

カラム流動モデルの離散化イメージ

🧊 モデルの次元定義
Layers:1
Rows:1
Columns:N
📏 幾何パラメータ
セル幅:L ÷ N
断面積:πr²
Inlet Outlet 1 2 3 N Column Length (L) Cell Width (Δx = L/N) Area (A = πr²) r

MODFLOW 6による離散化

MODFLOWは連続的な空間をグリッドセルに分割して計算します。1次元カラムの場合、DISパッケージで以下のように定義します:

import flopy

# シミュレーション名
sim_name = "column_model"

# --- 基本パラメータ ---
L = 1.0    # カラム長さ [m]
N = 15     # セル分割数
r = 0.05   # カラム半径 [m]

dx = L / N                   # セル幅 [m]
A  = 3.14159 * r**2          # 断面積 [m²]

# --- MODFLOW モデル構築 ---
sim = flopy.mf6.MFSimulation(sim_name=sim_name, exe_name="mf6")

# TDIS:時間設定
tdis = flopy.mf6.ModflowTdis(
    sim,
    time_units="SECONDS",
    nper=1,
    perioddata=[(86400, 1, 1.0)]
)

gwf = flopy.mf6.ModflowGwf(sim, modelname=sim_name)

# DISパッケージ:グリッド定義
dis = flopy.mf6.ModflowGwfdis(
    gwf,
    nlay=1,      # 層数:1(1次元)
    nrow=1,      # 行数:1
    ncol=N,      # 列数:セル分割数
    delr=dx,     # セル幅(流れ方向)
    delc=1.0,    # セル幅(直交方向):仮想的に1.0
    top=1.0,
    botm=0.0,
)

セル数 N=15 の場合、カラムは15個の計算ブロックに分割されます。各セルの幅は均一で dx = L/N となります。

境界条件の設定

1次元流動モデルには3種類のパッケージを組み合わせます:

パッケージ 場所 役割
WEL(井戸境界) 入口 Cell 1 一定流量 \(Q_{in}\) を注入
CHD(定水頭境界) 出口 Cell N 一定水頭 \(h_{out}\) を維持
NPF(節点特性) 全セル 透水係数 \(K\) を定義
IC(初期条件) 全セル 初期水頭 \(h_{init}\) を設定
# --- 物性値 ---
K     = 1.0e-5   # 透水係数 [m/s](均質・等方)
Qin   = 1.0e-6   # 注入流量 [m³/s]
h_out = 0.0      # 出口水頭 [m]
h_init = 1.0     # 初期水頭 [m]

# NPF:透水係数
npf = flopy.mf6.ModflowGwfnpf(
    gwf,
    k=K,          # x方向
    k22=K,        # y方向
    k33=K,        # z方向
)

# IC:初期条件
ic = flopy.mf6.ModflowGwfic(gwf, strt=h_init)

# WEL:入口境界(定流量)
wel = flopy.mf6.ModflowGwfwel(
    gwf,
    stress_period_data={0: [[(0, 0, 0), Qin]]}
)

# CHD:出口境界(定水頭)
chd = flopy.mf6.ModflowGwfchd(
    gwf,
    stress_period_data={0: [[(0, 0, N-1), h_out]]}
)
ノート均質・等方の仮定

本シリーズでは検証目的のため、透水係数は全セルで一定(均質・等方)とします。実際の地層不均質性を組み込む場合は、k に配列を渡すことで対応できます。


次回予告:実装編(カップリングの核心)

第1回では「何を、なぜ組み合わせるのか」「カラムモデルをどう設計するか」を解説しました。

第2回では以下を実装します:

  1. MODFLOW 6の実行とCell Budget Fileからの流速抽出
  2. Courant条件\(C_r = 1\))を満たす時間刻みの自動計算
  3. PHREEQCの初期化(150℃・100atm条件)
  4. カップリングループ:流速をPHREEQCのTRANSPORTブロックへ動的注入

「なぜCourant数を1に揃えるのか」という数値安定性の話も丁寧に解説する予定です。


まとめ

項目 設定値
カラム長さ 1.0 m
セル分割数 15
透水係数 1.0×10⁻⁵ m/s
注入流量 1.0×10⁻⁶ m³/s
温度条件 150℃
圧力条件 100 atm(10 MPa)
計算期間 24時間

本シリーズのコードはすべて GitHubリポジトリ で公開予定です。次回の実装編もお楽しみに。


このシリーズの他の記事: