设计思想:
- 面向对象;
- 简单易用;
- 高效灵活;
- 仅实施必要的计算, 不引入不必要的CPU计算换时间。
仅支持 FPM/Meson/Visual-Studio、
其他编译系统可直接复制源文件、
并测试了 ifort/ifx
和 gfortran
编译器。
要在fpm
项目中使用nnps
,请在fpm.toml
文件中添加以下几行:
[dependencies]
nnps = { git = "https://gitee.com/zoziha/nnps" }
注意:Windows-ifort bug,使用 OpenMP 静态编译会导致可分配数组出现问题!请使用 /libs:dll
编译选项!
或者取消 fpm.toml
的 OpenMP 依赖,使用串行版本:
fpm run --flag '/DSERIAL' --profile release --example --all --compiler ifort
Windows 10, R5-2500U, 1 Core, Release Mode:
编译器 | 选项 | grid2d(s) | grid3d(s) |
---|---|---|---|
gfortran | 12.031 | 30.297 | |
ifort | /heap-arrays:0 | 36.515 | 77.784 |
ifx | /heap-arrays:0 | 37.021 | - |
OneAPI Fortran 在开启标准语义后性能下降,且它对复杂派生类型的性能支撑一般,GFortran 取得头筹, 当然差一倍的性能差距是可以接受的。
对于 2D/3D NNPS,OpenMP 用于并行加速,并行线程可通过 OMP_NUM_THREADS
环境变量设置。
fpm run --example --all # 运行所有示例
program example_grid2d
use nnps_module, only: nnps_grid2d, wp
use display_module, only: display
implicit none
type(nnps_grid2d) :: nnps
real(wp), dimension(2, 4) :: loc = reshape([0.0_wp, 1.0_wp, 2.0_wp, 1.5_wp, &
1.0_wp, 1.0_wp, 0.5_wp, 1.0_wp], [2, 4])
integer, pointer :: pairs(:)
real(wp), pointer :: rdxs(:)
call nnps%init(loc, n=4)
call nnps%query(0.6_wp, pairs, rdxs, n=4)
print *, '*** grid find (2D)'
call display(pairs, 'pairs index:', brief=.false.)
call display(loc(:, pairs), 'pairs coordinates:', brief=.false.)
call display(rdxs, 'rdxs:', brief=.false.)
end program example_grid2d
! *** grid find (2D)
! [vector: 4] pairs index:
! 3, 4, 4, 1
! [matrix: 2*4] pairs coordinates:
! 1.000E+00, 5.000E-01, 5.000E-01, 0.000E+00;
! 1.000E+00, 1.000E+00, 1.000E+00, 1.000E+00
! [vector: 6] rdxs:
! 5.000E-01, 5.000E-01, 0.000E+00, 5.000E-01, 5.000E-01, 0.000E+00
这个库最初是研究 SPH 粒子法的 NNPS 算法,现在已经引入到 SPH 代码中,参见 zoziha/SPH。