void apbsnlinduce_(double uinp[maxatm][3], double fld[maxatm][3]){ /* Misc. pointers to APBS data structures */ Vpmg *pmg[NOSH_MAXCALC]; Vpmgp *pmgp[NOSH_MAXCALC]; Vpbe *pbe[NOSH_MAXCALC]; MGparm *mgparm = VNULL; PBEparm *pbeparm = VNULL; Vatom *atom = VNULL; /* Observables and unit conversion */ double field[3]; double sign,kT,electric; /* Potential Vgrid construction */ double nx,ny,nz,hx,hy,hzed,xmin,ymin,zmin; double *data; /* Loop variables */ int i,j; VASSERT(nosh != VNULL); for (i=0; i<NOSH_MAXCALC; i++) { pmg[i] = VNULL; pmgp[i] = VNULL; pbe[i] = VNULL; } /* Read TINKER induce input data into Vatom instances. */ for (i=0; i < alist[0]->number; i++){ atom = Valist_getAtom(alist[0],i); Vatom_setNLInducedDipole(atom, uinp[i]); for (j=0;j<3;j++){ fld[i][j] = 0.0; } } /* Solve the LPBE for the homogeneous system, then solvated. */ for (i=0; i<2; i++) { pmg[i] = VNULL; pmgp[i] = VNULL; pbe[i] = VNULL; /* Useful local variables */ mgparm = nosh->calc[i]->mgparm; pbeparm = nosh->calc[i]->pbeparm; if (!MGparm_check(mgparm)){ printf("MGparm Check failed\n"); exit(-1); } if (!PBEparm_check(pbeparm)){ printf("PBEparm Check failed\n"); exit(-1); } /* Set up problem */ mgparm->chgs = VCM_NLINDUCED; if (!initMG(i, nosh, mgparm, pbeparm, realCenter, pbe, alist, dielXMap, dielYMap, dielZMap, kappaMap, chargeMap, pmgp, pmg, potMap)) { Vnm_tprint( 2, "Error setting up MG calculation!\n"); return; } /* Solve the PDE */ if (solveMG(nosh, pmg[i], mgparm->type) != 1) { Vnm_tprint(2, "Error solving PDE!\n"); return; } /* Set partition information for observables and I/O */ if (setPartMG(nosh, mgparm, pmg[i]) != 1) { Vnm_tprint(2, "Error setting partition info!\n"); return; } /* Save the potential due to non-local induced dipoles */ nx = pmg[i]->pmgp->nx; ny = pmg[i]->pmgp->ny; nz = pmg[i]->pmgp->nz; hx = pmg[i]->pmgp->hx; hy = pmg[i]->pmgp->hy; hzed = pmg[i]->pmgp->hzed; xmin = pmg[i]->pmgp->xmin; ymin = pmg[i]->pmgp->ymin; zmin = pmg[i]->pmgp->zmin; if (nlIndU[i] == VNULL) { data = Vmem_malloc(VNULL, nx*ny*nz, sizeof(double)); Vpmg_fillArray(pmg[i], data, VDT_POT, 0.0, pbeparm->pbetype, pbeparm); nlIndU[i] = Vgrid_ctor(nx,ny,nz,hx,hy,hzed,xmin,ymin,zmin,data); nlIndU[i]->readdata = 1; // set readata flag to have dtor free data } else { data = nlIndU[i]->data; Vpmg_fillArray(pmg[i], data, VDT_POT, 0.0, pbeparm->pbetype, pbeparm); } if (i == 0){ sign = -1.0; } else { sign = 1.0; } for (j=0; j < alist[0]->number; j++){ Vpmg_fieldSpline4(pmg[i], j, field); fld[j][0] += sign * field[0]; fld[j][1] += sign * field[1]; fld[j][2] += sign * field[2]; } } /* load results into the return arrays in electron**2/Angstrom /* kT in kcal/mol */ kT = Vunit_kb * (1e-3) * Vunit_Na * 298.15 / 4.184; // electric: conversion from electron**2/Angstrom to Kcal/mol electric = 332.063709; for (i=0; i<alist[0]->number; i++){ fld[i][0] *= kT / electric; fld[i][1] *= kT / electric; fld[i][2] *= kT / electric; } killMG(nosh, pbe, pmgp, pmg); }
int main(int argc, char *argv[]) { std::cout<<"Your Alias: "<< "Ang_Wang"<<std::endl; //READING IN FROM TERMINAL int l; if(argc!=1) l = atoi(argv[1]); else l = 11; //FOR OUTPUT std::ofstream init; init.open("init.dat"); std::ofstream solution; solution.open("solution.dat"); //DEFINITION OF PARAMETERS std::size_t grid_size = pow(2,l)+1; double h = 2.0/((double) (grid_size-1)); std::size_t grid_size_x = grid_size; std::size_t grid_size_y = (grid_size - 1)/2 + 1; //STORING AND PRINTING THE ENTIRE VELOCITY DIST std::vector<std::vector<double > > u(grid_size_y, std::vector<double>(grid_size_x)); init_and_boundary(u); std::vector<std::vector<double > > f(grid_size_y, std::vector<double>(grid_size_x)); for (std::size_t i=0;i<grid_size_y;++i){ for (std::size_t j=0;j<grid_size_x;++j){ init<<std::setw(10)<<(j*h-1)<<" "<<std::setw(10)<<(1-i*h)<<" "<<std::setw(10)<<u[i][j]<<std::endl; } } for (std::size_t i=0; i<grid_size_y-1 ;++i){ for (std::size_t j=0;j<grid_size_x;++j){ init<<std::setw(10)<<(j*h-1)<<" "<<std::setw(10)<<(-1+i*h)<<" "<<std::setw(10)<<u[i][j]<<std::endl; } } init.close(); //TO MEASURE THE WALL CLOCK TIME struct timeval t0, t; gettimeofday(&t0, NULL); solveMG(l, u, f); //MEASURE WALL CLOCK TIME THE PROGRAMME TAKES gettimeofday(&t, NULL); std::cout<<"Wall clock time of MG execution: "<< ((int64_t)(t.tv_sec - t0.tv_sec) * (int64_t) 1000000 + (int64_t)t.tv_usec - (int64_t)t0.tv_usec) * 1e-3 << " ms"<<std::endl; // WRITING THE COMPUTED SOLUTION TO A FILE NAMED SOLUTION.TXT for (std::size_t i=0;i<grid_size_y;++i){ for (std::size_t j=0;j<grid_size_x;++j){ solution<<std::setw(10)<<(j*h-1)<<" "<<std::setw(10)<<(1-i*h)<<" "<<std::setw(10)<<u[i][j]<<std::endl; } } for (std::size_t i=0; i<grid_size_y-1 ;++i){ for (std::size_t j=0;j<grid_size_x;++j){ solution<<std::setw(10)<<(j*h-1)<<" "<<std::setw(10)<<(-1+i*h)<<" "<<std::setw(10)<<u[i][j]<<std::endl; } } solution.close(); }
void apbsempole_(int *natom, double x[maxatm][3], double rad[maxatm], double rpole[maxatm][13], double *total, double energy[maxatm], double fld[maxatm][3], double rff[maxatm][3], double rft[maxatm][3]) { /* Misc. pointers to APBS data structures */ Vpmg *pmg[NOSH_MAXCALC]; Vpmgp *pmgp[NOSH_MAXCALC]; Vpbe *pbe[NOSH_MAXCALC]; MGparm *mgparm = VNULL; PBEparm *pbeparm = VNULL; Vatom *atom = VNULL; /* Vgrid configuration for the kappa and dielectric maps */ double nx,ny,nz,hx,hy,hzed,xmin,ymin,zmin; double *data; double zkappa2, epsp, epsw; /* Loop indeces */ int i,j; /* Observables and unit conversion */ double sign, force[3], torque[3], field[3]; double kT,electric,debye; double charge, dipole[3], quad[9]; debye = 4.8033324; for (i=0; i<NOSH_MAXCALC; i++) { pmg[i] = VNULL; pmgp[i] = VNULL; pbe[i] = VNULL; } /* Kill the saved potential Vgrids */ for (i=0; i<2; i++){ if (permU[i] != VNULL) Vgrid_dtor(&permU[i]); if (indU[i] != VNULL) Vgrid_dtor(&indU[i]); if (nlIndU[i] != VNULL) Vgrid_dtor(&nlIndU[i]); } /* Kill the old atom list */ if (alist[0] != VNULL) { Valist_dtor(&alist[0]); } /* Create a new atom list (mol == 1) */ if (alist[0] == VNULL) { alist[0] = Valist_ctor(); alist[0]->atoms = Vmem_malloc(alist[0]->vmem, *natom, (sizeof(Vatom))); alist[0]->number = *natom; } /* Read TINKER input data into Vatom instances. */ for (i=0; i < alist[0]->number; i++){ atom = Valist_getAtom(alist[0],i); Vatom_setAtomID(atom, i); Vatom_setPosition(atom, x[i]); Vatom_setRadius(atom, rad[i]); charge = rpole[i][0]; Vatom_setCharge(atom, charge); dipole[0] = rpole[i][1]; dipole[1] = rpole[i][2]; dipole[2] = rpole[i][3]; Vatom_setDipole(atom, dipole); quad[0] = rpole[i][4]; quad[1] = rpole[i][5]; quad[2] = rpole[i][6]; quad[3] = rpole[i][7]; quad[4] = rpole[i][8]; quad[5] = rpole[i][9]; quad[6] = rpole[i][10]; quad[7] = rpole[i][11]; quad[8] = rpole[i][12]; Vatom_setQuadrupole(atom, quad); /* Useful check printf(" %i %f (%f,%f,%f)\n",i,rad[i], x[i][0], x[i][1], x[i][2]); printf(" %f\n %f,%f,%f\n", charge, dipole[0], dipole[1], dipole[2]); printf(" %f\n", quad[0]); printf(" %f %f\n", quad[3], quad[4]); printf(" %f %f %f\n", quad[6], quad[7], quad[8]); */ energy[i] = 0.0; for (j=0;j<3;j++){ fld[i][j] = 0.0; rff[i][j] = 0.0; rft[i][j] = 0.0; } } nosh->nmol = 1; Valist_getStatistics(alist[0]); /* Only call the setupCalc routine once, so that we can reuse this nosh object */ if (nosh->ncalc < 2) { if (NOsh_setupElecCalc(nosh, alist) != 1) { printf("Error setting up calculations\n"); exit(-1); } } /* Solve the LPBE for the homogeneous and then solvated states */ for (i=0; i<2; i++) { /* Useful local variables */ mgparm = nosh->calc[i]->mgparm; pbeparm = nosh->calc[i]->pbeparm; /* Just to be robust */ if (!MGparm_check(mgparm)){ printf("MGparm Check failed\n"); printMGPARM(mgparm, realCenter); exit(-1); } if (!PBEparm_check(pbeparm)){ printf("PBEparm Check failed\n"); printPBEPARM(pbeparm); exit(-1); } /* Set up the problem */ mgparm->chgs = VCM_PERMANENT; if (!initMG(i, nosh, mgparm, pbeparm, realCenter, pbe, alist, dielXMap, dielYMap, dielZMap, kappaMap, chargeMap, pmgp, pmg, potMap)) { Vnm_tprint( 2, "Error setting up MG calculation!\n"); return; } /* Solve the PDE */ if (solveMG(nosh, pmg[i], mgparm->type) != 1) { Vnm_tprint(2, "Error solving PDE!\n"); return; } /* Set partition information for observables and I/O */ /* Note - parallel operation has NOT been tested. */ if (setPartMG(nosh, mgparm, pmg[i]) != 1) { Vnm_tprint(2, "Error setting partition info!\n"); return; } nx = pmg[i]->pmgp->nx; ny = pmg[i]->pmgp->ny; nz = pmg[i]->pmgp->nz; hx = pmg[i]->pmgp->hx; hy = pmg[i]->pmgp->hy; hzed = pmg[i]->pmgp->hzed; xmin = pmg[i]->pmgp->xmin; ymin = pmg[i]->pmgp->ymin; zmin = pmg[i]->pmgp->zmin; /* Save dielectric/kappa maps into Vgrids, then change the nosh * data structure to think it read these maps in from a file. * The goal is to save setup time during convergence of the * induced dipoles. This is under consideration... * */ /* // X (shifted) data = Vmem_malloc(mem, nx*ny*nz, sizeof(double)); Vpmg_fillArray(pmg[i], data, VDT_DIELX, 0.0, pbeparm->pbetype); dielXMap[i] = Vgrid_ctor(nx,ny,nz,hx,hy,hzed, xmin + 0.5*hx,ymin,zmin,data); dielXMap[i]->readdata = 1; // Y (shifted) data = Vmem_malloc(mem, nx*ny*nz, sizeof(double)); Vpmg_fillArray(pmg[i], data, VDT_DIELY, 0.0, pbeparm->pbetype); dielYMap[i] = Vgrid_ctor(nx,ny,nz,hx,hy,hzed, xmin,ymin + 0.5*hy,zmin,data); dielYMap[i]->readdata = 1; // Z (shifted) data = Vmem_malloc(mem, nx*ny*nz, sizeof(double)); Vpmg_fillArray(pmg[i], data, VDT_DIELZ, 0.0, pbeparm->pbetype); dielZMap[i] = Vgrid_ctor(nx,ny,nz,hx,hy,hzed, xmin,ymin,zmin + 0.5*hzed,data); dielZMap[i]->readdata = 1; // Kappa data = Vmem_malloc(mem, nx*ny*nz, sizeof(double)); Vpmg_fillArray(pmg[i], data, VDT_KAPPA, 0.0, pbeparm->pbetype); kappaMap[i] = Vgrid_ctor(nx,ny,nz,hx,hy,hzed,xmin,ymin,zmin,data); kappaMap[i]->readdata = 1; // Update the pbeparam structure, since we now have // dielectric and kappap maps pbeparm->useDielMap = 1; pbeparm->dielMapID = i + 1; pbeparm->useKappaMap = 1; pbeparm->kappaMapID = i + 1; */ data = Vmem_malloc(mem, nx*ny*nz, sizeof(double)); Vpmg_fillArray(pmg[i], data, VDT_POT, 0.0, pbeparm->pbetype, pbeparm); permU[i] = Vgrid_ctor(nx,ny,nz,hx,hy,hzed,xmin,ymin,zmin,data); permU[i]->readdata = 1; // set readdata flag to have the dtor to free data if (i == 0){ sign = -1.0; } else { sign = 1.0; } /* Calculate observables */ for (j=0; j < alist[0]->number; j++){ energy[j] += sign * Vpmg_qfPermanentMultipoleEnergy(pmg[i], j); Vpmg_fieldSpline4(pmg[i], j, field); fld[j][0] += sign * field[0]; fld[j][1] += sign * field[1]; fld[j][2] += sign * field[2]; } if (!pmg[i]->pmgp->nonlin && (pmg[i]->surfMeth == VSM_SPLINE || pmg[i]->surfMeth == VSM_SPLINE3 || pmg[i]->surfMeth == VSM_SPLINE4)) { for (j=0; j < alist[0]->number; j++){ Vpmg_qfPermanentMultipoleForce(pmg[i], j, force, torque); rff[j][0] += sign * force[0]; rff[j][1] += sign * force[1]; rff[j][2] += sign * force[2]; rft[j][0] += sign * torque[0]; rft[j][1] += sign * torque[1]; rft[j][2] += sign * torque[2]; } kT = Vunit_kb * (1e-3) * Vunit_Na * 298.15 * 1.0/4.184; epsp = Vpbe_getSoluteDiel(pmg[i]->pbe); epsw = Vpbe_getSolventDiel(pmg[i]->pbe); if (VABS(epsp-epsw) > VPMGSMALL) { for (j=0; j < alist[0]->number; j++){ Vpmg_dbPermanentMultipoleForce(pmg[i], j, force); rff[j][0] += sign * force[0]; rff[j][1] += sign * force[1]; rff[j][2] += sign * force[2]; } } zkappa2 = Vpbe_getZkappa2(pmg[i]->pbe); if (zkappa2 > VPMGSMALL) { for (j=0; j < alist[0]->number; j++) { Vpmg_ibPermanentMultipoleForce(pmg[i], j, force); rff[j][0] += sign * force[0]; rff[j][1] += sign * force[1]; rff[j][2] += sign * force[2]; } } } } //nosh->ndiel = 2; //nosh->nkappa = 2; /* printf("Energy (multipole) %f Kcal/mol\n", *energy); printf("Energy (volume) %f Kcal/mol\n", evol * 0.5 * kT); */ // Convert results into kcal/mol units kT = Vunit_kb * (1e-3) * Vunit_Na * 298.15 * 1.0/4.184; // Electric converts from electron**2/Angstrom to kcal/mol electric = 332.063709; *total = 0.0; for (i=0; i<alist[0]->number; i++){ /* starting with the field in KT/e/Ang^2 multiply by kcal/mol/KT the field is then divided by "electric" to convert to e/Ang^2 */ energy[i] *= 0.5 * kT; *total += energy[i]; fld[i][0] *= kT / electric; fld[i][1] *= kT / electric; fld[i][2] *= kT / electric; rff[i][0] *= kT; rff[i][1] *= kT; rff[i][2] *= kT; rft[i][0] *= kT; rft[i][1] *= kT; rft[i][2] *= kT; } killMG(nosh, pbe, pmgp, pmg); }