modified: CMakeLists.txt
modified: INSTALL.md modified: README.md modified: build_release_zip.py modified: compute.py new file: doc/index.html modified: dynamics.py modified: engines/c/main.c modified: engines/cpp/main.cpp modified: engines/fortran/main.f90 modified: examples/case01/input/coord.txt renamed: examples/case01/input/parameters.yaml -> examples/case01/input/input.txt modified: examples/case01/run_dynamics.py new file: examples/case02/input/bond.txt new file: examples/case02/input/connection.txt new file: examples/case02/input/coord.txt new file: examples/case02/input/input.txt new file: examples/case02/run_dynamics.py
This commit is contained in:
@@ -1,3 +1,3 @@
|
||||
n mass radius x y z vx vy vz
|
||||
1 1 0.28 -1 0 0 0 0 0
|
||||
2 1 0.28 1 0 1 0 0 0
|
||||
n mass radius x y z vx vy vz fix_x fix_y fix_z
|
||||
1 1 0.28 -1 0 0 0 0 0 0 0 0
|
||||
2 1 0.28 1 0 1 0 0 0 0 0 0
|
||||
|
||||
@@ -7,18 +7,20 @@
|
||||
# 依赖关系:抽帧依赖模拟结果,绘图依赖模拟+抽帧
|
||||
step_simulate: 1 # 运行物理模拟 → output/trajectory.txt
|
||||
step_sample: 1 # 抽帧 → output/display.txt
|
||||
step_plot: 0 # 绘制轨迹/能量图 → output/trajectory_plots.png
|
||||
step_plot: 1 # 绘制轨迹/能量图 → output/trajectory_plots.png
|
||||
step_animation: 1 # 自动播放 VisPy 3D 动画窗口(需安装 vispy)
|
||||
force_calc: 0 # 强制重新计算:1=跳过缓存强算,0=自动使用已有输出
|
||||
|
||||
# ── 计算引擎 ──────────────────────────────────
|
||||
# 可选: python, c, cpp, fortran, java
|
||||
# python = Python 参考实现(compute.py)
|
||||
# c = C 引擎 (engines/c/build/dynamics_c)
|
||||
# cpp = C++ 引擎 (engines/cpp/build/dynamics_cpp)
|
||||
engine: python # 默认使用 Python 引擎
|
||||
# fortran = Fortran 引擎 (engines/fortran/build/dynamics_f90)
|
||||
engine: python # 默认使用 Python 引擎
|
||||
|
||||
# ── 盒子 ──────────────────────────────────────
|
||||
box_a: 10.0 # 立方体半边长,粒子被限制在 [-box_a, box_a]³ 内
|
||||
box_a: 20.0 # 立方体半边长,粒子被限制在 [-box_a, box_a]³ 内
|
||||
|
||||
# ── 初始构型 ──────────────────────────────────
|
||||
# 坐标文件格式:
|
||||
@@ -37,6 +39,14 @@ G: [0.0, 0.0, -9.8] # 重力场分量 (m/s²)
|
||||
# B: [0.5, 0.5, 0.5] # 阻尼分量
|
||||
B: [0.0, 0.0, 0.0] # 阻尼分量
|
||||
|
||||
# ── 力开关(0=关闭, 1=开启)──────────────────
|
||||
gravity_field: 1 # 均匀重力场 (G)
|
||||
gravity_interaction: 0 # 原子间万有引力
|
||||
elastic_force: 1 # 弹簧键力
|
||||
damping_force: 0 # 阻尼 (B)
|
||||
#
|
||||
gravity_strength: 1.0 # 万有引力强度(仅 gravity_interaction=1 时有效)
|
||||
|
||||
# ── 数值算法 ──────────────────────────────────
|
||||
# 可选:
|
||||
# explicit_euler 显式欧拉法
|
||||
@@ -51,18 +61,21 @@ method: leapfrog
|
||||
# 预热步数:模拟开始时跳过不保存的步数(用于稳定初始状态)
|
||||
warmup_steps: 0 # 默认 0(立即开始记录)
|
||||
|
||||
# 总计算步数
|
||||
NT: 10000
|
||||
# 总模拟时间(秒),程序自动计算 NT = T_total / DT
|
||||
# 如果同时指定了 NT,以 NT 为准
|
||||
T_total: 10.0
|
||||
|
||||
# 抽帧间隔(每 NSTEP 步取一帧用于动画)
|
||||
NSTEP: 100
|
||||
|
||||
# ── 时间步长 ──────────────────────────────────
|
||||
DT: 0.001 # 时间步长 (s)
|
||||
|
||||
# 抽帧范围:只保存 [sample_start, sample_end) 区间内的帧
|
||||
sample_start: null # null 表示从头开始(帧索引从 0 起)
|
||||
sample_end: null # null 表示到末尾
|
||||
|
||||
# ── 时间步长 ──────────────────────────────────
|
||||
DT: 0.001 # 时间步长 (s)
|
||||
|
||||
|
||||
# ── 显示参数 ──────────────────────────────────
|
||||
# 盒子透明度:单个数值(统一)或 6 个数的数组,按 [-x,+x,-y,+y,-z,+z] 顺序
|
||||
@@ -18,7 +18,7 @@ CASE_DIR = Path(__file__).resolve().parent
|
||||
DYNAMICS_PATH = Path("..") / ".." / "dynamics.py"
|
||||
INPUT_DIR = Path("input")
|
||||
OUTPUT_DIR = Path("output")
|
||||
CONFIG_FILE = INPUT_DIR / "parameters.yaml"
|
||||
CONFIG_FILE = INPUT_DIR / "input.txt"
|
||||
|
||||
|
||||
def load_dynamics_module(module_path: Path):
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
bond_name k rest_length
|
||||
k1 100.0 2.0
|
||||
@@ -0,0 +1,2 @@
|
||||
n1 n2 bond_name
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
n mass radius x y z vx vy vz fix_x fix_y fix_z
|
||||
1 1 0.28 0 0 0 0 0 0 1 1 1
|
||||
2 1 0.28 0 0 4 0 4 0 0 0 0
|
||||
@@ -0,0 +1,93 @@
|
||||
# 物理模拟参数配置
|
||||
# 格式:YAML
|
||||
# 用法:python run_dynamics.py
|
||||
|
||||
# ── 流程控制 ──────────────────────────────────
|
||||
# 每步用 0/1 单独开关,1=执行,0=跳过
|
||||
# 依赖关系:抽帧依赖模拟结果,绘图依赖模拟+抽帧
|
||||
step_simulate: 1 # 运行物理模拟 → output/trajectory.txt
|
||||
step_sample: 1 # 抽帧 → output/display.txt
|
||||
step_plot: 1 # 绘制轨迹/能量图 → output/trajectory_plots.png
|
||||
step_animation: 1 # 自动播放 VisPy 3D 动画窗口(需安装 vispy)
|
||||
force_calc: 0 # 强制重新计算:1=跳过缓存强算,0=自动使用已有输出
|
||||
|
||||
# ── 计算引擎 ──────────────────────────────────
|
||||
# 可选: python, c, cpp, fortran, java
|
||||
# python = Python 参考实现(compute.py)
|
||||
# c = C 引擎 (engines/c/build/dynamics_c)
|
||||
# cpp = C++ 引擎 (engines/cpp/build/dynamics_cpp)
|
||||
# fortran = Fortran 引擎 (engines/fortran/build/dynamics_f90)
|
||||
engine: python # 默认使用 Python 引擎
|
||||
|
||||
# ── 盒子 ──────────────────────────────────────
|
||||
box_a: 20.0 # 立方体半边长,粒子被限制在 [-box_a, box_a]³ 内
|
||||
|
||||
# ── 初始构型 ──────────────────────────────────
|
||||
# 坐标文件格式:
|
||||
# 第一行:n mass radius x y z vx vy vz
|
||||
# 后续行:原子序号 质量 半径 x y z vx vy vz
|
||||
coord_file: input/coord.txt
|
||||
connection_file: input/connection.txt
|
||||
bond_file: input/bond.txt
|
||||
|
||||
# 绘图/动画展示的原子序号(对应 coord_file 第一列 n)
|
||||
plot_atom: 1
|
||||
|
||||
# ── 物理参数 ──────────────────────────────────
|
||||
# 三个方向分量分别对应 x, y, z
|
||||
G: [0.0, 0.0, -9.8] # 重力场分量 (m/s²)
|
||||
# B: [0.5, 0.5, 0.5] # 阻尼分量
|
||||
B: [0.0, 0.0, 0.0] # 阻尼分量
|
||||
|
||||
# ── 力开关(0=关闭, 1=开启)──────────────────
|
||||
gravity_field: 0 # 均匀重力场 (G)
|
||||
gravity_interaction: 1 # 原子间万有引力
|
||||
elastic_force: 0 # 弹簧键力
|
||||
damping_force: 0 # 阻尼 (B)
|
||||
#
|
||||
gravity_strength: 100.0 # 万有引力强度(仅 gravity_interaction=1 时有效)
|
||||
|
||||
# ── 数值算法 ──────────────────────────────────
|
||||
# 可选:
|
||||
# explicit_euler 显式欧拉法
|
||||
# implicit_euler 隐式欧拉法
|
||||
# midpoint 中点法
|
||||
# leapfrog 蛙跳法
|
||||
method: leapfrog
|
||||
|
||||
# ── 步骤控制 ──────────────────────────────────
|
||||
# 以下参数控制哪些步骤被执行和保存
|
||||
|
||||
# 预热步数:模拟开始时跳过不保存的步数(用于稳定初始状态)
|
||||
warmup_steps: 0 # 默认 0(立即开始记录)
|
||||
|
||||
# 总模拟时间(秒),程序自动计算 NT = T_total / DT
|
||||
# 如果同时指定了 NT,以 NT 为准
|
||||
T_total: 10.0
|
||||
|
||||
# 抽帧间隔(每 NSTEP 步取一帧用于动画)
|
||||
NSTEP: 100
|
||||
|
||||
# ── 时间步长 ──────────────────────────────────
|
||||
DT: 0.001 # 时间步长 (s)
|
||||
|
||||
# 抽帧范围:只保存 [sample_start, sample_end) 区间内的帧
|
||||
sample_start: null # null 表示从头开始(帧索引从 0 起)
|
||||
sample_end: null # null 表示到末尾
|
||||
|
||||
|
||||
|
||||
# ── 显示参数 ──────────────────────────────────
|
||||
# 盒子透明度:单个数值(统一)或 6 个数的数组,按 [-x,+x,-y,+y,-z,+z] 顺序
|
||||
alpha: [0.0, 0.0, 0.0, 0.0, 0.0, 0.5]
|
||||
|
||||
# 小球颜色
|
||||
# 小球半径从 coord_file 的 radius 列读取
|
||||
ball_color_r: 0.90 # R 分量 (0~1)
|
||||
ball_color_g: 0.20 # G 分量
|
||||
ball_color_b: 0.20 # B 分量
|
||||
|
||||
# 盒子面颜色
|
||||
box_color_r: 0.80
|
||||
box_color_g: 0.80
|
||||
box_color_b: 0.85
|
||||
@@ -0,0 +1,54 @@
|
||||
"""
|
||||
Case runner for Dynamics case01.
|
||||
|
||||
This script keeps program and data separated:
|
||||
- program: ../../dynamics.py
|
||||
- input: ./input
|
||||
- output: ./output
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import argparse
|
||||
import importlib.util
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
CASE_DIR = Path(__file__).resolve().parent
|
||||
DYNAMICS_PATH = Path("..") / ".." / "dynamics.py"
|
||||
INPUT_DIR = Path("input")
|
||||
OUTPUT_DIR = Path("output")
|
||||
CONFIG_FILE = INPUT_DIR / "input.txt"
|
||||
|
||||
|
||||
def load_dynamics_module(module_path: Path):
|
||||
spec = importlib.util.spec_from_file_location("dynamics_module", module_path)
|
||||
if spec is None or spec.loader is None:
|
||||
raise ImportError(f"无法加载 dynamics.py: {module_path}")
|
||||
module = importlib.util.module_from_spec(spec)
|
||||
spec.loader.exec_module(module)
|
||||
return module
|
||||
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(description="运行 Dynamics 示例案例 case01")
|
||||
parser.add_argument("--no-plot", action="store_true", help="跳过 matplotlib 绘图")
|
||||
args = parser.parse_args()
|
||||
|
||||
dynamics_path = (CASE_DIR / DYNAMICS_PATH).resolve()
|
||||
input_dir = (CASE_DIR / INPUT_DIR).resolve()
|
||||
output_dir = (CASE_DIR / OUTPUT_DIR).resolve()
|
||||
config_path = (CASE_DIR / CONFIG_FILE).resolve()
|
||||
|
||||
module = load_dynamics_module(dynamics_path)
|
||||
module.run_case(
|
||||
config_path=config_path,
|
||||
runtime_base=CASE_DIR,
|
||||
input_dir=input_dir,
|
||||
output_dir=output_dir,
|
||||
no_plot=args.no_plot,
|
||||
)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user