• Main Page
  • Related Pages
  • Modules
  • Namespaces
  • Data Structures
  • Files
  • File List
  • Globals

tools/manip/born.c

00001 
00052 #include <unistd.h>
00053 
00054 #include "apbscfg.h"
00055 #include "apbs/vatom.h"
00056 #include "apbs/valist.h"
00057 #include "apbs/vacc.h"
00058 
00067 #define fGB(rij, Ri, Rj) \
00068   (VSQRT(VSQR(rij)+(Ri)*(Rj)*VEXP(-0.25*VSQR(rij)/(Ri)/(Rj))))
00069 
00078 #define dfGB_drij(rij, Ri, Rj) \
00079   (((rij)-0.25*VEXP(-0.25*VSQR(rij)/(Ri)/(Rj)))/fGB(rij,Ri,Rj))
00080 
00089 #define dfGB_dRi(rij, Ri, Rj) \
00090  (0.5*(0.25*VSQR(rij)/(Ri)+(Rj))*VEXP(-0.25*VSQR(rij)/(Ri)/(Rj))/fGB(rij,Ri,Rj))
00091 
00100 #define dfGB_dRj(rij, Ri, Rj) (dfGB_dRi(rij, Rj, Ri))
00101 
00102 
00103 int main(int argc, char **argv) {
00104 
00105     /* OBJECTS */
00106     Valist *alist;
00107     Vatom *atom1, *atom2;
00108     Vio *sock = VNULL;
00109     double charge1, charge2, dist, dist2, *pos1, *pos2, energy, myenergy;
00110     double zmagic, rad1, rad2, eps, disp[3], force[5], myforce[5], dG_drij;
00111     double dG_dRi, dG_dRj;
00112     int i, j;
00113     int verbose = 0;
00114     int doforce = 1;
00115 
00116     /* SYSTEM PARAMETERS */
00117     char *path;
00118 
00119     char *usage = "\n\n\
00120 This program calculates electrostatic properties using a generalized\n\
00121 Born equation.\n\
00122 Usage: born [-v] [-f] <epsilon> <molecule.pqr>\n\n\
00123    where <epsilon> is the unitless solvent dielectric constant and \n\
00124    <molecule.pqr> is the path to the molecule structure in PQR format.\n\
00125    This program supports the following options:\n\
00126        -v      give per-atom information\n\
00127        -f      calculate forces in addition to energies\n\n";
00128 
00129     Vio_start();
00130 
00131     if ((argc > 5) || (argc < 3)) {
00132         printf("\n*** Syntax error: got %d arguments, expected 2.\n",argc);
00133         printf("%s", usage);
00134         exit(666);
00135     };
00136     if (argc > 3) {
00137         for (i=1; i<(argc-2); i++) {
00138             if (strcmp("-v", argv[i]) == 0) {
00139                 printf("Providing per-atom information...\n");
00140                 verbose = 1;
00141             } else if (strcmp("-f", argv[i]) == 0) {
00142                 printf("Calculating forces...\n");
00143                 doforce = 1;
00144             } else {
00145                 printf("Ignoring option %s\n", argv[i]);
00146                 verbose = 0;
00147             }
00148         }
00149         path = argv[argc-1];
00150         sscanf(argv[argc-2], "%lf", &eps);
00151     } else {
00152         verbose = 0;
00153         path = argv[2];
00154         sscanf(argv[1], "%lf", &eps);
00155     }
00156 
00157     printf("Setting up atom list from %s\n", path);
00158     alist = Valist_ctor();
00159     sock = Vio_ctor("FILE", "ASC", VNULL, path, "r");
00160     if (sock == VNULL) {
00161         Vnm_print(2, "Problem opening virtual socket %s!\n", 
00162                   path);
00163         return 0;
00164     }
00165     if (Vio_accept(sock, 0) < 0) {
00166         Vnm_print(2, "Problem accepting virtual socket %s!\n",
00167                   path);
00168         return 0;
00169     }
00170     Valist_readPQR(alist,VNULL,sock);
00171     printf("Read %d atoms\n", Valist_getNumberAtoms(alist));
00172 
00173     /* Energy scaling factor */
00174     zmagic  = (1e-3)*(1e10)*Vunit_ec*Vunit_ec*Vunit_Na/(4*VPI*Vunit_eps0);
00175 
00176     energy = 0.0;
00177     force[0] = force[1] = force[2] = force[3] = force[4] = 0.0;
00178     
00179     printf("Using solvent diel %g, distance in Ang, and charge in e....\n",
00180       eps);
00181     printf("Calculating...\n");
00182     fflush(stdout);
00183     for (i=0; i<Valist_getNumberAtoms(alist); i++) {
00184         atom1 = Valist_getAtom(alist, i);
00185         pos1 = Vatom_getPosition(atom1);
00186         charge1 = Vatom_getCharge(atom1);
00187         rad1 = Vatom_getRadius(atom1);
00188         myenergy = -0.5*VSQR(charge1)/VSQR(rad1);
00189         myforce[0] = myforce[1] = myforce[2] = myforce[3] = myforce[4] = 0.0;
00190         for (j=0; j<Valist_getNumberAtoms(alist); j++) {
00191             if (j != i) {
00192                 atom2 = Valist_getAtom(alist, j);
00193                 pos2 = Vatom_getPosition(atom2);
00194                 rad2 = Vatom_getRadius(atom2);
00195                 charge2 = Vatom_getCharge(atom2);
00196                 disp[0] = pos1[0] - pos2[0];
00197                 disp[1] = pos1[1] - pos2[1];
00198                 disp[2] = pos1[2] - pos2[2];
00199                 dist2 = (VSQR(disp[0]) + VSQR(disp[1]) + VSQR(disp[2]));
00200                 dist = VSQRT(dist2);
00201                 dG_drij = 0.5*charge1*charge2*dfGB_drij(dist,rad1,rad2) / 
00202                   VSQR(fGB(dist, rad1, rad2));
00203                 dG_dRi = 0.5*charge1*charge2*dfGB_dRi(dist,rad1,rad2) / 
00204                   VSQR(fGB(dist, rad1, rad2));
00205                 dG_dRj = 0.5*charge1*charge2*dfGB_dRj(dist,rad1,rad2) / 
00206                   VSQR(fGB(dist, rad1, rad2));
00207                 myforce[0] += -disp[0]*dG_drij/(dist*dist2);
00208                 myforce[1] += -disp[1]*dG_drij/(dist*dist2);
00209                 myforce[2] += -disp[2]*dG_drij/(dist*dist2);
00210                 myforce[3] += dG_dRi;
00211                 myforce[4] += dG_dRj;
00212                 myenergy -= 0.5*(charge1*charge2/fGB(dist, rad1, rad2));
00213             }
00214         }
00215         myenergy = myenergy*(1-1/eps);
00216         myforce[0] = myforce[0]*(1-1/eps);
00217         myforce[1] = myforce[1]*(1-1/eps);
00218         myforce[2] = myforce[2]*(1-1/eps);
00219         myforce[3] = myforce[3]*(1-1/eps);
00220         myforce[4] = myforce[4]*(1-1/eps);
00221         energy += myenergy;
00222         force[0] += myforce[0];
00223         force[1] += myforce[1];
00224         force[2] += myforce[2];
00225         force[3] += myforce[3];
00226         force[4] += myforce[4];
00227         myenergy = myenergy*zmagic;
00228         myforce[0] = myforce[0]*zmagic;
00229         myforce[1] = myforce[1]*zmagic;
00230         myforce[2] = myforce[2]*zmagic;
00231         myforce[3] = myforce[3]*zmagic;
00232         myforce[4] = myforce[4]*zmagic;
00233         if (verbose) {
00234             printf("\tAtom %d:  Energy  = %1.12E kJ/mol\n", i, myenergy);
00235             if (doforce) {
00236                 printf("\tAtom %d:  x-force = %1.12E kJ/mol/A\n", i, 
00237                   myforce[0]);
00238                 printf("\tAtom %d:  y-force = %1.12E kJ/mol/A\n", i, 
00239                   myforce[1]);
00240                 printf("\tAtom %d:  z-force = %1.12E kJ/mol/A\n", i, 
00241                   myforce[2]);
00242                 printf("\tAtom %d:  Ri-force = %1.12E kJ/mol/A\n", i, 
00243                   myforce[3]);
00244                 printf("\tAtom %d:  Rj-force = %1.12E kJ/mol/A\n", i, 
00245                   myforce[4]);
00246             }
00247         }
00248     }
00249 
00250     energy = energy*zmagic;
00251  
00252     printf("\n\n-------------------------------------------------------\n");
00253     printf("GB solvation energy = %1.12e kJ/mol.\n", energy);
00254     printf("GB solvation x-force = %1.12e kJ/mol.\n", force[0]);
00255     printf("GB solvation y-force = %1.12e kJ/mol.\n", force[1]);
00256     printf("GB solvation z-force = %1.12e kJ/mol.\n", force[2]);
00257     printf("GB solvation Ri-force = %1.12e kJ/mol.\n", force[3]);
00258     printf("GB solvation Rj-force = %1.12e kJ/mol.\n", force[4]);
00259 
00260     return 0;
00261 }

Generated on Wed Oct 20 2010 11:12:19 for APBS by  doxygen 1.7.2