From 6c06c00f4b6a0641e320e8bce26f75d814b377e7 Mon Sep 17 00:00:00 2001 From: Ying-Li Niu <64801511@qq.com> Date: Fri, 19 Jun 2026 08:05:05 +0800 Subject: [PATCH] fix: Fortran engine use_marker/alpha header passthrough + case04 Moon orbit fix MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - engines/fortran/main.f90: - 新增 use_marker 和 alpha_str 的读取、传递、写入 display.txt header - 新增 json_get_alpha 函数兼容 JSON 单值或 6 元数组 - engines/release/: 引擎校准缓存 & fortran.json 参数 - examples/case04/: 修正月球位置 (11.5→10.5) 和速度 (526→647), 地月距缩至希尔半径以内 (0.5 < 1.0), 新增希尔半径验证说明 - examples/Readme.html: case04/case09 描述更新 --- engines/fortran/main.f90 | 77 ++++++++++++++++++++++++++--- engines/release/_calib_c.json | 2 +- engines/release/_calib_fortran.json | 1 + engines/release/fortran.json | 51 +++++++++++++++++++ examples/Readme.html | 12 ++--- examples/case04/Readme.html | 40 +++++++++------ examples/case04/input/coord.txt | 8 +-- examples/case04/input/input.txt | 2 +- 8 files changed, 158 insertions(+), 35 deletions(-) create mode 100644 engines/release/_calib_fortran.json create mode 100644 engines/release/fortran.json diff --git a/engines/fortran/main.f90 b/engines/fortran/main.f90 index 2e90c05..06a8afc 100644 --- a/engines/fortran/main.f90 +++ b/engines/fortran/main.f90 @@ -21,6 +21,8 @@ program dynamics_f90 integer :: driving_force double precision :: gravity_strength character(len=32) :: method + integer :: use_marker + character(len=512) :: alpha_str double precision :: t0, t1, elapsed, tw ! 原子数据 @@ -71,7 +73,8 @@ program dynamics_f90 ! 读取 param.json call read_params(param_path, box_a, NT, DT, NSTEP, warmup_steps, method, G, B, & gravity_field, gravity_interaction, & - elastic_force, damping_force, gravity_strength, driving_force) + elastic_force, damping_force, gravity_strength, driving_force, & + use_marker, alpha_str) ! 读取 coord.txt call read_coord(input_dir, n_atoms, atom_ids, masses, radii, pos_0, vel_0, fixed) @@ -201,7 +204,8 @@ program dynamics_f90 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) + driving_force, box_a, gravity_strength, & + use_marker, alpha_str) call cpu_time(t1) elapsed = t1 - t0 @@ -228,15 +232,17 @@ contains ! ======================================================================== subroutine read_params(path, box_a, NT, DT, NSTEP, warmup_steps, method, G, B, & gravity_field, gravity_interaction, & - elastic_force, damping_force, gravity_strength, driving_force) + elastic_force, damping_force, gravity_strength, driving_force, & + use_marker, alpha_str) character(len=*), intent(in) :: path double precision, intent(out) :: box_a, DT, G(3), B(3), gravity_strength integer, intent(out) :: NT, NSTEP, warmup_steps integer, intent(out) :: gravity_field, gravity_interaction, elastic_force, damping_force, driving_force - character(len=*), intent(out) :: method + integer, intent(out) :: use_marker + character(len=*), intent(out) :: method, alpha_str character(len=8096) :: buf character(len=256) :: line - integer :: u, ios + integer :: u, ios, i box_a = 10.0d0; NT = 10000; DT = 0.001d0; NSTEP = 100; warmup_steps = 0 method = 'leapfrog' @@ -244,6 +250,8 @@ subroutine read_params(path, box_a, NT, DT, NSTEP, warmup_steps, method, G, B, & gravity_field = 1; gravity_interaction = 0 elastic_force = 1; damping_force = 0; gravity_strength = 1.0d0 driving_force = 0 + use_marker = 0 + alpha_str = '0.2' open(newunit=u, file=trim(path), status='old', action='read', iostat=ios) if (ios /= 0) then @@ -274,6 +282,8 @@ subroutine read_params(path, box_a, NT, DT, NSTEP, warmup_steps, method, G, B, & damping_force = json_get_int(buf, 'damping_force', 0) gravity_strength = json_get_double(buf, 'gravity_strength', 1.0d0) driving_force = json_get_int(buf, 'driving_force', 0) + use_marker = json_get_int(buf, 'use_marker', 0) + call json_get_alpha(buf, 'alpha', alpha_str) end subroutine read_params ! ======================================================================== @@ -323,6 +333,55 @@ subroutine json_get_double3(buf, key, vals) end do end subroutine json_get_double3 +! 读取 alpha:兼容单值 (0.2) 或 6 元数组 [0.0,0.0,0.0,0.0,0.0,0.0] +! 输出为逗号分隔字符串,与 draw.py 的解析格式一致 +subroutine json_get_alpha(buf, key, val) + character(len=*), intent(in) :: buf, key + character(len=*), intent(out) :: val + double precision :: d6(6) + integer :: p, i, ios + character(len=32) :: tmp + val = '0.2' + p = index(buf, '"' // key // '"') + if (p == 0) return + p = index(buf(p:), ':') + p + ! skip whitespace + do while (p <= len(buf) .and. (buf(p:p) == ':' .or. buf(p:p) == ' ' & + .or. buf(p:p) == char(9) .or. buf(p:p) == char(10))) + p = p + 1 + end do + if (buf(p:p) == '[') then + ! 6 元数组 + d6 = 0.2d0 + p = p + 1 + do i = 1, 6 + do while (p <= len(buf) .and. (buf(p:p) == ' ' .or. buf(p:p) == ',' & + .or. buf(p:p) == char(9) .or. buf(p:p) == char(10))) + p = p + 1 + end do + if (p > len(buf) .or. buf(p:p) == ']') exit + read(buf(p:), *, iostat=ios) d6(i) + if (ios /= 0) exit + do while (p <= len(buf) .and. buf(p:p) /= ',' .and. buf(p:p) /= ']') + p = p + 1 + end do + end do + val = '' + do i = 1, 6 + write(tmp, '(f0.6)') d6(i) + if (i > 1) val = trim(val) // ',' + val = trim(val) // trim(tmp) + end do + else + ! 单值标量 + read(buf(p:), *, iostat=ios) d6(1) + if (ios == 0) then + write(tmp, '(f0.6)') d6(1) + val = trim(tmp) + end if + end if +end subroutine json_get_alpha + ! 从 JSON 中读取字符串值 subroutine json_get_string(buf, key, val) character(len=*), intent(in) :: buf, key @@ -999,10 +1058,12 @@ 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 + driving_force, box_a, gravity_strength, & + use_marker, alpha_str) + character(len=*), intent(in) :: outdir, method, alpha_str integer, intent(in) :: n_frames, nat, NT, NSTEP, warmup, nb integer, intent(in) :: gravity_field, elastic_force, damping_force, driving_force + integer, intent(in) :: use_marker 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) @@ -1051,6 +1112,8 @@ subroutine write_display_txt(outdir, n_frames, nat, aid, & 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(u, '("use_marker: ", i0)') use_marker + write(u, '("alpha: ", a)') trim(alpha_str) ! ── frame data ──────────────────────────────────────────────────────── do f = 1, n_frames diff --git a/engines/release/_calib_c.json b/engines/release/_calib_c.json index d19b77c..c879a09 100644 --- a/engines/release/_calib_c.json +++ b/engines/release/_calib_c.json @@ -1 +1 @@ -{"n_atoms": 40, "nt": 10000, "step_time": 0.00015027170181274412} \ No newline at end of file +{"n_atoms": 40, "nt": 10000, "step_time": 3.113259077072144e-05} \ No newline at end of file diff --git a/engines/release/_calib_fortran.json b/engines/release/_calib_fortran.json new file mode 100644 index 0000000..3ec89e5 --- /dev/null +++ b/engines/release/_calib_fortran.json @@ -0,0 +1 @@ +{"n_atoms": 40, "nt": 200000, "step_time": 0.0002908185601234436} \ No newline at end of file diff --git a/engines/release/fortran.json b/engines/release/fortran.json new file mode 100644 index 0000000..a25e603 --- /dev/null +++ b/engines/release/fortran.json @@ -0,0 +1,51 @@ +{ + "box_a": 300.0, + "NT": 200000, + "DT": 0.001, + "NSTEP": 100, + "warmup_steps": 0, + "method": "leapfrog", + "G": [ + 0.0, + 0.0, + 0.0 + ], + "B": [ + 0.005, + 0.0, + 0.005 + ], + "gravity_field": 0, + "gravity_interaction": 0, + "elastic_force": 1, + "damping_force": 0, + "gravity_strength": 1.0, + "driving_force": 1, + "save_trajectory": 0, + "alpha": [ + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0 + ], + "ball_radius": 0.5, + "ball_color": [ + 0.2, + 0.6, + 0.9 + ], + "box_color": [ + 0.8, + 0.8, + 0.85 + ], + "use_marker": 1, + "camera_distance": 60.0, + "camera_elevation": 0.0, + "camera_azimuth": 0.0, + "camera_center_x": 30.0, + "camera_center_y": 0.0, + "camera_center_z": 0.0 +} \ No newline at end of file diff --git a/examples/Readme.html b/examples/Readme.html index 5aa9d2b..8443a78 100644 --- a/examples/Readme.html +++ b/examples/Readme.html @@ -210,7 +210,7 @@
三体系统稳定椭圆轨道
+三体系统稳定轨道,经希尔半径检验