mdrunner函数在runner.c和runner_openmm.c中均有,是MD模拟的主要程序之一。但是对另一个do_md函数的调用一直是个谜,今天终于看出了点头绪。
这里以runner.c中的mdrunner作为例子:
先看一个Interator的定义,在这里我们发现了do_md的影子。
Interator有积分器,综合者的意思
/* The array should match theeI array in include/types/enums.h */
const gmx_intp_t Interator[eiNR] = { {do_md},{do_steep}, {do_cg}, {do_md}, {do_md}, {do_nm}, {do_lbfgs}, {do_tpi}, {do_tpi},{do_md}, {do_md}, {do_md}};
就好奇gmx_intp_t是什么类型的结构,看一下:
typedef struct {
gmx_integrator_t *func;
} gmx_intp_t;
位置就在其定义上面,然后看下gmx_integrator_t的定义:
typedef doublegmx_integrator_t (FILE *log, t_commrec *cr,
int nfile,const t_filenm fnm[],
const output_env_toenv, gmx_bool bVerbose,
gmx_boolbCompact, int nstglobalcomm,
gmx_vsite_t*vsite, gmx_constr_t constr,
int stepout,
t_inputrec*inputrec,
gmx_mtop_t*mtop, t_fcdata *fcd,
t_state*state,
t_mdatoms*mdatoms,
t_nrnb *nrnb, gmx_wallcycle_t wcycle,
gmx_edsam_ted,
t_forcerec*fr,
intrepl_ex_nst, int repl_ex_nex, int repl_ex_seed,
gmx_membed_t membed,
realcpt_period, real max_hours,
const char*deviceOptions,
unsigned longFlags,
gmx_runtime_t*runtime);
原来是一个方法的typedef声明,那integrator就是eiNR个包含gmx_integrator_t函数的gmx_intp_t结构体数组。有点绕。
通过integrator定义前面的注释,我们找到了eiNR在enums.h中的定义
enum {
eiMD, eiSteep, eiCG, eiBD,eiSD2, eiNM, eiLBFGS, eiTPI, eiTPIC, eiSD1, eiVV, eiVVAK, eiNR
};
但是不理解里面说的match是怎么match的。
下一次对主要嫌疑人的integrator见面在这:
if (integrator[inputrec->eI].func ==do_md)
{
/* Turn on signal handling on all nodes*/
/*
* (A user signal from the PME nodes(if any)
* is communicated to the PP nodes.
*/
signal_handler_install();
}
这里好像注册了一个信号,具体是干什么的,还未知。
然后就是:
/* Now do whatever the userwants us to do (how flexible...) */
integrator[inputrec->eI].func(fplog,cr, nfile, fnm,
oenv,bVerbose, bCompact,
nstglobalcomm,
vsite,constr,
nstepout,inputrec, mtop,
fcd,state,
mdatoms,nrnb, wcycle, ed, fr,
repl_ex_nst, repl_ex_nex, repl_ex_seed,
membed,
cpt_period, max_hours,
deviceOptions,
Flags,