void put_atoms_in_box_omp(int ePBC, matrix box, int natoms, rvec x[]) { int t, nth; nth = gmx_omp_nthreads_get(emntDefault); #pragma omp parallel for num_threads(nth) schedule(static) for (t = 0; t < nth; t++) { int offset, len; offset = (natoms*t )/nth; len = (natoms*(t + 1))/nth - offset; put_atoms_in_box(ePBC, box, len, x + offset); } }
void add_conf(t_atoms *atoms, rvec **x, rvec **v, real **r, gmx_bool bSrenew, int ePBC, matrix box, gmx_bool bInsert, t_atoms *atoms_solvt, rvec *x_solvt, rvec *v_solvt, real *r_solvt, gmx_bool bVerbose, real rshell, int max_sol, const output_env_t oenv) { t_nblist *nlist; t_atoms *atoms_all; real max_vdw, *r_prot, *r_all, n2, r2, ib1, ib2; int natoms_prot, natoms_solvt; int i, j, jj, m, j0, j1, jjj, jnres, jnr, inr, iprot, is1, is2; int prev, resnr, nresadd, d, k, ncells, maxincell; int dx0, dx1, dy0, dy1, dz0, dz1; int ntest, nremove, nkeep; rvec dx, xi, xj, xpp, *x_all, *v_all; gmx_bool *remove, *keep; int bSolSol; natoms_prot = atoms->nr; natoms_solvt = atoms_solvt->nr; if (natoms_solvt <= 0) { fprintf(stderr, "WARNING: Nothing to add\n"); return; } if (ePBC == epbcSCREW) { gmx_fatal(FARGS, "Sorry, %s pbc is not yet supported", epbc_names[ePBC]); } if (bVerbose) { fprintf(stderr, "Calculating Overlap...\n"); } /* Set margin around box edges to largest solvent dimension. * The maximum distance between atoms in a solvent molecule should * be calculated. At the moment a fudge factor of 3 is used. */ r_prot = *r; box_margin = 3*find_max_real(natoms_solvt, r_solvt); max_vdw = max(3*find_max_real(natoms_prot, r_prot), box_margin); fprintf(stderr, "box_margin = %g\n", box_margin); snew(remove, natoms_solvt); nremove = 0; if (!bInsert) { for (i = 0; i < atoms_solvt->nr; i++) { if (outside_box_plus_margin(x_solvt[i], box) ) { i = mark_res(i, remove, atoms_solvt->nr, atoms_solvt->atom, &nremove); } } fprintf(stderr, "Removed %d atoms that were outside the box\n", nremove); } /* Define grid stuff for genbox */ /* Largest VDW radius */ snew(r_all, natoms_prot+natoms_solvt); for (i = j = 0; i < natoms_prot; i++, j++) { r_all[j] = r_prot[i]; } for (i = 0; i < natoms_solvt; i++, j++) { r_all[j] = r_solvt[i]; } /* Combine arrays */ combine_atoms(atoms, atoms_solvt, *x, v ? *v : NULL, x_solvt, v_solvt, &atoms_all, &x_all, &v_all); /* Do neighboursearching step */ do_nsgrid(stdout, bVerbose, box, x_all, atoms_all, max_vdw, oenv); /* check solvent with solute */ nlist = &(fr->nblists[0].nlist_sr[eNL_VDW]); fprintf(stderr, "nri = %d, nrj = %d\n", nlist->nri, nlist->nrj); for (bSolSol = 0; (bSolSol <= (bInsert ? 0 : 1)); bSolSol++) { ntest = nremove = 0; fprintf(stderr, "Checking %s-Solvent overlap:", bSolSol ? "Solvent" : "Protein"); for (i = 0; (i < nlist->nri && nremove < natoms_solvt); i++) { inr = nlist->iinr[i]; j0 = nlist->jindex[i]; j1 = nlist->jindex[i+1]; rvec_add(x_all[inr], fr->shift_vec[nlist->shift[i]], xi); for (j = j0; (j < j1 && nremove < natoms_solvt); j++) { jnr = nlist->jjnr[j]; copy_rvec(x_all[jnr], xj); /* Check solvent-protein and solvent-solvent */ is1 = inr-natoms_prot; is2 = jnr-natoms_prot; /* Check if at least one of the atoms is a solvent that is not yet * listed for removal, and if both are solvent, that they are not in the * same residue. */ if ((!bSolSol && bXor((is1 >= 0), (is2 >= 0)) && /* One atom is protein */ ((is1 < 0) || ((is1 >= 0) && !remove[is1])) && ((is2 < 0) || ((is2 >= 0) && !remove[is2]))) || (bSolSol && (is1 >= 0) && (!remove[is1]) && /* is1 is solvent */ (is2 >= 0) && (!remove[is2]) && /* is2 is solvent */ (bInsert || /* when inserting also check inside the box */ (outside_box_minus_margin2(x_solvt[is1], box) && /* is1 on edge */ outside_box_minus_margin2(x_solvt[is2], box)) /* is2 on edge */ ) && (atoms_solvt->atom[is1].resind != /* Not the same residue */ atoms_solvt->atom[is2].resind))) { ntest++; rvec_sub(xi, xj, dx); n2 = norm2(dx); r2 = sqr(r_all[inr]+r_all[jnr]); if (n2 < r2) { if (bInsert) { nremove = natoms_solvt; for (k = 0; k < nremove; k++) { remove[k] = TRUE; } } /* Need only remove one of the solvents... */ if (is2 >= 0) { (void) mark_res(is2, remove, natoms_solvt, atoms_solvt->atom, &nremove); } else if (is1 >= 0) { (void) mark_res(is1, remove, natoms_solvt, atoms_solvt->atom, &nremove); } else { fprintf(stderr, "Neither atom is solvent%d %d\n", is1, is2); } } } } } if (!bInsert) { fprintf(stderr, " tested %d pairs, removed %d atoms.\n", ntest, nremove); } } if (debug) { for (i = 0; i < natoms_solvt; i++) { fprintf(debug, "remove[%5d] = %s\n", i, bool_names[remove[i]]); } } /* Search again, now with another cut-off */ if (rshell > 0) { do_nsgrid(stdout, bVerbose, box, x_all, atoms_all, rshell, oenv); nlist = &(fr->nblists[0].nlist_sr[eNL_VDW]); fprintf(stderr, "nri = %d, nrj = %d\n", nlist->nri, nlist->nrj); nkeep = 0; snew(keep, natoms_solvt); for (i = 0; i < nlist->nri; i++) { inr = nlist->iinr[i]; j0 = nlist->jindex[i]; j1 = nlist->jindex[i+1]; for (j = j0; j < j1; j++) { jnr = nlist->jjnr[j]; /* Check solvent-protein and solvent-solvent */ is1 = inr-natoms_prot; is2 = jnr-natoms_prot; /* Check if at least one of the atoms is a solvent that is not yet * listed for removal, and if both are solvent, that they are not in the * same residue. */ if (is1 >= 0 && is2 < 0) { mark_res(is1, keep, natoms_solvt, atoms_solvt->atom, &nkeep); } else if (is1 < 0 && is2 >= 0) { mark_res(is2, keep, natoms_solvt, atoms_solvt->atom, &nkeep); } } } fprintf(stderr, "Keeping %d solvent atoms after proximity check\n", nkeep); for (i = 0; i < natoms_solvt; i++) { remove[i] = remove[i] || !keep[i]; } sfree(keep); } /* count how many atoms and residues will be added and make space */ if (bInsert) { j = atoms_solvt->nr; jnres = atoms_solvt->nres; } else { j = 0; jnres = 0; for (i = 0; ((i < atoms_solvt->nr) && ((max_sol == 0) || (jnres < max_sol))); i++) { if (!remove[i]) { j++; if ((i == 0) || (atoms_solvt->atom[i].resind != atoms_solvt->atom[i-1].resind)) { jnres++; } } } } if (debug) { fprintf(debug, "Will add %d atoms in %d residues\n", j, jnres); } if (!bInsert) { /* Flag the remaing solvent atoms to be removed */ jjj = atoms_solvt->atom[i-1].resind; for (; (i < atoms_solvt->nr); i++) { if (atoms_solvt->atom[i].resind > jjj) { remove[i] = TRUE; } else { j++; } } } if (bSrenew) { srenew(atoms->resinfo, atoms->nres+jnres); srenew(atoms->atomname, atoms->nr+j); srenew(atoms->atom, atoms->nr+j); srenew(*x, atoms->nr+j); if (v) { srenew(*v, atoms->nr+j); } srenew(*r, atoms->nr+j); } /* add the selected atoms_solvt to atoms */ if (atoms->nr > 0) { resnr = atoms->resinfo[atoms->atom[atoms->nr-1].resind].nr; } else { resnr = 0; } prev = -1; nresadd = 0; for (i = 0; i < atoms_solvt->nr; i++) { if (!remove[i]) { if (prev == -1 || atoms_solvt->atom[i].resind != atoms_solvt->atom[prev].resind) { nresadd++; atoms->nres++; resnr++; atoms->resinfo[atoms->nres-1] = atoms_solvt->resinfo[atoms_solvt->atom[i].resind]; atoms->resinfo[atoms->nres-1].nr = resnr; /* calculate shift of the solvent molecule using the first atom */ copy_rvec(x_solvt[i], dx); put_atoms_in_box(ePBC, box, 1, &dx); rvec_dec(dx, x_solvt[i]); } atoms->atom[atoms->nr] = atoms_solvt->atom[i]; atoms->atomname[atoms->nr] = atoms_solvt->atomname[i]; rvec_add(x_solvt[i], dx, (*x)[atoms->nr]); if (v) { copy_rvec(v_solvt[i], (*v)[atoms->nr]); } (*r)[atoms->nr] = r_solvt[i]; atoms->atom[atoms->nr].resind = atoms->nres-1; atoms->nr++; prev = i; } } if (bSrenew) { srenew(atoms->resinfo, atoms->nres+nresadd); } if (bVerbose) { fprintf(stderr, "Added %d molecules\n", nresadd); } sfree(remove); done_atom(atoms_all); sfree(x_all); sfree(v_all); }
int main(int argc,char *argv[]) { static char *desc[] = { "testlr tests the PPPM and Ewald method for the", "long range electrostatics problem." }; static t_filenm fnm[] = { { efTPX, NULL, NULL, ffREAD }, { efHAT, "-g", "ghat", ffOPTRD }, { efOUT, "-o", "rho", ffOPTWR }, { efOUT, "-op", "lr-pb", ffOPTWR }, { efOUT, "-of", "lr-four", ffOPTWR }, { efOUT, "-opt", "tot-pb", ffOPTWR }, { efOUT, "-oft", "tot-four", ffOPTWR }, { efOUT, "-fin", "lr-four", ffOPTWR }, { efEPS, "-es", "sr", ffOPTWR }, { efEPS, "-elf", "lr-four", ffOPTWR }, { efEPS, "-etf", "tot-four", ffOPTWR }, { efEPS, "-qr", "qk-real", ffOPTWR }, { efEPS, "-qi", "qk-im", ffOPTWR }, { efEPS, "-elp", "lr-pb", ffOPTWR }, { efEPS, "-etp", "tot-pb", ffOPTWR }, { efEPS, "-rho", "rho", ffOPTWR }, { efEPS, "-qq", "charge", ffOPTWR }, { efXVG, "-gt", "gk-tab", ffOPTWR }, { efXVG, "-fcorr","fcorr", ffWRITE }, { efXVG, "-pcorr","pcorr", ffWRITE }, { efXVG, "-ftotcorr","ftotcorr", ffWRITE }, { efXVG, "-ptotcorr","ptotcorr", ffWRITE }, { efLOG, "-l", "fptest", ffWRITE }, { efXVG, "-gr", "spread", ffOPTWR }, { efPDB, "-pf", "pqr-four", ffOPTWR }, { efPDB, "-phitot", "pppm-phitot", ffOPTWR } }; #define NFILE asize(fnm) FILE *log; t_topology top; t_tpxheader stath; t_inputrec ir; t_block *excl; t_forcerec *fr; t_commrec *cr; t_mdatoms *mdatoms; t_graph *graph; int i,step,nre,natoms,nmol; rvec *x,*f_sr,*f_excl,*f_four,*f_pppm,*f_pois,box_size,hbox; matrix box; real t,lambda,vsr,*charge,*phi_f,*phi_pois,*phi_s,*phi_p3m,*rho; static bool bFour=FALSE,bVerbose=FALSE,bGGhat=FALSE,bPPPM=TRUE, bPoisson=FALSE,bOld=FALSE,bOldEwald=TRUE; static int nprocs = 1; static t_pargs pa[] = { { "-np", FALSE, etINT, &nprocs, "Do it in parallel" }, { "-ewald", FALSE, etBOOL, &bFour, "Do an Ewald solution"}, { "-pppm", FALSE, etBOOL, &bPPPM, "Do a PPPM solution" }, { "-poisson",FALSE, etBOOL, &bPoisson,"Do a Poisson solution" }, { "-v", FALSE, etBOOL, &bVerbose,"Verbose on"}, { "-ghat", FALSE, etBOOL, &bGGhat, "Generate Ghat function"}, { "-old", FALSE, etBOOL, &bOld, "Use old function types"}, { "-oldewald",FALSE,etBOOL, &bOldEwald,"Use old Ewald code"} }; CopyRight(stderr,argv[0]); parse_common_args(&argc,argv,PCA_CAN_TIME | PCA_CAN_VIEW, NFILE,fnm,asize(pa),pa,asize(desc),desc,0,NULL); if (nprocs > 1) { cr = init_par(&argc,argv); open_log(ftp2fn(efLOG,NFILE,fnm),cr); log = stdlog; } else { cr = init_par(&argc,argv); log = ftp2FILE(efLOG,NFILE,fnm,"w"); stdlog = log; } /* Read topology and coordinates */ read_tpxheader(ftp2fn(efTPX,NFILE,fnm),&stath,FALSE); snew(x,stath.natoms); snew(f_sr,stath.natoms); snew(f_excl,stath.natoms); snew(f_four,stath.natoms); snew(f_pppm,stath.natoms); snew(f_pois,stath.natoms); read_tpx(ftp2fn(efTPX,NFILE,fnm),&step,&t,&lambda,&ir, box,&natoms,x,NULL,NULL,&top); excl=&(top.atoms.excl); nmol=top.blocks[ebMOLS].nr; /* Allocate space for potential, charges and rho (charge density) */ snew(charge,stath.natoms); snew(phi_f,stath.natoms); snew(phi_p3m,stath.natoms); snew(phi_pois,stath.natoms); snew(phi_s,stath.natoms); snew(rho,stath.natoms); /* Set the charges */ for(i=0; (i<natoms); i++) charge[i]=top.atoms.atom[i].q; /* Make a simple box vector instead of tensor */ for(i=0; (i<DIM); i++) box_size[i]=box[i][i]; /* Set some constants */ fr = mk_forcerec(); mdatoms = atoms2md(&(top.atoms),FALSE,FALSE); set_LRconsts(log,ir.rcoulomb_switch,ir.rcoulomb,box_size,fr); init_forcerec(log,fr,&ir,&(top.blocks[ebMOLS]),cr, &(top.blocks[ebCGS]),&(top.idef),mdatoms,box,FALSE); calc_shifts(box,box_size,fr->shift_vec,FALSE); /* Periodicity stuff */ graph = mk_graph(&(top.idef),top.atoms.nr,FALSE,FALSE); shift_self(graph,fr->shift_vec,x); calc_LRcorrections(log,0,natoms,ir.rcoulomb_switch, ir.rcoulomb,charge,excl,x,f_excl,bOld); pr_f("f_excl.dat",natoms,f_excl); /* Compute the short range potential */ put_atoms_in_box(natoms,box,x); vsr=phi_sr(log,natoms,x,charge,ir.rcoulomb, ir.rcoulomb_switch,box_size,phi_s,excl,f_sr,bOld); pr_f("f_sr.dat",natoms,f_sr); /* Plot the short range potential in a matrix */ calc_ener(log,"Short Range",TRUE,nmol,natoms,phi_s,charge,excl); if (bFour) test_four(log,NFILE,fnm,&(top.atoms),&ir,x,f_four,box_size,charge,phi_f, phi_s,nmol,cr,bOld,bOldEwald); if (bPPPM) test_pppm(log,bVerbose,bGGhat,opt2fn("-g",NFILE,fnm), &(top.atoms),&ir,x,f_pppm,charge,box_size,phi_p3m,phi_s,nmol, cr,bOld,&(top.blocks[ebCGS])); if (bPoisson) test_poisson(log,bVerbose, &(top.atoms),&ir,x,f_pois,charge,box_size,phi_pois, phi_s,nmol,cr,bFour,f_four,phi_f,bOld); if (bPPPM && bFour) analyse_diff(log,"PPPM", top.atoms.nr,f_four,f_pppm,phi_f,phi_p3m,phi_s, opt2fn("-fcorr",NFILE,fnm), opt2fn("-pcorr",NFILE,fnm), opt2fn("-ftotcorr",NFILE,fnm), opt2fn("-ptotcorr",NFILE,fnm)); if (bPoisson && bFour) analyse_diff(log,"Poisson", top.atoms.nr,f_four,f_pois,phi_f,phi_pois,phi_s, opt2fn("-fcorr",NFILE,fnm), opt2fn("-pcorr",NFILE,fnm), opt2fn("-ftotcorr",NFILE,fnm), opt2fn("-ptotcorr",NFILE,fnm)); gmx_fio_fclose(log); thanx(stderr); return 0; }