docs: 更新 examples/Readme.md 并新增 Readme.html

- 覆盖全部 10 个案例(原 Readme 只到 case06)
- 新增案例选择指南表格
- Readme.html 为深色主题独立 HTML 页面
  (含卡片布局、标签分类、代码高亮、响应式设计)
- 各案例详情对齐最新配置参数
This commit is contained in:
2026-06-17 15:33:49 +08:00
parent ea99f09f9b
commit 0e636e275d
59 changed files with 7302 additions and 418 deletions
+82 -174
View File
@@ -49,7 +49,7 @@ program dynamics_f90
double precision, allocatable :: vx(:), vy(:), vz(:)
! 轨迹缓冲区
integer :: record_steps
integer :: record_steps, n_frames, frame_idx
double precision, allocatable :: traj_x(:, :), traj_y(:, :), traj_z(:, :)
double precision, allocatable :: traj_vx(:, :), traj_vy(:, :), traj_vz(:, :)
@@ -104,10 +104,11 @@ program dynamics_f90
vx(i) = vel_0(i, 1); vy(i) = vel_0(i, 2); vz(i) = vel_0(i, 3)
end do
! 分配轨迹缓冲区
! 分配轨迹缓冲区(只保存采样帧,不保存每一步)
record_steps = NT - warmup_steps
allocate(traj_x(record_steps, n), traj_y(record_steps, n), traj_z(record_steps, n))
allocate(traj_vx(record_steps, n), traj_vy(record_steps, n), traj_vz(record_steps, n))
n_frames = max(1, record_steps / max(1, NSTEP))
allocate(traj_x(n_frames, n), traj_y(n_frames, n), traj_z(n_frames, n))
allocate(traj_vx(n_frames, n), traj_vy(n_frames, n), traj_vz(n_frames, n))
! 真蛙跳初始化:v(0) 反推 v(-dt/2) = v(0) - 0.5*a_c(0)*dt
if (trim(method) == 'leapfrog') then
@@ -160,12 +161,19 @@ program dynamics_f90
pos_0)
end do
! 记录
prog_step = record_steps / 100
if (prog_step < 1) prog_step = 1
! 记录(每 NSTEP 步采一帧)
prog_step = max(1, record_steps / 100)
frame_idx = 0
do s = 1, record_steps
if (mod(s, prog_step) == 0 .and. s > 0) then
if (mod(s, prog_step) == 0) then
write(*, '("[Fortran-engine] progress: ", i0, "/", i0)') s, record_steps
flush(6)
end if
! 采帧:在每个 NSTEP 区间的起始时刻记录
if (mod(s-1, max(1, NSTEP)) == 0 .and. frame_idx < n_frames) then
frame_idx = frame_idx + 1
traj_x(frame_idx, :) = x; traj_y(frame_idx, :) = y; traj_z(frame_idx, :) = z
traj_vx(frame_idx, :) = vx; traj_vy(frame_idx, :) = vy; traj_vz(frame_idx, :) = vz
end if
if (driving_force /= 0 .and. n_drivers > 0) then
tw = ((s-1 + warmup_steps) * 1.0d0) * DT
@@ -178,8 +186,6 @@ program dynamics_f90
drv_eq_x, drv_eq_y, drv_eq_z, &
drv_freeze_x, drv_freeze_y, drv_freeze_z)
end if
traj_x(s, :) = x; traj_y(s, :) = y; traj_z(s, :) = z
traj_vx(s, :) = vx; traj_vy(s, :) = vy; traj_vz(s, :) = vz
call apply_step(method, n, x, y, z, vx, vy, vz, masses, G, B, &
n_bonds, bond_pairs, bond_stiffness, bond_rest_lengths, &
fixed, box_a, DT, &
@@ -188,13 +194,14 @@ program dynamics_f90
pos_0)
end do
! 输出轨迹
write(*, '("[Fortran-engine] 正在写入轨迹数据…")')
call write_json(output_dir, traj_x, traj_y, traj_z, traj_vx, traj_vy, traj_vz, &
record_steps, n_atoms, atom_ids, masses, &
NT, DT, NSTEP, warmup_steps, method, G, B, &
n_bonds, bond_pairs, bond_stiffness, bond_rest_lengths, &
driving_force)
! 输出 display.txt
write(*, '("[Fortran-engine] 正在写入 display.txt (", i0, " 帧)…")') n_frames
flush(6)
call write_display_txt(output_dir, n_frames, n_atoms, atom_ids, &
traj_x, traj_y, traj_z, traj_vx, traj_vy, traj_vz, &
NT, DT, NSTEP, warmup_steps, method, G, B, &
n_bonds, gravity_field, elastic_force, damping_force, &
driving_force, box_a, gravity_strength)
call cpu_time(t1)
elapsed = t1 - t0
@@ -985,179 +992,80 @@ subroutine apply_driving(n, x, y, z, vx, vy, vz, t, step, dt, &
end subroutine apply_driving
! ========================================================================
! JSON 输出
! display.txt 输出(与 compute.py save_display_txt 格式一致)
! ========================================================================
subroutine write_json(outdir, tx, ty, tz, tvx, tvy, tvz, &
nsteps, nat, aid, amass, &
NT, DT, NSTEP, warmup, method, G, B, &
nb, bp, bk, br, driving_force)
subroutine write_display_txt(outdir, n_frames, nat, aid, &
tx, ty, tz, tvx, tvy, tvz, &
NT, DT, NSTEP, warmup, method, G, B, &
nb, gravity_field, elastic_force, damping_force, &
driving_force, box_a, gravity_strength)
character(len=*), intent(in) :: outdir, method
integer, intent(in) :: nsteps, nat, NT, NSTEP, warmup, nb, bp(nb, 2), aid(nat), driving_force
double precision, intent(in) :: tx(nsteps, nat), ty(nsteps, nat), tz(nsteps, nat)
double precision, intent(in) :: tvx(nsteps, nat), tvy(nsteps, nat), tvz(nsteps, nat)
double precision, intent(in) :: DT, G(3), B(3), bk(nb), br(nb), amass(nat)
integer, intent(in) :: n_frames, nat, NT, NSTEP, warmup, nb
integer, intent(in) :: gravity_field, elastic_force, damping_force, driving_force
integer, intent(in) :: aid(nat)
double precision, intent(in) :: tx(n_frames, nat), ty(n_frames, nat), tz(n_frames, nat)
double precision, intent(in) :: tvx(n_frames, nat), tvy(n_frames, nat), tvz(n_frames, nat)
double precision, intent(in) :: DT, G(3), B(3), box_a, gravity_strength
character(len=512) :: path, buf
integer :: u, s, i, ib, ios
integer :: u, f, a, ios
integer :: dynamic_steps
double precision :: T_total
path = trim(outdir) // '/trajectory.txt'
dynamic_steps = NT - warmup
T_total = NT * DT
path = trim(outdir) // '/display.txt'
open(newunit=u, file=trim(path), status='replace', action='write', iostat=ios)
if (ios /= 0) then
write(*, '("[Fortran-engine] 错误: 无法写入 ", a)') trim(path)
stop
return
end if
write(u, '(a)') '{'
! traj_x
write(u, '(a)') ' "traj_x": ['
do s = 1, nsteps
call json_arr(u, tx(s, :), nat, s < nsteps, ' ')
end do
write(u, '(a)') ' ],'
! traj_y
write(u, '(a)') ' "traj_y": ['
do s = 1, nsteps
call json_arr(u, ty(s, :), nat, s < nsteps, ' ')
end do
write(u, '(a)') ' ],'
! traj_z
write(u, '(a)') ' "traj_z": ['
do s = 1, nsteps
call json_arr(u, tz(s, :), nat, s < nsteps, ' ')
end do
write(u, '(a)') ' ],'
! traj_vx
write(u, '(a)') ' "traj_vx": ['
do s = 1, nsteps
call json_arr(u, tvx(s, :), nat, s < nsteps, ' ')
end do
write(u, '(a)') ' ],'
! traj_vy
write(u, '(a)') ' "traj_vy": ['
do s = 1, nsteps
call json_arr(u, tvy(s, :), nat, s < nsteps, ' ')
end do
write(u, '(a)') ' ],'
! traj_vz
write(u, '(a)') ' "traj_vz": ['
do s = 1, nsteps
call json_arr(u, tvz(s, :), nat, s < nsteps, ' ')
end do
write(u, '(a)') ' ],'
! 标量参数
write(buf, '(a, i0, a)') ' "NT": ', NT, ','
! ── header ────────────────────────────────────────────────────────────
write(u, '("number of frames: ", i0)') n_frames
write(u, '("number of particles: ", i0)') nat
write(u, '("DT: ", g0)') DT
write(u, '("NSTEP: ", i0)') NSTEP
write(u, '("method: ", a)') trim(method)
write(u, '("NT: ", i0)') NT
write(u, '("warmup_steps: ", i0)') warmup
write(u, '("dynamic_steps: ", i0)') dynamic_steps
write(u, '("T_total: ", g0)') T_total
write(u, '("box_a: ", g0)') box_a
write(u, '("gravity_field: ", i0)') gravity_field
write(u, '("elastic_force: ", i0)') elastic_force
write(u, '("damping_force: ", i0)') damping_force
write(u, '("driving_force: ", i0)') driving_force
write(u, '("gravity_strength: ", g0)') gravity_strength
write(buf, '("G: [", g0, ", ", g0, ", ", g0, "]")') G(1), G(2), G(3)
write(u, '(a)') trim(buf)
write(buf, '(a, g0, a)') ' "DT": ', DT, ','
write(u, '(a)') trim(buf)
write(buf, '(a, i0, a)') ' "NSTEP": ', NSTEP, ','
write(u, '(a)') trim(buf)
write(buf, '(a, a, a)') ' "method": "', trim(method), '",'
write(u, '(a)') trim(buf)
write(buf, '(a, i0, a)') ' "warmup_steps": ', warmup, ','
write(buf, '("B: [", g0, ", ", g0, ", ", g0, "]")') B(1), B(2), B(3)
write(u, '(a)') trim(buf)
write(u, '("number_of_frames: ", i0)') n_frames
write(u, '("number_of_particles: ", i0)') nat
write(buf, '("X_MIN: ", g0)') -box_a; write(u, '(a)') trim(buf)
write(buf, '("X_MAX: ", g0)') box_a; write(u, '(a)') trim(buf)
write(buf, '("Y_MIN: ", g0)') -box_a; write(u, '(a)') trim(buf)
write(buf, '("Y_MAX: ", g0)') box_a; write(u, '(a)') trim(buf)
write(buf, '("Z_MIN: ", g0)') -box_a; write(u, '(a)') trim(buf)
write(buf, '("Z_MAX: ", g0)') box_a; write(u, '(a)') trim(buf)
write(buf, '(a, g0, a, g0, a, g0, a)') &
' "G": [', G(1), ', ', G(2), ', ', G(3), '],'
write(u, '(a)') trim(buf)
write(buf, '(a, g0, a, g0, a, g0, a)') &
' "B": [', B(1), ', ', B(2), ', ', B(3), '],'
write(u, '(a)') trim(buf)
! 原子信息
write(u, '(a)', advance='no') ' "atom_ids": ['
do i = 1, nat
if (i > 1) write(u, '(a)', advance='no') ','
write(u, '(i0)', advance='no') aid(i)
! ── frame data ────────────────────────────────────────────────────────
do f = 1, n_frames
write(u, '()') ! 空行
write(u, '("frame: ", i0)') f
write(u, '("n x y z vx vy vz")')
do a = 1, nat
write(u, '(i0, 6(f13.6))') aid(a), &
tx(f,a), ty(f,a), tz(f,a), tvx(f,a), tvy(f,a), tvz(f,a)
end do
end do
write(u, '(a)') '],'
write(u, '(a)', advance='no') ' "atom_masses": ['
do i = 1, nat
if (i > 1) write(u, '(a)', advance='no') ','
write(u, '(g0)', advance='no') amass(i)
end do
write(u, '(a)') '],'
! 成键
if (nb > 0) then
call write_int2_arr(u, 'bond_pairs', bp, nb, .true.)
call write_dbl_arr(u, 'bond_stiffness', bk, nb, .true.)
call write_dbl_arr(u, 'bond_rest_lengths', br, nb, .true.)
else
write(u, '(a)') ' "bond_pairs": [],'
write(u, '(a)') ' "bond_stiffness": [],'
write(u, '(a)') ' "bond_rest_lengths": [],'
end if
write(buf, '(a, i0)') ' "driving_force": ', driving_force
write(u, '(a)') trim(buf)
write(u, '(a)') '}'
close(u)
end subroutine write_json
! 写出单行 JSON 数组 [v1, v2, ...]
subroutine json_arr(u, vals, n, has_next, indent)
integer, intent(in) :: u, n
double precision, intent(in) :: vals(n)
logical, intent(in) :: has_next
character(len=*), intent(in) :: indent
integer :: i
write(u, '(a)', advance='no') indent // '['
do i = 1, n
if (i > 1) write(u, '(a)', advance='no') ','
write(u, '(g0.8)', advance='no') vals(i)
end do
if (has_next) then
write(u, '(a)') '],'
else
write(u, '(a)') ']'
end if
end subroutine json_arr
subroutine write_int2_arr(u, name, arr, n, has_next)
integer, intent(in) :: u, n, arr(n, 2)
character(len=*), intent(in) :: name
logical, intent(in) :: has_next
character(len=65536) :: buf
integer :: i, pos
write(u, '(a)', advance='no') ' "' // trim(name) // '": ['
do i = 1, n
if (i > 1) write(u, '(a)', advance='no') ','
write(buf, '(a, i0, a, i0, a)') '[', arr(i, 1), ',', arr(i, 2), ']'
write(u, '(a)', advance='no') trim(buf)
end do
if (has_next) then
write(u, '(a)') '],'
else
write(u, '(a)') ']'
end if
end subroutine write_int2_arr
subroutine write_dbl_arr(u, name, arr, n, has_next)
integer, intent(in) :: u, n
double precision, intent(in) :: arr(n)
character(len=*), intent(in) :: name
logical, intent(in) :: has_next
integer :: i
write(u, '(a)', advance='no') ' "' // trim(name) // '": ['
do i = 1, n
if (i > 1) write(u, '(a)', advance='no') ','
write(u, '(g0.8)', advance='no') arr(i)
end do
if (has_next) then
write(u, '(a)') '],'
else
write(u, '(a)') ']'
end if
end subroutine write_dbl_arr
write(*, '("[Fortran-engine] display.txt 已保存: ", a)') trim(path)
flush(6)
end subroutine write_display_txt
end program dynamics_f90