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

bin/routines.c

Go to the documentation of this file.
00001 
00052 #include "apbscfg.h"
00053 #include "maloc/maloc.h"  
00054 #ifdef HAVE_MC_H
00055 #include "mc/mc.h"  
00056 #include "apbs/vfetk.h"
00057 #endif
00058 #ifdef HAVE_MCX_H
00059 #  include "mcx/mcx.h"  
00060 #endif
00061 
00062 #include "apbs/apbs.h"  
00063 #include "apbs/vhal.h"  
00064 #include "apbs/nosh.h"  
00065 #include "apbs/vgrid.h"  
00066 #include "apbs/mgparm.h"  
00067 #include "apbs/pbeparm.h"  
00068 #include "apbs/femparm.h"  
00069 
00070 
00071 #include "routines.h"
00072 
00073 VEMBED(rcsid="$Id: routines.c 1606 2010-09-14 20:52:31Z yhuang01 $")
00074 
00075 VPUBLIC void startVio() { Vio_start(); }
00076 
00077 VPUBLIC Vparam* loadParameter(NOsh *nosh) {
00078            
00079            Vparam *param = VNULL;
00080            
00081            if (nosh->gotparm) {
00082                       param = Vparam_ctor();
00083                       switch (nosh->parmfmt) {
00084                                  case NPF_FLAT:
00085                                             Vnm_tprint( 1, "Reading parameter data from %s.\n",
00086                                                                              nosh->parmpath);
00087                                             if (Vparam_readFlatFile(param, "FILE", "ASC", VNULL, 
00088                                                                                                               nosh->parmpath) != 1) {
00089                                                        Vnm_tprint(2, "Error reading parameter file (%s)!\n", nosh->parmpath);
00090                                                        return VNULL;
00091                                             }
00092                                                        break;
00093                                  case NPF_XML:
00094                                             Vnm_tprint( 1, "Reading parameter data from %s.\n",
00095                                                                              nosh->parmpath);
00096                                             if (Vparam_readXMLFile(param, "FILE", "ASC", VNULL, 
00097                                                                                                       nosh->parmpath) != 1) {
00098                                                        Vnm_tprint(2, "Error reading parameter file (%s)!\n", nosh->parmpath);
00099                                                        return VNULL;
00100                                             }
00101                                                        break;
00102                                  default:
00103                                             Vnm_tprint(2, "Error! Undefined parameter file type (%d)!\n", nosh->parmfmt);
00104                                             return VNULL;
00105                       } /* switch parmfmt */
00106            }
00107 
00108            return param;
00109 }
00110 
00111 
00112 VPUBLIC int loadMolecules(NOsh *nosh, Vparam *param, Valist *alist[NOSH_MAXMOL]) {
00113            
00114            int i;
00115            int use_params = 0;
00116            Vrc_Codes rc;
00117            
00118            Vio *sock = VNULL;
00119            
00120            Vnm_tprint( 1, "Got paths for %d molecules\n", nosh->nmol);
00121            if (nosh->nmol <= 0) {
00122                       Vnm_tprint(2, "You didn't specify any molecules (correctly)!\n");
00123                       Vnm_tprint(2, "Bailing out!\n");
00124                       return 0;
00125            }
00126            
00127            if (nosh->gotparm) {
00128                       if (param == VNULL) {
00129                                  Vnm_tprint(2, "Error!  You don't have a valid parameter object!\n");
00130                                  return 0;
00131                       }
00132                       use_params = 1;
00133            }
00134 
00135            for (i=0; i<nosh->nmol; i++) {
00136                       if(alist[i] == VNULL){
00137                                  alist[i] = Valist_ctor();
00138                       }else{
00139                                  alist[i] = VNULL;
00140                                  alist[i] = Valist_ctor();
00141                       }
00142                       
00143                       switch (nosh->molfmt[i]) {
00144                                  case NMF_PQR:
00145                                                        /* Print out a warning to the user letting them know that we are overriding PQR
00146                                                        values for charge, radius and epsilon */
00147                                                        if (use_params) {
00148                                                                   Vnm_print(2, "\nWARNING!!  Radius/charge information from PQR file %s\n", nosh->molpath[i]);
00149                                                                   Vnm_print(2, "will be replaced with data from parameter file (%s)!\n", nosh->parmpath);
00150                                                        }
00151                                                        Vnm_tprint( 1, "Reading PQR-format atom data from %s.\n",
00152                                                                              nosh->molpath[i]);
00153                                                        sock = Vio_ctor("FILE", "ASC", VNULL, nosh->molpath[i], "r");
00154                                                        if (sock == VNULL) {
00155                                                                   Vnm_print(2, "Problem opening virtual socket %s!\n", 
00156                                                                                nosh->molpath[i]);
00157                                                                   return 0;
00158                                                        }
00159                                                        if (Vio_accept(sock, 0) < 0) {
00160                                                                   Vnm_print(2, "Problem accepting virtual socket %s!\n",
00161                                                                                           nosh->molpath[i]);
00162                                                                   return 0;
00163                                                        }
00164                                                        if(use_params){
00165                                                                   rc = Valist_readPQR(alist[i], param, sock);
00166                                                        }else{
00167                                                                   rc = Valist_readPQR(alist[i], VNULL, sock);
00168                                                        }
00169                                                        if(rc == 0) return 0;
00170                                                        
00171                                                        Vio_acceptFree(sock);
00172                                                        Vio_dtor(&sock);
00173                                                        break;
00174                                  case NMF_PDB:
00175                                                        /* Load parameters */
00176                                                        if (!nosh->gotparm) {
00177                                                                   Vnm_tprint(2, "NOsh:  Error!  Can't read PDB without specifying PARM file!\n");
00178                                                                   return 0;
00179                                                        }
00180                                                        Vnm_tprint( 1, "Reading PDB-format atom data from %s.\n",
00181                                                                              nosh->molpath[i]);
00182                                                        sock = Vio_ctor("FILE", "ASC", VNULL, nosh->molpath[i], "r");
00183                                                        if (sock == VNULL) {
00184                                                                   Vnm_print(2, "Problem opening virtual socket %s!\n", 
00185                                                                                nosh->molpath[i]);
00186                                                                   return 0;
00187                                                        }
00188                                                        if (Vio_accept(sock, 0) < 0) {
00189                                                                   Vnm_print(2, "Problem accepting virtual socket %s!\n", nosh->molpath[i]);
00190                                                                   return 0;
00191                                                        }
00192                                                        rc = Valist_readPDB(alist[i], param, sock);
00193                                                        /* If we are looking for an atom/residue that does not exist
00194                                                         * then abort and return 0 */
00195                                                        if(rc == 0) return 0;
00196                                                        
00197                                                        Vio_acceptFree(sock);
00198                                                        Vio_dtor(&sock);
00199                                                        break;
00200                                  case NMF_XML:
00201                                             Vnm_tprint( 1, "Reading XML-format atom data from %s.\n",
00202                                                                              nosh->molpath[i]);
00203                                             sock = Vio_ctor("FILE", "ASC", VNULL, nosh->molpath[i], "r");
00204                                             if (sock == VNULL) {
00205                                                        Vnm_print(2, "Problem opening virtual socket %s!\n", 
00206                                                                                nosh->molpath[i]);
00207                                                        return 0;
00208                                             }
00209                                                        if (Vio_accept(sock, 0) < 0) {
00210                                                                   Vnm_print(2, "Problem accepting virtual socket %s!\n",
00211                                                                                           nosh->molpath[i]);
00212                                                                   return 0;
00213                                                        }
00214                                                        if(use_params){
00215                                                                   rc = Valist_readXML(alist[i], param, sock);
00216                                                        }else{
00217                                                                   rc = Valist_readXML(alist[i], VNULL, sock);
00218                                                        }
00219                                                        if(rc == 0) return 0;
00220                                                        
00221                                             Vio_acceptFree(sock);
00222                                             Vio_dtor(&sock);
00223                                             break;
00224                                  default:
00225                                             Vnm_tprint(2, "NOsh:  Error!  Undefined molecule file type \
00226 (%d)!\n", nosh->molfmt[i]);
00227                                             return 0;
00228                       } /* switch molfmt */
00229 
00230                       if (rc != 1) {
00231                                  Vnm_tprint( 2, "Error while reading molecule from %s\n",
00232                                                                   nosh->molpath[i]);
00233                                  return 0;
00234                       }
00235 
00236                       Vnm_tprint( 1, "  %d atoms\n", Valist_getNumberAtoms(alist[i]));
00237                       Vnm_tprint( 1, "  Centered at (%4.3e, %4.3e, %4.3e)\n",
00238                                                        alist[i]->center[0], alist[i]->center[1], 
00239                                                        alist[i]->center[2]);
00240                       Vnm_tprint( 1, "  Net charge %3.2e e\n", alist[i]->charge);        
00241 
00242            }
00243 
00244            return 1;
00245 
00246 }
00247 
00248 VPUBLIC void killMolecules(NOsh *nosh, Valist *alist[NOSH_MAXMOL]) {
00249            
00250            int i;
00251            
00252 #ifndef VAPBSQUIET
00253            Vnm_tprint( 1, "Destroying %d molecules\n", nosh->nmol);
00254 #endif
00255            
00256            for (i=0; i<nosh->nmol; i++) Valist_dtor(&(alist[i]));
00257            
00258 }
00259 
00260 VPUBLIC int loadDielMaps(NOsh *nosh, 
00261                                                                    Vgrid *dielXMap[NOSH_MAXMOL], 
00262                                                                    Vgrid *dielYMap[NOSH_MAXMOL],
00263                                                                    Vgrid *dielZMap[NOSH_MAXMOL]) {
00264            
00265            int i, ii, nx, ny, nz;
00266            double sum, hx, hy, hzed, xmin, ymin, zmin;
00267            
00268            if (nosh->ndiel > 0) 
00269                       Vnm_tprint( 1, "Got paths for %d dielectric map sets\n", 
00270                                                        nosh->ndiel);
00271            else return 1;
00272            
00273            for (i=0; i<nosh->ndiel; i++) {
00274                       Vnm_tprint( 1, "Reading x-shifted dielectric map data from \
00275 %s:\n", nosh->dielXpath[i]);
00276                       dielXMap[i] = Vgrid_ctor(0, 0, 0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, VNULL);
00277                       switch (nosh->dielfmt[i]) {
00278                                  case VDF_DX:
00279                                             if (Vgrid_readDX(dielXMap[i], "FILE", "ASC", VNULL, 
00280                                                                                          nosh->dielXpath[i]) != 1) {
00281                                                        Vnm_tprint( 2, "Fatal error while reading from %s\n",
00282                                                                                         nosh->dielXpath[i]);
00283                                                        return 0;
00284                                             }
00285                                             nx = dielXMap[i]->nx;
00286                                             ny = dielXMap[i]->ny;
00287                                             nz = dielXMap[i]->nz;
00288                                             hx = dielXMap[i]->hx;
00289                                             hy = dielXMap[i]->hy;
00290                                             hzed = dielXMap[i]->hzed;
00291                                             xmin = dielXMap[i]->xmin;
00292                                             ymin = dielXMap[i]->ymin;
00293                                             zmin = dielXMap[i]->zmin;
00294                                             Vnm_tprint(1, "  %d x %d x %d grid\n", nx, ny, nz);
00295                                             Vnm_tprint(1, "  (%g, %g, %g) A spacings\n", hx, hy, hzed);
00296                                             Vnm_tprint(1, "  (%g, %g, %g) A lower corner\n", 
00297                                                                      xmin, ymin, zmin);
00298                                             sum = 0;
00299                                             for (ii=0; ii<(nx*ny*nz); ii++)
00300                                                        sum += (dielXMap[i]->data[ii]);
00301                                                        sum = sum*hx*hy*hzed;
00302                                             Vnm_tprint(1, "  Volume integral = %3.2e A^3\n", sum);
00303                                             break;
00304                                  case VDF_GZ:
00305                                             if (Vgrid_readGZ(dielXMap[i], nosh->dielXpath[i]) != 1) {
00306                                                        Vnm_tprint( 2, "Fatal error while reading from %s\n",
00307                                                                                 nosh->dielXpath[i]);
00308                                                        return 0;
00309                                             }
00310                                             nx = dielXMap[i]->nx;
00311                                             ny = dielXMap[i]->ny;
00312                                             nz = dielXMap[i]->nz;
00313                                             hx = dielXMap[i]->hx;
00314                                             hy = dielXMap[i]->hy;
00315                                             hzed = dielXMap[i]->hzed;
00316                                             xmin = dielXMap[i]->xmin;
00317                                             ymin = dielXMap[i]->ymin;
00318                                             zmin = dielXMap[i]->zmin;
00319                                             Vnm_tprint(1, "  %d x %d x %d grid\n", nx, ny, nz);
00320                                             Vnm_tprint(1, "  (%g, %g, %g) A spacings\n", hx, hy, hzed);
00321                                             Vnm_tprint(1, "  (%g, %g, %g) A lower corner\n", 
00322                                                                      xmin, ymin, zmin);
00323                                             sum = 0;
00324                                             for (ii=0; ii<(nx*ny*nz); ii++)
00325                                                        sum += (dielXMap[i]->data[ii]);
00326                                             sum = sum*hx*hy*hzed;
00327                                             Vnm_tprint(1, "  Volume integral = %3.2e A^3\n", sum);
00328                                             break;
00329                                  case VDF_UHBD:
00330                                             Vnm_tprint( 2, "UHBD input not supported yet!\n");
00331                                             return 0;
00332                                  case VDF_AVS:
00333                                             Vnm_tprint( 2, "AVS input not supported yet!\n");
00334                                             return 0;
00335                                  case VDF_MCSF:
00336                                             Vnm_tprint( 2, "MCSF input not supported yet!\n");
00337                                             return 0;
00338                                  default:
00339                                             Vnm_tprint( 2, "Invalid data format (%d)!\n", 
00340                                                                              nosh->dielfmt[i]);
00341                                             return 0;
00342                       }
00343                       Vnm_tprint( 1, "Reading y-shifted dielectric map data from \
00344 %s:\n", nosh->dielYpath[i]);
00345                       dielYMap[i] = Vgrid_ctor(0, 0, 0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, VNULL);
00346                       switch (nosh->dielfmt[i]) {
00347                                  case VDF_DX:
00348                                             if (Vgrid_readDX(dielYMap[i], "FILE", "ASC", VNULL, 
00349                                                                                          nosh->dielYpath[i]) != 1) {
00350                                                        Vnm_tprint( 2, "Fatal error while reading from %s\n",
00351                                                                                         nosh->dielYpath[i]);
00352                                                        return 0;
00353                                             }
00354                                             nx = dielYMap[i]->nx;
00355                                             ny = dielYMap[i]->ny;
00356                                             nz = dielYMap[i]->nz;
00357                                             hx = dielYMap[i]->hx;
00358                                             hy = dielYMap[i]->hy;
00359                                             hzed = dielYMap[i]->hzed;
00360                                             xmin = dielYMap[i]->xmin;
00361                                             ymin = dielYMap[i]->ymin;
00362                                             zmin = dielYMap[i]->zmin;
00363                                             Vnm_tprint(1, "  %d x %d x %d grid\n", nx, ny, nz);
00364                                             Vnm_tprint(1, "  (%g, %g, %g) A spacings\n", hx, hy, hzed);
00365                                             Vnm_tprint(1, "  (%g, %g, %g) A lower corner\n",
00366                                                                      xmin, ymin, zmin);
00367                                             sum = 0;
00368                                             for (ii=0; ii<(nx*ny*nz); ii++)
00369                                                        sum += (dielYMap[i]->data[ii]);
00370                                                        sum = sum*hx*hy*hzed;
00371                                             Vnm_tprint(1, "  Volume integral = %3.2e A^3\n", sum);
00372                                             break;
00373                                  case VDF_GZ:
00374                                             if (Vgrid_readGZ(dielYMap[i], nosh->dielYpath[i]) != 1) {
00375                                                        Vnm_tprint( 2, "Fatal error while reading from %s\n",
00376                                                                                 nosh->dielYpath[i]);
00377                                                        return 0;
00378                                             }
00379                                             nx = dielYMap[i]->nx;
00380                                             ny = dielYMap[i]->ny;
00381                                             nz = dielYMap[i]->nz;
00382                                             hx = dielYMap[i]->hx;
00383                                             hy = dielYMap[i]->hy;
00384                                             hzed = dielYMap[i]->hzed;
00385                                             xmin = dielYMap[i]->xmin;
00386                                             ymin = dielYMap[i]->ymin;
00387                                             zmin = dielYMap[i]->zmin;
00388                                             Vnm_tprint(1, "  %d x %d x %d grid\n", nx, ny, nz);
00389                                             Vnm_tprint(1, "  (%g, %g, %g) A spacings\n", hx, hy, hzed);
00390                                             Vnm_tprint(1, "  (%g, %g, %g) A lower corner\n",
00391                                                                      xmin, ymin, zmin);
00392                                             sum = 0;
00393                                             for (ii=0; ii<(nx*ny*nz); ii++)
00394                                                        sum += (dielYMap[i]->data[ii]);
00395                                             sum = sum*hx*hy*hzed;
00396                                             Vnm_tprint(1, "  Volume integral = %3.2e A^3\n", sum);
00397                                             break;
00398                                  case VDF_UHBD:
00399                                             Vnm_tprint( 2, "UHBD input not supported yet!\n");
00400                                             return 0;
00401                                  case VDF_AVS:
00402                                             Vnm_tprint( 2, "AVS input not supported yet!\n");
00403                                             return 0;
00404                                  case VDF_MCSF:
00405                                             Vnm_tprint( 2, "MCSF input not supported yet!\n");
00406                                             return 0;
00407                                  default:
00408                                             Vnm_tprint( 2, "Invalid data format (%d)!\n", 
00409                                                                              nosh->dielfmt[i]);
00410                                             return 0;
00411                       }
00412                       Vnm_tprint( 1, "Reading z-shifted dielectric map data from \
00413 %s:\n", nosh->dielZpath[i]);
00414                       dielZMap[i] = Vgrid_ctor(0, 0, 0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, VNULL);
00415                       switch (nosh->dielfmt[i]) {
00416                                  case VDF_DX:
00417                                             if (Vgrid_readDX(dielZMap[i], "FILE", "ASC", VNULL, 
00418                                                                                          nosh->dielZpath[i]) != 1) {
00419                                                        Vnm_tprint( 2, "Fatal error while reading from %s\n",
00420                                                                                         nosh->dielZpath[i]);
00421                                                        return 0;
00422                                             }
00423                                             nx = dielZMap[i]->nx;
00424                                             ny = dielZMap[i]->ny;
00425                                             nz = dielZMap[i]->nz;
00426                                             hx = dielZMap[i]->hx;
00427                                             hy = dielZMap[i]->hy;
00428                                             hzed = dielZMap[i]->hzed;
00429                                             xmin = dielZMap[i]->xmin;
00430                                             ymin = dielZMap[i]->ymin;
00431                                             zmin = dielZMap[i]->zmin;
00432                                             Vnm_tprint(1, "  %d x %d x %d grid\n",
00433                                                                      nx, ny, nz);
00434                                             Vnm_tprint(1, "  (%g, %g, %g) A spacings\n",
00435                                                                      hx, hy, hzed);
00436                                             Vnm_tprint(1, "  (%g, %g, %g) A lower corner\n",
00437                                                                      xmin, ymin, zmin);
00438                                             sum = 0;
00439                                             for (ii=0; ii<(nx*ny*nz); ii++) sum += (dielZMap[i]->data[ii]);
00440                                                        sum = sum*hx*hy*hzed;
00441                                             Vnm_tprint(1, "  Volume integral = %3.2e A^3\n", sum);
00442                                             break;
00443                                  case VDF_GZ:
00444                                             if (Vgrid_readGZ(dielZMap[i], nosh->dielZpath[i]) != 1) {
00445                                                        Vnm_tprint( 2, "Fatal error while reading from %s\n",
00446                                                                                 nosh->dielZpath[i]);
00447                                                        return 0;
00448                                             }
00449                                             nx = dielZMap[i]->nx;
00450                                             ny = dielZMap[i]->ny;
00451                                             nz = dielZMap[i]->nz;
00452                                             hx = dielZMap[i]->hx;
00453                                             hy = dielZMap[i]->hy;
00454                                             hzed = dielZMap[i]->hzed;
00455                                             xmin = dielZMap[i]->xmin;
00456                                             ymin = dielZMap[i]->ymin;
00457                                             zmin = dielZMap[i]->zmin;
00458                                             Vnm_tprint(1, "  %d x %d x %d grid\n",
00459                                                                      nx, ny, nz);
00460                                             Vnm_tprint(1, "  (%g, %g, %g) A spacings\n",
00461                                                                      hx, hy, hzed);
00462                                             Vnm_tprint(1, "  (%g, %g, %g) A lower corner\n",
00463                                                                      xmin, ymin, zmin);
00464                                             sum = 0;
00465                                             for (ii=0; ii<(nx*ny*nz); ii++) sum += (dielZMap[i]->data[ii]);
00466                                             sum = sum*hx*hy*hzed;
00467                                             Vnm_tprint(1, "  Volume integral = %3.2e A^3\n", sum);
00468                                             break;
00469                                  case VDF_UHBD:
00470                                             Vnm_tprint( 2, "UHBD input not supported yet!\n");
00471                                             return 0;
00472                                  case VDF_AVS:
00473                                             Vnm_tprint( 2, "AVS input not supported yet!\n");
00474                                             return 0;
00475                                  case VDF_MCSF:
00476                                             Vnm_tprint( 2, "MCSF input not supported yet!\n");
00477                                             return 0;
00478                                  default:
00479                                             Vnm_tprint( 2, "Invalid data format (%d)!\n", 
00480                                                                              nosh->dielfmt[i]);
00481                                             return 0;
00482                       }
00483            }
00484            
00485            return 1;
00486            
00487 }
00488 
00489 VPUBLIC void killDielMaps(NOsh *nosh, 
00490                                                                     Vgrid *dielXMap[NOSH_MAXMOL], 
00491                                                                     Vgrid *dielYMap[NOSH_MAXMOL],
00492                                                                     Vgrid *dielZMap[NOSH_MAXMOL]) {
00493            
00494            int i;
00495            
00496            if (nosh->ndiel > 0) {
00497 #ifndef VAPBSQUIET
00498                       Vnm_tprint( 1, "Destroying %d dielectric map sets\n", 
00499                                                        nosh->ndiel);
00500 #endif
00501                       for (i=0; i<nosh->ndiel; i++) {
00502                                  Vgrid_dtor(&(dielXMap[i]));
00503                                  Vgrid_dtor(&(dielYMap[i]));
00504                                  Vgrid_dtor(&(dielZMap[i]));
00505                       }
00506            }
00507            else return;
00508            
00509 }
00510 
00511 VPUBLIC int loadKappaMaps(NOsh *nosh, Vgrid *map[NOSH_MAXMOL]) {
00512            
00513            int i, ii;
00514            double sum;
00515            
00516            if (nosh->nkappa > 0) 
00517                       Vnm_tprint( 1, "Got paths for %d kappa maps\n", nosh->nkappa);
00518            else return 1;
00519            
00520            for (i=0; i<nosh->nkappa; i++) {
00521                       Vnm_tprint( 1, "Reading kappa map data from %s:\n",
00522                                                        nosh->kappapath[i]);
00523                       map[i] = Vgrid_ctor(0, 0, 0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, VNULL);
00524                       switch (nosh->kappafmt[i]) {
00525                                  case VDF_DX:
00526                                             if (Vgrid_readDX(map[i], "FILE", "ASC", VNULL, 
00527                                                                                          nosh->kappapath[i]) != 1) {
00528                                                        Vnm_tprint( 2, "Fatal error while reading from %s\n",
00529                                                                                         nosh->kappapath[i]);
00530                                                        return 0;
00531                                             }
00532                                             Vnm_tprint(1, "  %d x %d x %d grid\n", 
00533                                                                      map[i]->nx, map[i]->ny, map[i]->nz);
00534                                             Vnm_tprint(1, "  (%g, %g, %g) A spacings\n", 
00535                                                                      map[i]->hx, map[i]->hy, map[i]->hzed);
00536                                             Vnm_tprint(1, "  (%g, %g, %g) A lower corner\n", 
00537                                                                      map[i]->xmin, map[i]->ymin, map[i]->zmin);
00538                                             sum = 0;
00539                                             for (ii=0; ii<(map[i]->nx*map[i]->ny*map[i]->nz); ii++)
00540                                                        sum += (map[i]->data[ii]);
00541                                                        sum = sum*map[i]->hx*map[i]->hy*map[i]->hzed;
00542                                             Vnm_tprint(1, "  Volume integral = %3.2e A^3\n", sum);
00543                                             break;
00544                                  case VDF_UHBD:
00545                                             Vnm_tprint( 2, "UHBD input not supported yet!\n");
00546                                             return 0;
00547                                  case VDF_MCSF:
00548                                             Vnm_tprint( 2, "MCSF input not supported yet!\n");
00549                                             return 0;
00550                                  case VDF_AVS:
00551                                             Vnm_tprint( 2, "AVS input not supported yet!\n");
00552                                             return 0;
00553                                  default:
00554                                             Vnm_tprint( 2, "Invalid data format (%d)!\n", 
00555                                                                              nosh->kappafmt[i]);
00556                                             return 0;
00557                       }
00558            }
00559            
00560            return 1;
00561            
00562 }
00563 
00564 VPUBLIC void killKappaMaps(NOsh *nosh, Vgrid *map[NOSH_MAXMOL]) {
00565            
00566            int i;
00567            
00568            if (nosh->nkappa > 0) {
00569 #ifndef VAPBSQUIET
00570                       Vnm_tprint( 1, "Destroying %d kappa maps\n", nosh->nkappa);
00571 #endif
00572                       for (i=0; i<nosh->nkappa; i++) Vgrid_dtor(&(map[i]));
00573            }
00574            else return;
00575            
00576 }
00577 
00578 VPUBLIC int loadPotMaps(NOsh *nosh, Vgrid *map[NOSH_MAXMOL]) {
00579            
00580            int i, ii;
00581            double sum;
00582            
00583            if (nosh->npot > 0) 
00584                       Vnm_tprint( 1, "Got paths for %d potential maps\n", nosh->npot);
00585            else return 1;
00586            
00587            for (i=0; i<nosh->npot; i++) {
00588                       Vnm_tprint( 1, "Reading potential map data from %s:\n",
00589                                                nosh->potpath[i]);
00590                       map[i] = Vgrid_ctor(0, 0, 0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, VNULL);
00591                       switch (nosh->potfmt[i]) {
00592                                  case VDF_DX:
00593                                  case VDF_GZ:
00594                                             if (nosh->potfmt[i] == VDF_DX) {
00595                                                        if (Vgrid_readDX(map[i], "FILE", "ASC", VNULL, 
00596                                                                                                     nosh->potpath[i]) != 1) {
00597                                                                   Vnm_tprint( 2, "Fatal error while reading from %s\n",
00598                                                                                            nosh->potpath[i]);
00599                                                                   return 0;
00600                                                        }
00601                                             }else {
00602                                                        if (Vgrid_readGZ(map[i], nosh->potpath[i]) != 1) {
00603                                                                   Vnm_tprint( 2, "Fatal error while reading from %s\n",
00604                                                                                            nosh->potpath[i]);
00605                                                                   return 0;
00606                                                        }
00607                                             }
00608                                             Vnm_tprint(1, "  %d x %d x %d grid\n", 
00609                                                                      map[i]->nx, map[i]->ny, map[i]->nz);
00610                                             Vnm_tprint(1, "  (%g, %g, %g) A spacings\n", 
00611                                                                      map[i]->hx, map[i]->hy, map[i]->hzed);
00612                                             Vnm_tprint(1, "  (%g, %g, %g) A lower corner\n", 
00613                                                                      map[i]->xmin, map[i]->ymin, map[i]->zmin);
00614                                             sum = 0;
00615                                             for (ii=0; ii<(map[i]->nx*map[i]->ny*map[i]->nz); ii++)
00616                                                        sum += (map[i]->data[ii]);
00617                                             sum = sum*map[i]->hx*map[i]->hy*map[i]->hzed;
00618                                             Vnm_tprint(1, "  Volume integral = %3.2e A^3\n", sum);
00619                                             break;
00620                                  case VDF_UHBD:
00621                                             Vnm_tprint( 2, "UHBD input not supported yet!\n");
00622                                             return 0;
00623                                  case VDF_MCSF:
00624                                             Vnm_tprint( 2, "MCSF input not supported yet!\n");
00625                                             return 0;
00626                                  case VDF_AVS:
00627                                             Vnm_tprint( 2, "AVS input not supported yet!\n");
00628                                             return 0;
00629                                  default:
00630                                             Vnm_tprint( 2, "Invalid data format (%d)!\n", 
00631                                                                      nosh->potfmt[i]);
00632                                             return 0;
00633                       }
00634            }
00635            
00636            return 1;
00637            
00638 }
00639 
00640 VPUBLIC void killPotMaps(NOsh *nosh, Vgrid *map[NOSH_MAXMOL]) {
00641            
00642            int i;
00643            
00644            if (nosh->npot > 0) {
00645 #ifndef VAPBSQUIET
00646                       Vnm_tprint( 1, "Destroying %d potential maps\n", nosh->npot);
00647 #endif
00648                       for (i=0; i<nosh->npot; i++) Vgrid_dtor(&(map[i]));
00649            }
00650            else return;
00651            
00652 }
00653 
00654 VPUBLIC int loadChargeMaps(NOsh *nosh, Vgrid *map[NOSH_MAXMOL]) {
00655            
00656            int i, ii;
00657            double sum;
00658            
00659            if (nosh->ncharge > 0)
00660                       Vnm_tprint( 1, "Got paths for %d charge maps\n", nosh->ncharge);
00661            else return 1;
00662            
00663            for (i=0; i<nosh->ncharge; i++) {
00664                       Vnm_tprint( 1, "Reading charge map data from %s:\n",
00665                                                        nosh->chargepath[i]);
00666                       map[i] = Vgrid_ctor(0, 0, 0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, VNULL);
00667                       switch (nosh->chargefmt[i]) {
00668                                  case VDF_DX:
00669                                             if (Vgrid_readDX(map[i], "FILE", "ASC", VNULL, 
00670                                                                                          nosh->chargepath[i]) != 1) {
00671                                                        Vnm_tprint( 2, "Fatal error while reading from %s\n",
00672                                                                                         nosh->chargepath[i]);
00673                                                        return 0;
00674                                             }
00675                                             Vnm_tprint(1, "  %d x %d x %d grid\n", 
00676                                                                      map[i]->nx, map[i]->ny, map[i]->nz);
00677                                             Vnm_tprint(1, "  (%g, %g, %g) A spacings\n", 
00678                                                                      map[i]->hx, map[i]->hy, map[i]->hzed);
00679                                             Vnm_tprint(1, "  (%g, %g, %g) A lower corner\n", 
00680                                                                      map[i]->xmin, map[i]->ymin, map[i]->zmin);
00681                                             sum = 0;
00682                                             for (ii=0; ii<(map[i]->nx*map[i]->ny*map[i]->nz); ii++) 
00683                                                        sum += (map[i]->data[ii]);
00684                                                        sum = sum*map[i]->hx*map[i]->hy*map[i]->hzed;
00685                                             Vnm_tprint(1, "  Charge map integral = %3.2e e\n", sum);
00686                                             break;
00687                                  case VDF_UHBD:
00688                                             Vnm_tprint( 2, "UHBD input not supported yet!\n");
00689                                             return 0;
00690                                  case VDF_AVS:
00691                                             Vnm_tprint( 2, "AVS input not supported yet!\n");
00692                                             return 0;
00693                                  case VDF_MCSF:
00694                                             Vnm_tprint(2, "MCSF input not supported yet!\n");
00695                                             return 0;
00696                                  case VDF_GZ:
00697                                             if (Vgrid_readGZ(map[i], nosh->chargepath[i]) != 1) {
00698                                                        Vnm_tprint( 2, "Fatal error while reading from %s\n",
00699                                                                                 nosh->chargepath[i]);
00700                                                        return 0;
00701                                             }
00702                                             Vnm_tprint(1, "  %d x %d x %d grid\n", 
00703                                                                      map[i]->nx, map[i]->ny, map[i]->nz);
00704                                             Vnm_tprint(1, "  (%g, %g, %g) A spacings\n", 
00705                                                                      map[i]->hx, map[i]->hy, map[i]->hzed);
00706                                             Vnm_tprint(1, "  (%g, %g, %g) A lower corner\n", 
00707                                                                      map[i]->xmin, map[i]->ymin, map[i]->zmin);
00708                                             sum = 0;
00709                                             for (ii=0; ii<(map[i]->nx*map[i]->ny*map[i]->nz); ii++) 
00710                                                        sum += (map[i]->data[ii]);
00711                                             sum = sum*map[i]->hx*map[i]->hy*map[i]->hzed;
00712                                             Vnm_tprint(1, "  Charge map integral = %3.2e e\n", sum);
00713                                             break;
00714                                  default:
00715                                             Vnm_tprint( 2, "Invalid data format (%d)!\n", 
00716                                                                              nosh->kappafmt[i]);
00717                                             return 0;
00718                       }
00719            }
00720            
00721            return 1;
00722            
00723 }
00724 
00725 VPUBLIC void killChargeMaps(NOsh *nosh, Vgrid *map[NOSH_MAXMOL]) {
00726            
00727            int i;
00728            
00729            if (nosh->ncharge > 0) {
00730 #ifndef VAPBSQUIET
00731                       Vnm_tprint( 1, "Destroying %d charge maps\n", nosh->ncharge);
00732 #endif
00733                       
00734                       for (i=0; i<nosh->ncharge; i++) Vgrid_dtor(&(map[i]));
00735            }
00736            
00737            else return;
00738            
00739 }
00740 
00741 VPUBLIC void printPBEPARM(PBEparm *pbeparm) {
00742            
00743            int i;
00744            double ionstr = 0.0;
00745            
00746            for (i=0; i<pbeparm->nion; i++)
00747                       ionstr += 0.5*(VSQR(pbeparm->ionq[i])*pbeparm->ionc[i]);
00748            
00749            Vnm_tprint( 1, "  Molecule ID: %d\n", pbeparm->molid);
00750            switch (pbeparm->pbetype) {
00751                       case PBE_NPBE:
00752                                  Vnm_tprint( 1, "  Nonlinear traditional PBE\n");
00753                                  break;
00754                       case PBE_LPBE:
00755                                  Vnm_tprint( 1, "  Linearized traditional PBE\n");
00756                                  break;
00757                       case PBE_NRPBE:
00758                                  Vnm_tprint( 1, "  Nonlinear regularized PBE\n");
00759                                  Vnm_tprint( 2, "  ** Sorry, but Nathan broke the nonlinear regularized PBE implementation. **\n");
00760                                  Vnm_tprint( 2, "  ** Please let us know if you are interested in using it. **\n");
00761                                  VASSERT(0);
00762                                  break;
00763                       case PBE_LRPBE:
00764                                  Vnm_tprint( 1, "  Linearized regularized PBE\n");
00765                                  break;
00766                       case PBE_SMPBE: /* SMPBE Added */
00767                                  Vnm_tprint( 1, "  Nonlinear Size-Modified PBE\n");
00768                                  break;
00769                       default:
00770                                  Vnm_tprint(2, "  Unknown PBE type (%d)!\n", pbeparm->pbetype);
00771                                  break;
00772            }
00773            if (pbeparm->bcfl == BCFL_ZERO) {
00774                       Vnm_tprint( 1, "  Zero boundary conditions\n");
00775            } else if (pbeparm->bcfl == BCFL_SDH) {
00776                       Vnm_tprint( 1, "  Single Debye-Huckel sphere boundary \
00777 conditions\n");
00778            } else if (pbeparm->bcfl == BCFL_MDH) {
00779                       Vnm_tprint( 1, "  Multiple Debye-Huckel sphere boundary \
00780 conditions\n");
00781            } else if (pbeparm->bcfl == BCFL_FOCUS) {
00782                       Vnm_tprint( 1, "  Boundary conditions from focusing\n");
00783            } else if (pbeparm->bcfl == BCFL_MAP) {
00784                       Vnm_tprint( 1, "  Boundary conditions from potential map\n");
00785            } else if (pbeparm->bcfl == BCFL_MEM) {
00786                       Vnm_tprint( 1, "  Membrane potential boundary conditions.\n");
00787            }
00788            Vnm_tprint( 1, "  %d ion species (%4.3f M ionic strength):\n",
00789                                             pbeparm->nion, ionstr);
00790            for (i=0; i<pbeparm->nion; i++) {
00791                       Vnm_tprint( 1, "    %4.3f A-radius, %4.3f e-charge, \
00792 %4.3f M concentration\n", 
00793                                                        pbeparm->ionr[i], pbeparm->ionq[i], pbeparm->ionc[i]);            
00794            }
00795            
00796            if(pbeparm->pbetype == PBE_SMPBE){ /* SMPBE Added */
00797                       Vnm_tprint( 1, "  Lattice spacing: %4.3f A (SMPBE) \n", pbeparm->smvolume);
00798                       Vnm_tprint( 1, "  Relative size parameter: %4.3f  (SMPBE) \n", pbeparm->smsize);
00799            }
00800            
00801            Vnm_tprint( 1, "  Solute dielectric: %4.3f\n", pbeparm->pdie);
00802            Vnm_tprint( 1, "  Solvent dielectric: %4.3f\n", pbeparm->sdie);
00803            switch (pbeparm->srfm) {
00804                       case 0:
00805                                  Vnm_tprint( 1, "  Using \"molecular\" surface \
00806 definition; no smoothing\n");
00807                                  Vnm_tprint( 1, "  Solvent probe radius: %4.3f A\n",
00808                                                                   pbeparm->srad);
00809                                  break;
00810                       case 1:
00811                                  Vnm_tprint( 1, "  Using \"molecular\" surface definition;\
00812 harmonic average smoothing\n");
00813                                  Vnm_tprint( 1, "  Solvent probe radius: %4.3f A\n",
00814                                                                   pbeparm->srad);
00815                                  break;
00816                       case 2:
00817                                  Vnm_tprint( 1, "  Using spline-based surface definition;\
00818 window = %4.3f\n", pbeparm->swin);
00819                                  break;
00820                       default:
00821                                  break;
00822            }
00823            Vnm_tprint( 1, "  Temperature:  %4.3f K\n", pbeparm->temp);
00824            if (pbeparm->calcenergy != PCE_NO) Vnm_tprint( 1, "  Electrostatic \
00825 energies will be calculated\n");
00826            if (pbeparm->calcforce == PCF_TOTAL) Vnm_tprint( 1, "  Net solvent \
00827 forces will be calculated \n");
00828            if (pbeparm->calcforce == PCF_COMPS) Vnm_tprint( 1, "  All-atom \
00829 solvent forces will be calculated\n");
00830            for (i=0; i<pbeparm->numwrite; i++) {
00831                       switch (pbeparm->writetype[i]) {
00832                                  case VDT_CHARGE:
00833                                             Vnm_tprint(1, "  Charge distribution to be written to ");
00834                                             break;
00835                                  case VDT_POT:
00836                                             Vnm_tprint(1, "  Potential to be written to ");
00837                                             break;
00838                                  case VDT_SMOL:
00839                                             Vnm_tprint(1, "  Molecular solvent accessibility \
00840 to be written to ");
00841                                             break;
00842                                  case VDT_SSPL:
00843                                             Vnm_tprint(1, "  Spline-based solvent accessibility \
00844 to be written to ");
00845                                             break;
00846                                  case VDT_VDW:
00847                                             Vnm_tprint(1, "  van der Waals solvent accessibility \
00848 to be written to ");
00849                                             break;
00850                                  case VDT_IVDW:
00851                                             Vnm_tprint(1, "  Ion accessibility to be written to ");
00852                                             break;
00853                                  case VDT_LAP:
00854                                             Vnm_tprint(1, "  Potential Laplacian to be written to ");
00855                                             break;
00856                                  case VDT_EDENS:
00857                                             Vnm_tprint(1, "  Energy density to be written to ");
00858                                             break;
00859                                  case VDT_NDENS:
00860                                             Vnm_tprint(1, "  Ion number density to be written to ");
00861                                             break;
00862                                  case VDT_QDENS:
00863                                             Vnm_tprint(1, "  Ion charge density to be written to ");
00864                                             break;
00865                                  case VDT_DIELX:
00866                                             Vnm_tprint(1, "  X-shifted dielectric map to be written \
00867 to ");
00868                                             break;
00869                                  case VDT_DIELY:
00870                                             Vnm_tprint(1, "  Y-shifted dielectric map to be written \
00871 to ");
00872                                             break;
00873                                  case VDT_DIELZ:
00874                                             Vnm_tprint(1, "  Z-shifted dielectric map to be written \
00875 to ");
00876                                             break;
00877                                  case VDT_KAPPA:
00878                                             Vnm_tprint(1, "  Kappa map to be written to ");
00879                                             break;
00880                                  case VDT_ATOMPOT:
00881                                             Vnm_tprint(1, "  Atom potentials to be written to ");
00882                                             break;
00883                                  default: 
00884                                             Vnm_tprint(2, "  Invalid data type for writing!\n");
00885                                             break;
00886                       }
00887                       switch (pbeparm->writefmt[i]) {
00888                                  case VDF_DX:
00889                                             Vnm_tprint(1, "%s.%s\n", pbeparm->writestem[i], "dx");
00890                                             break;
00891                                  case VDF_GZ:
00892                                             Vnm_tprint(1, "%s.%s\n", pbeparm->writestem[i], "dx.gz");
00893                                             break;
00894                                  case VDF_UHBD:
00895                                             Vnm_tprint(1, "%s.%s\n", pbeparm->writestem[i], "grd");
00896                                             break;
00897                                  case VDF_AVS:
00898                                             Vnm_tprint(1, "%s.%s\n", pbeparm->writestem[i], "ucd");
00899                                             break;
00900                                  case VDF_MCSF:
00901                                             Vnm_tprint(1, "%s.%s\n", pbeparm->writestem[i], "mcsf");
00902                                             break;                                      
00903                                  case VDF_FLAT:
00904                                             Vnm_tprint(1, "%s.%s\n", pbeparm->writestem[i], "txt");
00905                                             break;                                      
00906                                  default: 
00907                                             Vnm_tprint(2, "  Invalid format for writing!\n");
00908                                             break;
00909                       }
00910                       
00911            }
00912            
00913 }
00914 
00915 VPUBLIC void printMGPARM(MGparm *mgparm, double realCenter[3]) {
00916            
00917            switch (mgparm->chgm) {
00918                       case 0:
00919                                  Vnm_tprint(1, "  Using linear spline charge discretization.\n");
00920                                  break;
00921                       case 1:
00922                                  Vnm_tprint(1, "  Using cubic spline charge discretization.\n");
00923                                  break;
00924                       default:
00925                                  break;
00926            }
00927            if (mgparm->type == MCT_PARALLEL) {
00928                       Vnm_tprint( 1, "  Partition overlap fraction = %g\n", 
00929                                                        mgparm->ofrac);
00930                       Vnm_tprint( 1, "  Processor array = %d x %d x %d\n", 
00931                                                        mgparm->pdime[0], mgparm->pdime[1], mgparm->pdime[2]);
00932            }
00933            Vnm_tprint( 1, "  Grid dimensions: %d x %d x %d\n",
00934                                             mgparm->dime[0], mgparm->dime[1], mgparm->dime[2]);
00935            Vnm_tprint( 1, "  Grid spacings: %4.3f x %4.3f x %4.3f\n",
00936                                             mgparm->grid[0], mgparm->grid[1], mgparm->grid[2]);
00937            Vnm_tprint( 1, "  Grid lengths: %4.3f x %4.3f x %4.3f\n",
00938                                             mgparm->glen[0], mgparm->glen[1], mgparm->glen[2]);
00939            Vnm_tprint( 1, "  Grid center: (%4.3f, %4.3f, %4.3f)\n",
00940                                             realCenter[0], realCenter[1], realCenter[2]);
00941            Vnm_tprint( 1, "  Multigrid levels: %d\n", mgparm->nlev);
00942            
00943 }
00944 
00945 VPUBLIC int initMG(int icalc, NOsh *nosh, MGparm *mgparm, 
00946                                                PBEparm *pbeparm, double realCenter[3], Vpbe *pbe[NOSH_MAXCALC], 
00947                                                Valist *alist[NOSH_MAXMOL], Vgrid *dielXMap[NOSH_MAXMOL], 
00948                                                Vgrid *dielYMap[NOSH_MAXMOL], Vgrid *dielZMap[NOSH_MAXMOL],
00949                                                Vgrid *kappaMap[NOSH_MAXMOL],  
00950                                                Vgrid *chargeMap[NOSH_MAXMOL], Vpmgp *pmgp[NOSH_MAXCALC], 
00951                                                Vpmg *pmg[NOSH_MAXCALC], Vgrid *potMap[NOSH_MAXMOL]) {
00952 
00953            int j,  focusFlag, iatom;
00954            size_t bytesTotal, highWater;
00955            double sparm, iparm, q;
00956            Vatom *atom = VNULL;
00957            Vgrid *theDielXMap, *theDielYMap, *theDielZMap;
00958            Vgrid *theKappaMap, *thePotMap, *theChargeMap;
00959            Valist *myalist = VNULL;
00960            
00961            Vnm_tstart(APBS_TIMER_SETUP, "Setup timer");
00962            
00963            /* Update the grid center */
00964            for (j=0; j<3; j++) realCenter[j] = mgparm->center[j];
00965            
00966            /* Check for completely-neutral molecule */
00967            q = 0;
00968            myalist = alist[pbeparm->molid-1];
00969            for (iatom=0; iatom<Valist_getNumberAtoms(myalist); iatom++) {
00970                       atom = Valist_getAtom(myalist, iatom);
00971                       q += VSQR(Vatom_getCharge(atom));
00972            }
00973            /*  D. Gohara 10/22/09 - disabled 
00974            if (q < (1e-6)) {
00975                       Vnm_tprint(2, "Molecule #%d is uncharged!\n", pbeparm->molid);
00976                       Vnm_tprint(2, "Sum square charge = %g!\n", q);
00977                       return 0;
00978            }
00979            */
00980            
00981            /* Set up PBE object */
00982            Vnm_tprint(0, "Setting up PBE object...\n");
00983            if (pbeparm->srfm == VSM_SPLINE) sparm = pbeparm->swin;
00984            else sparm = pbeparm->srad;
00985            if (pbeparm->nion > 0) iparm = pbeparm->ionr[0];
00986            else iparm = 0.0;
00987            if (pbeparm->bcfl == BCFL_FOCUS) {
00988                       if (icalc == 0) {
00989                                  Vnm_tprint( 2, "Can't focus first calculation!\n");
00990                                  return 0;
00991                       }
00992                       focusFlag = 1;
00993            } else focusFlag = 0;
00994            
00995            pbe[icalc] = Vpbe_ctor(myalist, pbeparm->nion,
00996                                                                      pbeparm->ionc, pbeparm->ionr, pbeparm->ionq, 
00997                                                                      pbeparm->temp, pbeparm->pdie, 
00998                                                                      pbeparm->sdie, sparm, focusFlag, pbeparm->sdens, 
00999                                                                      pbeparm->zmem, pbeparm->Lmem, pbeparm->mdie, 
01000                                                                      pbeparm->memv);
01001            
01002            /* Set up PDE object */
01003            Vnm_tprint(0, "Setting up PDE object...\n");
01004            switch (pbeparm->pbetype) {
01005                       case PBE_NPBE:
01006                                  /* TEMPORARY USEAQUA */
01007                                  mgparm->nonlintype = NONLIN_NPBE;
01008                                  mgparm->method = (mgparm->useAqua == 1) ? VSOL_NewtonAqua : VSOL_Newton;
01009                                  pmgp[icalc] = Vpmgp_ctor(mgparm);
01010                                  break;
01011                       case PBE_LPBE:
01012                                  /* TEMPORARY USEAQUA */
01013                                  mgparm->nonlintype = NONLIN_LPBE;
01014                                  mgparm->method = (mgparm->useAqua == 1) ? VSOL_CGMGAqua : VSOL_MG;
01015                                  pmgp[icalc] = Vpmgp_ctor(mgparm);
01016                                  break;
01017                       case PBE_LRPBE:
01018                                  Vnm_tprint(2, "Sorry, LRPBE isn't supported with the MG solver!\n");
01019                                  return 0;
01020                                  break;
01021                       case PBE_NRPBE:
01022                                  Vnm_tprint(2, "Sorry, NRPBE isn't supported with the MG solver!\n");
01023                                  return 0;
01024                                  break;
01025                       case PBE_SMPBE: /* SMPBE Added */
01026                                  mgparm->nonlintype = NONLIN_SMPBE;
01027                                  pmgp[icalc] = Vpmgp_ctor(mgparm);
01028                                  
01029                                  /* Copy Code */
01030                                  pbe[icalc]->smsize = pbeparm->smsize;
01031                                  pbe[icalc]->smvolume = pbeparm->smvolume;
01032                                  pbe[icalc]->ipkey = pmgp[icalc]->ipkey;
01033                                  
01034                                  break;
01035                       default:
01036                                  Vnm_tprint(2, "Error!  Unknown PBE type (%d)!\n", pbeparm->pbetype);
01037                                  return 0;
01038            }
01039            Vnm_tprint(0, "Setting PDE center to local center...\n");
01040            pmgp[icalc]->bcfl = pbeparm->bcfl;
01041            pmgp[icalc]->xcent = realCenter[0];
01042            pmgp[icalc]->ycent = realCenter[1];
01043            pmgp[icalc]->zcent = realCenter[2];
01044            
01045            if (pbeparm->bcfl == BCFL_FOCUS) {
01046         if (icalc == 0) {
01047             Vnm_tprint( 2, "Can't focus first calculation!\n");
01048             return 0;
01049         }
01050         /* Focusing requires the previous calculation in order to setup the 
01051         current run... */
01052         pmg[icalc] = Vpmg_ctor(pmgp[icalc], pbe[icalc], 1, pmg[icalc-1],
01053                                                                                 mgparm, pbeparm->calcenergy);   
01054         /* ...however, it should be done with the previous calculation now, so 
01055         we should be able to destroy it here. */
01056         /* Vpmg_dtor(&(pmg[icalc-1])); */
01057            } else {
01058                       if (icalc>0) Vpmg_dtor(&(pmg[icalc-1]));
01059                       pmg[icalc] = Vpmg_ctor(pmgp[icalc], pbe[icalc], 0, VNULL, mgparm, PCE_NO);
01060            }
01061            if (icalc>0) {
01062                       Vpmgp_dtor(&(pmgp[icalc-1]));
01063                       Vpbe_dtor(&(pbe[icalc-1]));
01064            }
01065            if (pbeparm->useDielMap) {
01066                       if ((pbeparm->dielMapID-1) < nosh->ndiel) {
01067                                  theDielXMap = dielXMap[pbeparm->dielMapID-1];
01068                       } else {
01069                                  Vnm_print(2, "Error!  %d is not a valid dielectric map ID!\n", 
01070                                                          pbeparm->dielMapID);
01071                                  return 0;
01072                       }
01073            } else theDielXMap = VNULL;
01074            if (pbeparm->useDielMap) {
01075                       if ((pbeparm->dielMapID-1) < nosh->ndiel) {
01076                                  theDielYMap = dielYMap[pbeparm->dielMapID-1];
01077                       } else {
01078                                  Vnm_print(2, "Error!  %d is not a valid dielectric map ID!\n",
01079                                                          pbeparm->dielMapID);
01080                                  return 0;
01081                       }
01082            } else theDielYMap = VNULL;
01083            if (pbeparm->useDielMap) {
01084                       if ((pbeparm->dielMapID-1) < nosh->ndiel) {
01085                                  theDielZMap = dielZMap[pbeparm->dielMapID-1];
01086                       } else {
01087                                  Vnm_print(2, "Error!  %d is not a valid dielectric map ID!\n",
01088                                                          pbeparm->dielMapID);
01089                                  return 0;
01090                       }
01091            } else theDielZMap = VNULL;
01092            if (pbeparm->useKappaMap) {
01093                       if ((pbeparm->kappaMapID-1) < nosh->nkappa) {
01094                                  theKappaMap = kappaMap[pbeparm->kappaMapID-1];
01095                       } else {
01096                                  Vnm_print(2, "Error!  %d is not a valid kappa map ID!\n",
01097                                                          pbeparm->kappaMapID);
01098                                  return 0;
01099                       }
01100            } else theKappaMap = VNULL;
01101            if (pbeparm->usePotMap) {
01102                       if ((pbeparm->potMapID-1) < nosh->npot) {
01103                                  thePotMap = potMap[pbeparm->potMapID-1];
01104                       } else {
01105                                  Vnm_print(2, "Error!  %d is not a valid potential map ID!\n",
01106                                                          pbeparm->potMapID);
01107                                  return 0;
01108                       }
01109            } else thePotMap = VNULL;
01110            if (pbeparm->useChargeMap) {
01111                       if ((pbeparm->chargeMapID-1) < nosh->ncharge) {
01112                                  theChargeMap = chargeMap[pbeparm->chargeMapID-1];
01113                       } else {
01114                                  Vnm_print(2, "Error!  %d is not a valid charge map ID!\n",
01115                                                          pbeparm->chargeMapID);
01116                                  return 0;
01117                       }
01118            } else theChargeMap = VNULL;
01119 
01120     if (pbeparm->bcfl == BCFL_MAP && thePotMap == VNULL) {
01121                       Vnm_print(2, "Warning: You specified 'bcfl map' in the input file, but no potential map was found.\n");
01122                       Vnm_print(2, "         You must specify 'usemap pot' statement in the APBS input file!\n");
01123                       Vnm_print(2, "Bailing out ...\n");
01124                       return 0;
01125            }
01126 
01127            if (!Vpmg_fillco(pmg[icalc], 
01128                                                         pbeparm->srfm, pbeparm->swin, mgparm->chgm,
01129                                                         pbeparm->useDielMap, theDielXMap,
01130                                                         pbeparm->useDielMap, theDielYMap,
01131                                                         pbeparm->useDielMap, theDielZMap,
01132                                                         pbeparm->useKappaMap, theKappaMap,
01133                                                         pbeparm->usePotMap, thePotMap,
01134                                                         pbeparm->useChargeMap, theChargeMap)) {
01135                       Vnm_print(2, "initMG:  problems setting up coefficients (fillco)!\n");
01136                       return 0;
01137            }
01138 
01139            /* Print a few derived parameters */
01140 #ifndef VAPBSQUIET
01141            Vnm_tprint(1, "  Debye length:  %g A\n", Vpbe_getDeblen(pbe[icalc]));
01142 #endif
01143            
01144            /* Setup time statistics */
01145            Vnm_tstop(APBS_TIMER_SETUP, "Setup timer");
01146            
01147            /* Memory statistics */
01148            bytesTotal = Vmem_bytesTotal();
01149            highWater = Vmem_highWaterTotal();
01150            
01151 #ifndef VAPBSQUIET
01152            Vnm_tprint( 1, "  Current memory usage:  %4.3f MB total, \
01153 %4.3f MB high water\n", (double)(bytesTotal)/(1024.*1024.),
01154                                             (double)(highWater)/(1024.*1024.));
01155 #endif
01156            
01157            return 1;
01158            
01159 }
01160 
01161 VPUBLIC void killMG(NOsh *nosh, Vpbe *pbe[NOSH_MAXCALC], 
01162                                                        Vpmgp *pmgp[NOSH_MAXCALC], Vpmg *pmg[NOSH_MAXCALC]) {
01163            
01164         int i;
01165            
01166 #ifndef VAPBSQUIET
01167            Vnm_tprint(1, "Destroying multigrid structures.\n");
01168 #endif
01169            
01170            /* 
01171               There appears to be a relationship (or this is a bug in Linux, can't tell
01172               at the moment, since Linux is the only OS that seems to be affected) 
01173               between one of the three object types: Vpbe, Vpmg or Vpmgp that requires 
01174               deallocations to be performed in a specific order. This results in a  
01175               bug some of the time when freeing Vpmg objects below. Therefore it 
01176               appears to be important to release the Vpmg structs BEFORE the Vpmgp structs .
01177            */
01178            Vpmg_dtor(&(pmg[nosh->ncalc-1]));
01179            
01180            for(i=0;i<nosh->ncalc;i++){
01181                       Vpbe_dtor(&(pbe[i]));
01182                       Vpmgp_dtor(&(pmgp[i]));
01183            }
01184            
01185 }
01186 
01187 VPUBLIC int solveMG(NOsh *nosh, Vpmg *pmg, MGparm_CalcType type) {
01188            
01189            int nx, ny, nz, i;
01190            
01191            
01192            if (nosh != VNULL) {
01193                       if (nosh->bogus) return 1;
01194            }
01195            
01196            Vnm_tstart(APBS_TIMER_SOLVER, "Solver timer");
01197            
01198            
01199            if (type != MCT_DUMMY) {
01200 #ifndef VAPBSQUIET
01201                       Vnm_tprint( 1,"  Solving PDE (see io.mc* for details)...\n");
01202 #endif
01203                       if (!Vpmg_solve(pmg)) {
01204                                  Vnm_print(2, "  Error during PDE solution!\n");
01205                                  return 0;
01206                       }
01207            } else {
01208                       Vnm_tprint( 1,"  Skipping solve for mg-dummy run; zeroing \
01209 solution array\n");
01210                       nx = pmg->pmgp->nx;
01211                       ny = pmg->pmgp->ny;
01212                       nz = pmg->pmgp->nz;
01213                       for (i=0; i<nx*ny*nz; i++) pmg->u[i] = 0.0;
01214            }
01215            Vnm_tstop(APBS_TIMER_SOLVER, "Solver timer");
01216            
01217            return 1;
01218            
01219 }
01220 
01221 VPUBLIC int setPartMG(NOsh *nosh, MGparm *mgparm, Vpmg *pmg) {
01222            
01223            int j;
01224            double partMin[3], partMax[3];
01225            
01226            if (nosh->bogus) return 1;
01227            
01228            if (mgparm->type == MCT_PARALLEL) {
01229                       for (j=0; j<3; j++) {
01230                                  partMin[j] = mgparm->partDisjCenter[j] - 0.5*mgparm->partDisjLength[j];
01231                                  partMax[j] = mgparm->partDisjCenter[j] + 0.5*mgparm->partDisjLength[j];
01232                       }
01233 #if 0
01234                       Vnm_tprint(1, "setPartMG (%s, %d):  Disj part center = (%g, %g, %g)\n",
01235                                                __FILE__, __LINE__,
01236                                                mgparm->partDisjCenter[0],
01237                                                mgparm->partDisjCenter[1],
01238                                                mgparm->partDisjCenter[2]
01239                                                );
01240                       Vnm_tprint(1, "setPartMG (%s, %d):  Disj part lower corner = (%g, %g, %g)\n",
01241                                                __FILE__, __LINE__, partMin[0], partMin[1], partMin[2]);
01242                       Vnm_tprint(1, "setPartMG (%s, %d):  Disj part upper corner = (%g, %g, %g)\n",
01243                                                __FILE__, __LINE__,
01244                                                partMax[0], partMax[1], partMax[2]);
01245 #endif
01246            } else {
01247                       for (j=0; j<3; j++) {
01248                                  partMin[j] = mgparm->center[j] - 0.5*mgparm->glen[j];
01249                                  partMax[j] = mgparm->center[j] + 0.5*mgparm->glen[j];
01250                       }
01251            }
01252            /* Vnm_print(1, "DEBUG (%s, %d):  setPartMG calling setPart with upper corner \
01253 %g %g %g and lower corner %g %g %g\n", __FILE__,  __LINE__,
01254                                    partMin[0], partMin[1], partMin[2],
01255                                    partMax[0], partMax[1], partMax[2]); */
01256            Vpmg_setPart(pmg, partMin, partMax, mgparm->partDisjOwnSide);
01257            
01258            
01259            return 1;
01260            
01261 }
01262 
01263 VPUBLIC int energyMG(NOsh *nosh, int icalc, Vpmg *pmg, 
01264                                                         int *nenergy, double *totEnergy, double *qfEnergy, double *qmEnergy,
01265                                                         double *dielEnergy) {
01266            
01267            Valist *alist;
01268            Vatom *atom;
01269            int i;
01270            double tenergy;
01271            MGparm *mgparm;
01272            PBEparm *pbeparm;
01273            int extEnergy;              
01274            
01275            mgparm = nosh->calc[icalc]->mgparm;
01276            pbeparm = nosh->calc[icalc]->pbeparm;
01277            
01278            Vnm_tstart(APBS_TIMER_ENERGY, "Energy timer");
01279 #ifndef VAPBSQUIET
01280            Vnm_tprint( 1,"  Calculating energy (see io.mc* for details)...\n");
01281 #endif
01282            extEnergy = 1;
01283            
01284            if (pbeparm->calcenergy == PCE_TOTAL) {
01285                       *nenergy = 1;
01286                       /* Some processors don't count */
01287                       if (nosh->bogus == 0) {
01288                                  *totEnergy = Vpmg_energy(pmg, extEnergy);
01289 #ifndef VAPBSQUIET
01290                                  Vnm_tprint( 1, "  Total electrostatic energy = %1.12E kJ/mol\n", 
01291                                                                   Vunit_kb*pbeparm->temp*(1e-3)*Vunit_Na*(*totEnergy));
01292 #endif
01293                       } else *totEnergy = 0;
01294            } else if (pbeparm->calcenergy == PCE_COMPS) {
01295                       *nenergy = 1;
01296                       *totEnergy = Vpmg_energy(pmg, extEnergy);
01297                       *qfEnergy = Vpmg_qfEnergy(pmg, extEnergy);
01298                       *qmEnergy = Vpmg_qmEnergy(pmg, extEnergy);
01299                       *dielEnergy = Vpmg_dielEnergy(pmg, extEnergy);
01300 #ifndef VAPBSQUIET
01301                       Vnm_tprint( 1, "  Total electrostatic energy = %1.12E \
01302 kJ/mol\n", Vunit_kb*pbeparm->temp*(1e-3)*Vunit_Na*(*totEnergy));
01303                       Vnm_tprint( 1, "  Fixed charge energy = %g kJ/mol\n",
01304                                                        0.5*Vunit_kb*pbeparm->temp*(1e-3)*Vunit_Na*(*qfEnergy));
01305                       Vnm_tprint( 1, "  Mobile charge energy = %g kJ/mol\n",
01306                                                        Vunit_kb*pbeparm->temp*(1e-3)*Vunit_Na*(*qmEnergy));
01307                       Vnm_tprint( 1, "  Dielectric energy = %g kJ/mol\n",
01308                                                        Vunit_kb*pbeparm->temp*(1e-3)*Vunit_Na*(*dielEnergy));
01309                       Vnm_tprint( 1, "  Per-atom energies:\n");
01310 #endif
01311                       alist = pmg->pbe->alist;
01312                       for (i=0; i<Valist_getNumberAtoms(alist); i++) {
01313                                  atom = Valist_getAtom(alist, i); 
01314                                  tenergy = Vpmg_qfAtomEnergy(pmg, atom);
01315 #ifndef VAPBSQUIET
01316                                  Vnm_tprint( 1, "      Atom %d:  %1.12E kJ/mol\n", i,
01317                                                                   0.5*Vunit_kb*pbeparm->temp*(1e-3)*Vunit_Na*tenergy);
01318 #endif
01319                       }
01320            } else *nenergy = 0;
01321            
01322            Vnm_tstop(APBS_TIMER_ENERGY, "Energy timer");
01323            
01324            return 1;
01325 }
01326 
01327 VPUBLIC int forceMG(Vmem *mem, NOsh *nosh, PBEparm *pbeparm, MGparm *mgparm,
01328                                                        Vpmg *pmg, int *nforce, AtomForce **atomForce, 
01329                                                        Valist *alist[NOSH_MAXMOL]) {
01330            
01331            int j, k;
01332            double qfForce[3], dbForce[3], ibForce[3];
01333            
01334            Vnm_tstart(APBS_TIMER_FORCE, "Force timer");
01335 
01336 #ifndef VAPBSQUIET
01337            Vnm_tprint( 1,"  Calculating forces...\n");
01338 #endif
01339 
01340            if (pbeparm->calcforce == PCF_TOTAL) {
01341                       *nforce = 1;
01342                       *atomForce = (AtomForce *)Vmem_malloc(mem, 1, sizeof(AtomForce));
01343                       /* Clear out force arrays */
01344                       for (j=0; j<3; j++) {
01345                                  (*atomForce)[0].qfForce[j] = 0;
01346                                  (*atomForce)[0].ibForce[j] = 0;
01347                                  (*atomForce)[0].dbForce[j] = 0;
01348                       }
01349                       for (j=0;j<Valist_getNumberAtoms(alist[pbeparm->molid-1]);j++) { 
01350                                  if (nosh->bogus == 0) {
01351                                             VASSERT(Vpmg_qfForce(pmg, qfForce, j, mgparm->chgm));
01352                                             VASSERT(Vpmg_ibForce(pmg, ibForce, j, pbeparm->srfm));
01353                                             VASSERT(Vpmg_dbForce(pmg, dbForce, j, pbeparm->srfm));
01354                                  } else {
01355                                             for (k=0; k<3; k++) {
01356                                                        qfForce[k] = 0; 
01357                                                        ibForce[k] = 0; 
01358                                                        dbForce[k] = 0; 
01359                                             }
01360                                  }
01361                                  for (k=0; k<3; k++) {
01362                                             (*atomForce)[0].qfForce[k] += qfForce[k];
01363                                             (*atomForce)[0].ibForce[k] += ibForce[k];
01364                                             (*atomForce)[0].dbForce[k] += dbForce[k];
01365                                  }
01366                       }
01367 #ifndef VAPBSQUIET
01368                       Vnm_tprint( 1, "  Printing net forces for molecule %d (kJ/mol/A)\n",
01369                                                        pbeparm->molid);
01370                       Vnm_tprint( 1, "  Legend:\n");
01371                       Vnm_tprint( 1, "    qf  -- fixed charge force\n");
01372                       Vnm_tprint( 1, "    db  -- dielectric boundary force\n");
01373                       Vnm_tprint( 1, "    ib  -- ionic boundary force\n");
01374                       Vnm_tprint( 1, "  qf  %4.3e  %4.3e  %4.3e\n",
01375                                                        Vunit_kb*pbeparm->temp*(1e-3)*Vunit_Na*(*atomForce)[0].qfForce[0],
01376                                                        Vunit_kb*pbeparm->temp*(1e-3)*Vunit_Na*(*atomForce)[0].qfForce[1],
01377                                                        Vunit_kb*pbeparm->temp*(1e-3)*Vunit_Na*(*atomForce)[0].qfForce[2]);
01378                       Vnm_tprint( 1, "  ib  %4.3e  %4.3e  %4.3e\n",
01379                                                        Vunit_kb*pbeparm->temp*(1e-3)*Vunit_Na*(*atomForce)[0].ibForce[0],
01380                                                        Vunit_kb*pbeparm->temp*(1e-3)*Vunit_Na*(*atomForce)[0].ibForce[1],
01381                                                        Vunit_kb*pbeparm->temp*(1e-3)*Vunit_Na*(*atomForce)[0].ibForce[2]);
01382                       Vnm_tprint( 1, "  db  %4.3e  %4.3e  %4.3e\n",
01383                                                        Vunit_kb*pbeparm->temp*(1e-3)*Vunit_Na*(*atomForce)[0].dbForce[0],
01384                                                        Vunit_kb*pbeparm->temp*(1e-3)*Vunit_Na*(*atomForce)[0].dbForce[1],
01385                                                        Vunit_kb*pbeparm->temp*(1e-3)*Vunit_Na*(*atomForce)[0].dbForce[2]);
01386 #endif
01387            } else if (pbeparm->calcforce == PCF_COMPS) {
01388                       *nforce = Valist_getNumberAtoms(alist[pbeparm->molid-1]);
01389                       *atomForce = (AtomForce *)Vmem_malloc(mem, *nforce,
01390                                                                                                                            sizeof(AtomForce));
01391 #ifndef VAPBSQUIET
01392                       Vnm_tprint( 1, "  Printing per-atom forces for molecule %d (kJ/mol/A)\n",
01393                                                        pbeparm->molid);
01394                       Vnm_tprint( 1, "  Legend:\n");
01395                       Vnm_tprint( 1, "    tot n -- total force for atom n\n");
01396                       Vnm_tprint( 1, "    qf  n -- fixed charge force for atom n\n");
01397                       Vnm_tprint( 1, "    db  n -- dielectric boundary force for atom n\n");
01398                       Vnm_tprint( 1, "    ib  n -- ionic boundary force for atom n\n");
01399 #endif
01400                       for (j=0;j<Valist_getNumberAtoms(alist[pbeparm->molid-1]);j++) {
01401                                  if (nosh->bogus == 0) {
01402                                             VASSERT(Vpmg_qfForce(pmg, (*atomForce)[j].qfForce, j, 
01403                                                                                                     mgparm->chgm));
01404                                             VASSERT(Vpmg_ibForce(pmg, (*atomForce)[j].ibForce, j, 
01405                                                                                                     pbeparm->srfm));
01406                                             VASSERT(Vpmg_dbForce(pmg, (*atomForce)[j].dbForce, j, 
01407                                                                                                     pbeparm->srfm));
01408                                  } else {
01409                                             for (k=0; k<3; k++) {
01410                                                        (*atomForce)[j].qfForce[k] = 0;
01411                                                        (*atomForce)[j].ibForce[k] = 0;
01412                                                        (*atomForce)[j].dbForce[k] = 0;
01413                                             }
01414                                  }
01415 #ifndef VAPBSQUIET
01416                                  Vnm_tprint( 1, "mgF  tot %d  %4.3e  %4.3e  %4.3e\n", j, 
01417                                                                   Vunit_kb*pbeparm->temp*(1e-3)*Vunit_Na \
01418                                                                   *((*atomForce)[j].qfForce[0]+(*atomForce)[j].ibForce[0]+
01419                                                                     (*atomForce)[j].dbForce[0]),
01420                                                                   Vunit_kb*pbeparm->temp*(1e-3)*Vunit_Na \
01421                                                                   *((*atomForce)[j].qfForce[1]+(*atomForce)[j].ibForce[1]+
01422                                                                     (*atomForce)[j].dbForce[1]),
01423                                                                   Vunit_kb*pbeparm->temp*(1e-3)*Vunit_Na \
01424                                                                   *((*atomForce)[j].qfForce[2]+(*atomForce)[j].ibForce[2]+
01425                                                                     (*atomForce)[j].dbForce[2]));
01426                                  Vnm_tprint( 1, "mgF  qf  %d  %4.3e  %4.3e  %4.3e\n", j, 
01427                                                                   Vunit_kb*pbeparm->temp*(1e-3)*Vunit_Na \
01428                                                                   *(*atomForce)[j].qfForce[0],
01429                                                                   Vunit_kb*pbeparm->temp*(1e-3)*Vunit_Na \
01430                                                                   *(*atomForce)[j].qfForce[1],
01431                                                                   Vunit_kb*pbeparm->temp*(1e-3)*Vunit_Na \
01432                                                                   *(*atomForce)[j].qfForce[2]);
01433                                  Vnm_tprint( 1, "mgF  ib  %d  %4.3e  %4.3e  %4.3e\n", j, 
01434                                                                   Vunit_kb*pbeparm->temp*(1e-3)*Vunit_Na \
01435                                                                   *(*atomForce)[j].ibForce[0],
01436                                                                   Vunit_kb*pbeparm->temp*(1e-3)*Vunit_Na \
01437                                                                   *(*atomForce)[j].ibForce[1],
01438                                                                   Vunit_kb*pbeparm->temp*(1e-3)*Vunit_Na \
01439                                                                   *(*atomForce)[j].ibForce[2]);
01440                                  Vnm_tprint( 1, "mgF  db  %d  %4.3e  %4.3e  %4.3e\n", j, 
01441                                                                   Vunit_kb*pbeparm->temp*(1e-3)*Vunit_Na \
01442                                                                   *(*atomForce)[j].dbForce[0],
01443                                                                   Vunit_kb*pbeparm->temp*(1e-3)*Vunit_Na \
01444                                                                   *(*atomForce)[j].dbForce[1],
01445                                                                   Vunit_kb*pbeparm->temp*(1e-3)*Vunit_Na \
01446                                                                   *(*atomForce)[j].dbForce[2]);
01447 #endif
01448                       }
01449            } else *nforce = 0;
01450            
01451            Vnm_tstop(APBS_TIMER_FORCE, "Force timer");
01452            
01453            return 1;
01454 }
01455 
01456 VPUBLIC void killEnergy() { 
01457            
01458 #ifndef VAPBSQUIET
01459            Vnm_tprint(1, "No energy arrays to destroy.\n"); 
01460 #endif
01461            
01462 }
01463 
01464 VPUBLIC void killForce(Vmem *mem, NOsh *nosh, int nforce[NOSH_MAXCALC], 
01465                                                           AtomForce *atomForce[NOSH_MAXCALC]) {
01466            
01467            int i;
01468            
01469 #ifndef VAPBSQUIET
01470            Vnm_tprint(1, "Destroying force arrays.\n");
01471 #endif
01472            
01473            for (i=0; i<nosh->ncalc; i++) {
01474                       
01475                       if (nforce[i] > 0) Vmem_free(mem, nforce[i], sizeof(AtomForce),
01476                                                                                                     (void **)&(atomForce[i]));
01477                       
01478            }
01479 }
01480 
01481 VPUBLIC int writematMG(int rank, NOsh *nosh, PBEparm *pbeparm, Vpmg *pmg) {
01482            
01483            char writematstem[VMAX_ARGLEN];
01484            char outpath[VMAX_ARGLEN];
01485            char mxtype[3];
01486            int strlenmax;
01487            
01488            if (nosh->bogus) return 1;
01489            
01490 #ifdef HAVE_MPI_H
01491            strlenmax = VMAX_ARGLEN-14;
01492            if (strlen(pbeparm->writematstem) > strlenmax) {
01493                       Vnm_tprint(2, "  Matrix name (%s) too long (%d char max)!\n",
01494                                                pbeparm->writematstem, strlenmax);
01495                       Vnm_tprint(2, "  Not writing matrix!\n");
01496                       return 0;
01497            }
01498            sprintf(writematstem, "%s-PE%d", pbeparm->writematstem, rank);
01499 #else
01500            strlenmax = (int)(VMAX_ARGLEN)-1;
01501            if ((int)strlen(pbeparm->writematstem) > strlenmax) {
01502                       Vnm_tprint(2, "  Matrix name (%s) too long (%d char max)!\n",
01503                                                pbeparm->writematstem, strlenmax);
01504                       Vnm_tprint(2, "  Not writing matrix!\n");
01505                       return 0;
01506            }
01507            if(nosh->ispara == 1){
01508                       sprintf(writematstem, "%s-PE%d", pbeparm->writematstem,nosh->proc_rank);
01509            }else{
01510                       sprintf(writematstem, "%s", pbeparm->writematstem);
01511            }
01512 #endif
01513            
01514            if (pbeparm->writemat == 1) {
01515                       strlenmax = VMAX_ARGLEN-5;
01516                       if ((int)strlen(pbeparm->writematstem) > strlenmax) {
01517                                  Vnm_tprint(2, "  Matrix name (%s) too long (%d char max)!\n",
01518                                                           pbeparm->writematstem, strlenmax);
01519                                  Vnm_tprint(2, "  Not writing matrix!\n");
01520                                  return 0;
01521                       }
01522                       sprintf(outpath, "%s.%s", writematstem, "mat");
01523                       mxtype[0] = 'R';
01524                       mxtype[1] = 'S';
01525                       mxtype[2] = 'A';
01526                       /* Poisson operator only */
01527                       if (pbeparm->writematflag == 0) {
01528                                  Vnm_tprint( 1, "  Writing Poisson operator matrix \
01529 to %s...\n", outpath);
01530                                  
01531                                  /* Linearization of Poisson-Boltzmann operator around solution */
01532                       } else if (pbeparm->writematflag == 1) {
01533                                  Vnm_tprint( 1, "  Writing linearization of full \
01534 Poisson-Boltzmann operator matrix to %s...\n", outpath);
01535                                  
01536                       } else {
01537                                  Vnm_tprint( 2, "  Bogus matrix specification\
01538 (%d)!\n", pbeparm->writematflag);
01539                                  return 0;
01540                       }
01541                       
01542                       Vnm_tprint(0, "  Printing operator...\n");
01543                       //Vpmg_printColComp(pmg, outpath, outpath, mxtype, 
01544                       //                                            pbeparm->writematflag);
01545                       return 0;
01546                       
01547            }
01548            
01549            return 1;
01550 }
01551 
01552 VPUBLIC void storeAtomEnergy(Vpmg *pmg, int icalc, double **atomEnergy, 
01553                                                                               int *nenergy){
01554            
01555            Vatom *atom;
01556            Valist *alist;
01557            int i;
01558            
01559            alist = pmg->pbe->alist;
01560            *nenergy = Valist_getNumberAtoms(alist);
01561            *atomEnergy = (double *)Vmem_malloc(pmg->vmem, *nenergy, sizeof(double));
01562            
01563            for (i=0; i<*nenergy; i++) {
01564                       atom = Valist_getAtom(alist, i); 
01565                       (*atomEnergy)[i] = Vpmg_qfAtomEnergy(pmg, atom);
01566            }
01567 }
01568 
01569 VPUBLIC int writedataFlat(
01570                                                                     NOsh *nosh, 
01571                                                                     Vcom *com, 
01572                                                                     const char *fname, 
01573                                                                     double totEnergy[NOSH_MAXCALC], 
01574                                                                     double qfEnergy[NOSH_MAXCALC], 
01575                                                                     double qmEnergy[NOSH_MAXCALC], 
01576                                                                     double dielEnergy[NOSH_MAXCALC],
01577                                                                     int nenergy[NOSH_MAXCALC], 
01578                                                                     double *atomEnergy[NOSH_MAXCALC],
01579                                                                     int nforce[NOSH_MAXCALC], 
01580                                                                     AtomForce *atomForce[NOSH_MAXCALC]) {
01581            
01582            FILE *file;
01583            time_t now;
01584            int ielec, icalc, i, j;
01585            char *timestring = VNULL;
01586            PBEparm *pbeparm = VNULL;
01587            MGparm *mgparm = VNULL;
01588            double conversion, ltenergy, gtenergy, scalar;
01589 
01590            if (nosh->bogus) return 1;
01591            
01592            /* Initialize some variables */
01593            
01594            icalc = 0;
01595            
01596            file = fopen(fname, "w");
01597            if (file == VNULL) {
01598                       Vnm_print(2, "writedataFlat: Problem opening virtual socket %s\n",
01599                                               fname);
01600                       return 0;
01601            }
01602            
01603            /* Strip the newline character from the date */
01604            
01605            now = time(VNULL);
01606            timestring = ctime(&now);
01607            fprintf(file,"%s\n", timestring);
01608            
01609            for (ielec=0; ielec<nosh->nelec;ielec++) { /* elec loop */
01610                       
01611                       /* Initialize per-elec pointers */
01612                       
01613                       mgparm = nosh->calc[icalc]->mgparm;
01614                       pbeparm = nosh->calc[icalc]->pbeparm;
01615                       
01616                       /* Convert from kT/e to kJ/mol */
01617                       conversion =  Vunit_kb*pbeparm->temp*(1e-3)*Vunit_Na;
01618                       
01619                       fprintf(file,"elec");
01620                       if (Vstring_strcasecmp(nosh->elecname[ielec], "") != 0) {
01621                                  fprintf(file," name %s\n", nosh->elecname[ielec]);
01622                       } else fprintf(file, "\n");
01623                       
01624                       switch (mgparm->type) {
01625                                  case MCT_DUMMY:
01626                                             fprintf(file,"    mg-dummy\n");
01627                                             break;
01628                                  case MCT_MANUAL:
01629                                             fprintf(file,"    mg-manual\n");
01630                                             break;
01631                                  case MCT_AUTO:
01632                                             fprintf(file,"    mg-auto\n");
01633                                             break;
01634                                  case MCT_PARALLEL:
01635                                             fprintf(file,"    mg-para\n");
01636                                             break;
01637                                  default:
01638                                             break;
01639                       }
01640                       
01641                       fprintf(file,"    mol %d\n", pbeparm->molid);
01642                       fprintf(file,"    dime %d %d %d\n", mgparm->dime[0], mgparm->dime[1],\
01643                                             mgparm->dime[2]);
01644                       
01645                       switch (pbeparm->pbetype) {
01646                                  case PBE_NPBE:
01647                                             fprintf(file,"    npbe\n");
01648                                             break;
01649                                  case PBE_LPBE:
01650                                             fprintf(file,"    lpbe\n");
01651                                             break;
01652                                  default:
01653                                             break;
01654                       }
01655                       
01656                       if (pbeparm->nion > 0) {
01657                                  for (i=0; i<pbeparm->nion; i++) {
01658                                             fprintf(file,"    ion %4.3f %4.3f %4.3f\n",
01659                                                                   pbeparm->ionr[i], pbeparm->ionq[i], pbeparm->ionc[i]);
01660                                  }
01661                       }
01662                       
01663                       fprintf(file,"    pdie %4.3f\n", pbeparm->pdie);
01664                       fprintf(file,"    sdie %4.3f\n", pbeparm->sdie);
01665                       
01666                       switch (pbeparm->srfm) {
01667                                  case 0:
01668                                             fprintf(file,"    srfm mol\n");
01669                                             fprintf(file,"    srad %4.3f\n", pbeparm->srad);
01670                                             break;
01671                                  case 1:
01672                                             fprintf(file,"    srfm smol\n");
01673                                             fprintf(file,"    srad %4.3f\n", pbeparm->srad);
01674                                             break;
01675                                  case 2:
01676                                             fprintf(file,"    srfm spl2\n");
01677                                             fprintf(file,"    srad %4.3f\n", pbeparm->srad);
01678                                             break;
01679                                  default:
01680                                             break;
01681                       }
01682                       
01683                       switch (pbeparm->bcfl) {
01684                                  case BCFL_ZERO:
01685                                             fprintf(file,"    bcfl zero\n");
01686                                             break;
01687                                  case BCFL_SDH:
01688                                             fprintf(file,"    bcfl sdh\n");
01689                                             break;
01690                                  case BCFL_MDH:
01691                                             fprintf(file,"    bcfl mdh\n");
01692                                             break;
01693                                  case BCFL_FOCUS:
01694                                             fprintf(file,"    bcfl focus\n");
01695                                             break;
01696                                  case BCFL_MAP:
01697                                             fprintf(file,"    bcfl map\n");
01698                                             break;
01699                                  case BCFL_MEM:
01700                                             fprintf(file,"    bcfl mem\n");
01701                                             break;
01702                                  default:
01703                                             break;
01704                       }
01705                       
01706                       fprintf(file,"    temp %4.3f\n", pbeparm->temp);
01707                       
01708                       for (;icalc<=nosh->elec2calc[ielec];icalc++){ /* calc loop */
01709                                  
01710                                  /* Reinitialize per-calc pointers */
01711                                  mgparm = nosh->calc[icalc]->mgparm;
01712                                  pbeparm = nosh->calc[icalc]->pbeparm;
01713                                  
01714                                  fprintf(file,"    calc\n");
01715                                  fprintf(file,"        id %i\n", (icalc+1));
01716                                  fprintf(file,"        grid %4.3f %4.3f %4.3f\n", 
01717                                                        mgparm->grid[0], mgparm->grid[1], mgparm->grid[2]);
01718                                  fprintf(file,"        glen %4.3f %4.3f %4.3f\n", 
01719                                                        mgparm->glen[0], mgparm->glen[1], mgparm->glen[2]);
01720                                  
01721                                  if (pbeparm->calcenergy == PCE_TOTAL) {
01722                                             fprintf(file,"        totEnergy %1.12E kJ/mol\n", 
01723                                                                   (totEnergy[icalc]*conversion));
01724                                  } if (pbeparm->calcenergy == PCE_COMPS) {
01725                                          fprintf(file,"        totEnergy %1.12E kJ/mol\n", 
01726                                                                   (totEnergy[icalc]*conversion));
01727                                             fprintf(file,"        qfEnergy %1.12E kJ/mol\n", 
01728                                                                   (0.5*qfEnergy[icalc]*conversion)); 
01729                                             fprintf(file,"        qmEnergy %1.12E kJ/mol\n", 
01730                                                                   (qmEnergy[icalc]*conversion)); 
01731                                             fprintf(file,"        dielEnergy %1.12E kJ/mol\n", 
01732                                                                   (dielEnergy[icalc]*conversion));
01733                                             for (i=0; i<nenergy[icalc]; i++){
01734                                                        fprintf(file,"        atom %i %1.12E kJ/mol\n", i,
01735                                                                              (0.5*atomEnergy[icalc][i]*conversion));
01736                                                        
01737                                             }
01738                                  } 
01739 
01740                                  if (pbeparm->calcforce == PCF_TOTAL) { 
01741                                             fprintf(file,"        qfForce %1.12E %1.12E %1.12E kJ/mol/A\n", 
01742                                                                   (atomForce[icalc][0].qfForce[0]*conversion), 
01743                                                                (atomForce[icalc][0].qfForce[1]*conversion),
01744                                                                (atomForce[icalc][0].qfForce[2]*conversion));
01745                                             fprintf(file,"        ibForce %1.12E %1.12E %1.12E kJ/mol/A\n", 
01746                                                                   (atomForce[icalc][0].ibForce[0]*conversion), 
01747                                                                (atomForce[icalc][0].ibForce[1]*conversion),
01748                                                                (atomForce[icalc][0].ibForce[2]*conversion));
01749                                             fprintf(file,"        dbForce %1.12E %1.12E %1.12E kJ/mol/A\n", 
01750                                                                   (atomForce[icalc][0].dbForce[0]*conversion), 
01751                                                                (atomForce[icalc][0].dbForce[1]*conversion),
01752                                                                (atomForce[icalc][0].dbForce[2]*conversion));
01753                                  }
01754                                  fprintf(file,"    end\n");
01755                       }
01756 
01757                       fprintf(file,"end\n");
01758            }
01759 
01760 /* Handle print energy statements */
01761 
01762 for (i=0; i<nosh->nprint; i++) {
01763            
01764            if (nosh->printwhat[i] == NPT_ENERGY) {
01765                       
01766                       fprintf(file,"print energy");
01767                       fprintf(file," %d", nosh->printcalc[i][0]+1); 
01768                       
01769                       for (j=1; j<nosh->printnarg[i]; j++) {
01770                                  if (nosh->printop[i][j-1] == 0) fprintf(file," +");
01771                                  else if (nosh->printop[i][j-1] == 1) fprintf(file, " -");
01772                                  fprintf(file, " %d", nosh->printcalc[i][j]+1);
01773                       }
01774                       
01775                       fprintf(file, "\n");
01776                       icalc = nosh->elec2calc[nosh->printcalc[i][0]];
01777                       
01778                       ltenergy = Vunit_kb * (1e-3) * Vunit_Na * \
01779                                  nosh->calc[icalc]->pbeparm->temp * totEnergy[icalc];
01780                       
01781                       for (j=1; j<nosh->printnarg[i]; j++) {
01782                                  icalc = nosh->elec2calc[nosh->printcalc[i][j]];
01783                                  /* Add or subtract? */
01784                                  if (nosh->printop[i][j-1] == 0) scalar = 1.0;
01785                                  else if (nosh->printop[i][j-1] == 1) scalar = -1.0;
01786                                  /* Accumulate */
01787                                  ltenergy += (scalar * Vunit_kb * (1e-3) * Vunit_Na *
01788                                                                    nosh->calc[icalc]->pbeparm->temp * totEnergy[icalc]);
01789                                  
01790                                  Vcom_reduce(com, &ltenergy, &gtenergy, 1, 2, 0);
01791                                  
01792                       }
01793                       fprintf(file,"    localEnergy %1.12E kJ/mol\n", \
01794                                             ltenergy);
01795                       fprintf(file,"    globalEnergy %1.12E kJ/mol\nend\n", \
01796                                             gtenergy); 
01797            } 
01798 }
01799 
01800 fclose(file);
01801 
01802 return 1;
01803 }
01804 
01805 VPUBLIC int writedataXML(NOsh *nosh, Vcom *com, const char *fname, 
01806                                                                    double totEnergy[NOSH_MAXCALC], 
01807                                                                    double qfEnergy[NOSH_MAXCALC], 
01808                                                                    double qmEnergy[NOSH_MAXCALC], 
01809                                                                    double dielEnergy[NOSH_MAXCALC],
01810                                                                    int nenergy[NOSH_MAXCALC], 
01811                                                                    double *atomEnergy[NOSH_MAXCALC],
01812                                                           int nforce[NOSH_MAXCALC], 
01813                                                                    AtomForce *atomForce[NOSH_MAXCALC]) {
01814            
01815            FILE *file;
01816            time_t now;
01817            int ielec, icalc, i, j;
01818            char *timestring = VNULL;
01819            char *c = VNULL;
01820            PBEparm *pbeparm = VNULL;
01821            MGparm *mgparm = VNULL;
01822            double conversion, ltenergy, gtenergy, scalar;
01823            
01824            if (nosh->bogus) return 1;
01825            
01826            /* Initialize some variables */
01827            
01828            icalc = 0;
01829            
01830            file = fopen(fname, "w");
01831            if (file == VNULL) {
01832                       Vnm_print(2, "writedataXML: Problem opening virtual socket %s\n",
01833                                               fname);
01834                       return 0;
01835            }
01836            
01837            fprintf(file,"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
01838            fprintf(file,"<APBS>\n");
01839            
01840            /* Strip the newline character from the date */
01841            
01842            now = time(VNULL);
01843            timestring = ctime(&now);
01844            for(c = timestring; *c != '\n'; c++);
01845            *c = '\0';
01846            fprintf(file,"    <date>%s</date>\n", timestring);
01847            
01848            for (ielec=0; ielec<nosh->nelec;ielec++){ /* elec loop */
01849                       
01850                       /* Initialize per-elec pointers */
01851                       
01852                       mgparm = nosh->calc[icalc]->mgparm;
01853                       pbeparm = nosh->calc[icalc]->pbeparm;
01854                       
01855                       /* Convert from kT/e to kJ/mol */
01856                       conversion =  Vunit_kb*pbeparm->temp*(1e-3)*Vunit_Na;
01857                       
01858                       fprintf(file,"    <elec>\n");
01859                       if (Vstring_strcasecmp(nosh->elecname[ielec], "") != 0) {
01860                                  fprintf(file,"      <name>%s</name>\n", nosh->elecname[ielec]);
01861                       } 
01862                       
01863                       switch (mgparm->type) {
01864                                  case MCT_DUMMY:
01865                                             fprintf(file,"      <type>mg-dummy</type>\n");
01866                                             break;
01867                                  case MCT_MANUAL:
01868                                             fprintf(file,"      <type>mg-manual</type>\n");
01869                                             break;
01870                                  case MCT_AUTO:
01871                                             fprintf(file,"      <type>mg-auto</type>\n");
01872                                             break;
01873                                  case MCT_PARALLEL:
01874                                             fprintf(file,"      <type>mg-para</type>\n");
01875                                             break;
01876                                  default:
01877                                             break;
01878                       }
01879                       
01880                       fprintf(file,"      <molid>%d</molid>\n", pbeparm->molid);
01881                       fprintf(file,"      <nx>%d</nx>\n", mgparm->dime[0]);
01882                       fprintf(file,"      <ny>%d</ny>\n", mgparm->dime[1]);
01883                       fprintf(file,"      <nz>%d</nz>\n", mgparm->dime[2]);
01884                       
01885                       switch (pbeparm->pbetype) {
01886                                  case PBE_NPBE:
01887                                             fprintf(file,"      <pbe>npbe</pbe>\n");
01888                                             break;
01889                                  case PBE_LPBE:
01890                                             fprintf(file,"      <pbe>lpbe</pbe>\n");
01891                                             break;
01892                                  default:
01893                                             break;
01894                       }
01895                       
01896                       if (pbeparm->nion > 0) {
01897                                  for (i=0; i<pbeparm->nion; i++) {
01898                                             fprintf(file, "      <ion>\n");
01899                                             fprintf(file,"          <radius>%4.3f A</radius>\n",
01900                                                                   pbeparm->ionr[i]);
01901                                             fprintf(file,"          <charge>%4.3f A</charge>\n",
01902                                                                   pbeparm->ionq[i]);
01903                                             fprintf(file,"          <concentration>%4.3f M</concentration>\n", 
01904                                                                   pbeparm->ionc[i]);
01905                                             fprintf(file, "      </ion>\n");
01906                                             
01907                                  }
01908                       }
01909                       
01910                       fprintf(file,"      <pdie>%4.3f</pdie>\n", pbeparm->pdie);
01911                       fprintf(file,"      <sdie>%4.3f</sdie>\n", pbeparm->sdie);
01912                       
01913                       switch (pbeparm->srfm) {
01914                                  case 0:
01915                                             fprintf(file,"      <srfm>mol</srfm>\n");
01916                                             fprintf(file,"      <srad>%4.3f</srad>\n", pbeparm->srad);
01917                                             break;
01918                                  case 1:
01919                                             fprintf(file,"      <srfm>smol</srfm>\n");
01920                                             fprintf(file,"      <srad>%4.3f</srad>\n", pbeparm->srad);
01921                                             break;
01922                                  case 2:
01923                                             fprintf(file,"      <srfm>spl2</srfm>\n");
01924                                             break;
01925                                  default:
01926                                             break;
01927                       }
01928                       
01929                       switch (pbeparm->bcfl) {
01930                                  case BCFL_ZERO:
01931                                             fprintf(file,"      <bcfl>zero</bcfl>\n");
01932                                             break;
01933                                  case BCFL_SDH:
01934                                             fprintf(file,"      <bcfl>sdh</bcfl>\n");
01935                                             break;
01936                                  case BCFL_MDH:
01937                                             fprintf(file,"      <bcfl>mdh</bcfl>\n");
01938                                             break;
01939                                  case BCFL_FOCUS:
01940                                             fprintf(file,"      <bcfl>focus</bcfl>\n");
01941                                             break;
01942                                  case BCFL_MAP:
01943                                             fprintf(file,"      <bcfl>map</bcfl>\n");
01944                                             break;
01945                                  case BCFL_MEM:
01946                                             fprintf(file,"      <bcfl>mem</bcfl>\n");
01947                                             break;
01948                                  default:
01949                                             break;
01950                       }
01951                       
01952                       fprintf(file,"      <temp>%4.3f K</temp>\n", pbeparm->temp);
01953                       
01954                       for (;icalc<=nosh->elec2calc[ielec];icalc++){ /* calc loop */
01955                                  
01956                                  /* Reinitialize per-calc pointers */
01957                                  mgparm = nosh->calc[icalc]->mgparm;
01958                                  pbeparm = nosh->calc[icalc]->pbeparm;
01959                                  
01960                                  fprintf(file,"      <calc>\n");
01961                                  fprintf(file,"          <id>%i</id>\n", (icalc+1));
01962                                  fprintf(file,"          <hx>%4.3f A</hx>\n", mgparm->grid[0]);
01963                                  fprintf(file,"          <hy>%4.3f A</hy>\n", mgparm->grid[1]);
01964                                  fprintf(file,"          <hz>%4.3f A</hz>\n", mgparm->grid[2]);
01965                                  fprintf(file,"          <xlen>%4.3f A</xlen>\n", mgparm->glen[0]);
01966                                  fprintf(file,"          <ylen>%4.3f A</ylen>\n", mgparm->glen[1]);
01967                                  fprintf(file,"          <zlen>%4.3f A</zlen>\n", mgparm->glen[2]);
01968                                  
01969                                  if (pbeparm->calcenergy == PCE_TOTAL) {
01970                                             fprintf(file,"          <totEnergy>%1.12E kJ/mol</totEnergy>\n", 
01971                                                                   (totEnergy[icalc]*conversion));
01972                                  } else if (pbeparm->calcenergy == PCE_COMPS) {
01973                                    fprintf(file,"          <totEnergy>%1.12E kJ/mol</totEnergy>\n", 
01974                                                                   (totEnergy[icalc]*conversion));
01975                                             fprintf(file,"          <qfEnergy>%1.12E kJ/mol</qfEnergy>\n", 
01976                                                                   (0.5*qfEnergy[icalc]*conversion)); 
01977                                             fprintf(file,"          <qmEnergy>%1.12E kJ/mol</qmEnergy>\n", 
01978                                                                   (qmEnergy[icalc]*conversion)); 
01979                                             fprintf(file,"          <dielEnergy>%1.12E kJ/mol</dielEnergy>\n", 
01980                                                                   (dielEnergy[icalc]*conversion));
01981                                             for (i=0; i<nenergy[icalc]; i++){
01982                                                        fprintf(file,"          <atom>\n");
01983                                                        fprintf(file,"              <id>%i</id>\n", i+1);
01984                                                        fprintf(file,"              <energy>%1.12E kJ/mol</energy>\n", 
01985                                                                              (0.5*atomEnergy[icalc][i]*conversion));
01986                                                        fprintf(file,"          </atom>\n");
01987                                             }
01988                                  } 
01989 
01990 
01991                                  if (pbeparm->calcforce == PCF_TOTAL) { 
01992                                          fprintf(file,"          <qfforce_x>%1.12E</qfforce_x>\n", 
01993                                                        atomForce[icalc][0].qfForce[0]*conversion); 
01994                                             fprintf(file,"          <qfforce_y>%1.12E</qfforce_y>\n", 
01995                                                        atomForce[icalc][0].qfForce[1]*conversion); 
01996                                             fprintf(file,"          <qfforce_z>%1.12E</qfforce_z>\n", 
01997                                                        atomForce[icalc][0].qfForce[2]*conversion); 
01998                                             fprintf(file,"          <ibforce_x>%1.12E</ibforce_x>\n", 
01999                                                        atomForce[icalc][0].ibForce[0]*conversion); 
02000                                             fprintf(file,"          <ibforce_y>%1.12E</ibforce_y>\n", 
02001                                                        atomForce[icalc][0].ibForce[1]*conversion); 
02002                                             fprintf(file,"          <ibforce_z>%1.12E</ibforce_z>\n", 
02003                                                        atomForce[icalc][0].ibForce[2]*conversion); 
02004                                             fprintf(file,"          <dbforce_x>%1.12E</dbforce_x>\n", 
02005                                                        atomForce[icalc][0].dbForce[0]*conversion); 
02006                                             fprintf(file,"          <dbforce_y>%1.12E</dbforce_y>\n", 
02007                                                        atomForce[icalc][0].dbForce[1]*conversion); 
02008                                             fprintf(file,"          <dbforce_z>%1.12E</dbforce_z>\n", 
02009                                                        atomForce[icalc][0].dbForce[2]*conversion); 
02010                                  }
02011 
02012                                  fprintf(file,"      </calc>\n");
02013                       }
02014 
02015                       fprintf(file,"    </elec>\n");
02016            }
02017 
02018 /* Handle print energy statements */
02019 
02020 for (i=0; i<nosh->nprint; i++) {
02021            
02022            if (nosh->printwhat[i] == NPT_ENERGY) {
02023                       
02024                       fprintf(file,"    <printEnergy>\n");
02025                       fprintf(file,"        <equation>%d", nosh->printcalc[i][0]+1); 
02026                       
02027                       for (j=1; j<nosh->printnarg[i]; j++) {
02028                                  if (nosh->printop[i][j-1] == 0) fprintf(file," +");
02029                                  else if (nosh->printop[i][j-1] == 1) fprintf(file, " -");
02030                                  fprintf(file, " %d", nosh->printcalc[i][j] +1);
02031                       }
02032                       
02033                       fprintf(file, "</equation>\n");
02034                       icalc = nosh->elec2calc[nosh->printcalc[i][0]];
02035                       
02036                       ltenergy = Vunit_kb * (1e-3) * Vunit_Na * \
02037                                  nosh->calc[icalc]->pbeparm->temp * totEnergy[icalc];
02038                       
02039                       for (j=1; j<nosh->printnarg[i]; j++) {
02040                                  icalc = nosh->elec2calc[nosh->printcalc[i][j]];
02041                                  /* Add or subtract? */
02042                                  if (nosh->printop[i][j-1] == 0) scalar = 1.0;
02043                                  else if (nosh->printop[i][j-1] == 1) scalar = -1.0;
02044                                  /* Accumulate */
02045                                  ltenergy += (scalar * Vunit_kb * (1e-3) * Vunit_Na *
02046                                                                    nosh->calc[icalc]->pbeparm->temp * totEnergy[icalc]);
02047                       }
02048                       Vcom_reduce(com, &ltenergy, &gtenergy, 1, 2, 0);
02049                       fprintf(file,"        <localEnergy>%1.12E kJ/mol</localEnergy>\n", \
02050                                             ltenergy);
02051                       fprintf(file,"        <globalEnergy>%1.12E kJ/mol</globalEnergy>\n", \
02052                                             gtenergy); 
02053                       
02054                       fprintf(file,"    </printEnergy>\n");
02055            }
02056 }
02057 
02058 /* Add ending tags and close the file */
02059 fprintf(file,"</APBS>\n");
02060 fclose(file);
02061 
02062 return 1;
02063 }   
02064 
02065 VPUBLIC int writedataMG(int rank, NOsh *nosh, PBEparm *pbeparm, Vpmg *pmg) {
02066            
02067            char writestem[VMAX_ARGLEN];
02068            char outpath[VMAX_ARGLEN];
02069            char title[72];
02070            int i, nx, ny, nz, natoms;
02071            double hx, hy, hzed, xcent, ycent, zcent, xmin, ymin, zmin;
02072            
02073            Vgrid *grid; 
02074            Vio *sock;
02075            
02076            if (nosh->bogus) return 1;
02077            
02078            for (i=0; i<pbeparm->numwrite; i++) { 
02079                       
02080                       nx = pmg->pmgp->nx;
02081                       ny = pmg->pmgp->ny;
02082                       nz = pmg->pmgp->nz;
02083                       hx = pmg->pmgp->hx;
02084                       hy = pmg->pmgp->hy;
02085                       hzed = pmg->pmgp->hzed;
02086                       
02087                       switch (pbeparm->writetype[i]) {
02088                                  
02089                                  case VDT_CHARGE:
02090                                             
02091                                             Vnm_tprint(1, "  Writing charge distribution to ");
02092                                             xcent = pmg->pmgp->xcent;
02093                                             ycent = pmg->pmgp->ycent;
02094                                             zcent = pmg->pmgp->zcent;
02095                                             xmin = xcent - 0.5*(nx-1)*hx;
02096                                             ymin = ycent - 0.5*(ny-1)*hy;
02097                                             zmin = zcent - 0.5*(nz-1)*hzed;
02098                                             VASSERT(Vpmg_fillArray(pmg, pmg->rwork, VDT_CHARGE, 0.0, 
02099                                                                                                       pbeparm->pbetype, pbeparm));
02100                                             sprintf(title, "CHARGE DISTRIBUTION (e)");
02101                                             break;
02102                                             
02103                                  case VDT_POT:
02104                                             
02105                                             Vnm_tprint(1, "  Writing potential to ");
02106                                             xcent = pmg->pmgp->xcent;
02107                                             ycent = pmg->pmgp->ycent;
02108                                             zcent = pmg->pmgp->zcent;
02109                                             xmin = xcent - 0.5*(nx-1)*hx;
02110                                             ymin = ycent - 0.5*(ny-1)*hy;
02111                                             zmin = zcent - 0.5*(nz-1)*hzed;
02112                                             VASSERT(Vpmg_fillArray(pmg, pmg->rwork, VDT_POT, 0.0, 
02113                                                                                                       pbeparm->pbetype, pbeparm));
02114                                             sprintf(title, "POTENTIAL (kT/e)");
02115                                             break;
02116                                             
02117                                  case VDT_SMOL:
02118                                             
02119                                             Vnm_tprint(1, "  Writing molecular accessibility to ");
02120                                             xcent = pmg->pmgp->xcent;
02121                                             ycent = pmg->pmgp->ycent;
02122                                             zcent = pmg->pmgp->zcent;
02123                                             xmin = xcent - 0.5*(nx-1)*hx;
02124                                             ymin = ycent - 0.5*(ny-1)*hy;
02125                                             zmin = zcent - 0.5*(nz-1)*hzed;
02126                                             VASSERT(Vpmg_fillArray(pmg, pmg->rwork, VDT_SMOL, 
02127                                                                                                       pbeparm->srad, pbeparm->pbetype, pbeparm));
02128                                             sprintf(title, 
02129                                                                   "SOLVENT ACCESSIBILITY -- MOLECULAR (%4.3f PROBE)", 
02130                                                                   pbeparm->srad);
02131                                             break;
02132                                             
02133                                  case VDT_SSPL:
02134                                             
02135                                             Vnm_tprint(1, "  Writing spline-based accessibility to ");
02136                                             xcent = pmg->pmgp->xcent;
02137                                             ycent = pmg->pmgp->ycent;
02138                                             zcent = pmg->pmgp->zcent;
02139                                             xmin = xcent - 0.5*(nx-1)*hx;
02140                                             ymin = ycent - 0.5*(ny-1)*hy;
02141                                             zmin = zcent - 0.5*(nz-1)*hzed;
02142                                             VASSERT(Vpmg_fillArray(pmg, pmg->rwork, VDT_SSPL,
02143                                                                                                       pbeparm->swin, pbeparm->pbetype, pbeparm));
02144                                             sprintf(title, 
02145                                                                   "SOLVENT ACCESSIBILITY -- SPLINE (%4.3f WINDOW)",
02146                                                                   pbeparm->swin);
02147                                             break;
02148                                             
02149                                  case VDT_VDW:
02150                                             
02151                                             Vnm_tprint(1, "  Writing van der Waals accessibility to ");
02152                                             xcent = pmg->pmgp->xcent;
02153                                             ycent = pmg->pmgp->ycent;
02154                                             zcent = pmg->pmgp->zcent;
02155                                             xmin = xcent - 0.5*(nx-1)*hx;
02156                                             ymin = ycent - 0.5*(ny-1)*hy;
02157                                             zmin = zcent - 0.5*(nz-1)*hzed;
02158                                             VASSERT(Vpmg_fillArray(pmg, pmg->rwork, VDT_VDW, 0.0, 
02159                                                                                                       pbeparm->pbetype, pbeparm));
02160                                             sprintf(title, "SOLVENT ACCESSIBILITY -- VAN DER WAALS");
02161                                             break;
02162                                             
02163                                  case VDT_IVDW:
02164                                             
02165                                             Vnm_tprint(1, "  Writing ion accessibility to ");
02166                                             xcent = pmg->pmgp->xcent;
02167                                             ycent = pmg->pmgp->ycent;
02168                                             zcent = pmg->pmgp->zcent;
02169                                             xmin = xcent - 0.5*(nx-1)*hx;
02170                                             ymin = ycent - 0.5*(ny-1)*hy;
02171                                             zmin = zcent - 0.5*(nz-1)*hzed;
02172                                             VASSERT(Vpmg_fillArray(pmg, pmg->rwork, VDT_IVDW, 
02173                                                                                                       pmg->pbe->maxIonRadius, pbeparm->pbetype, pbeparm));
02174                                             sprintf(title, 
02175                                                                   "ION ACCESSIBILITY -- SPLINE (%4.3f RADIUS)",
02176                                                                   pmg->pbe->maxIonRadius);
02177                                             break;
02178                                             
02179                                  case VDT_LAP:
02180                                             
02181                                             Vnm_tprint(1, "  Writing potential Laplacian to ");
02182                                             xcent = pmg->pmgp->xcent;
02183                                             ycent = pmg->pmgp->ycent;
02184                                             zcent = pmg->pmgp->zcent;
02185                                             xmin = xcent - 0.5*(nx-1)*hx;
02186                                             ymin = ycent - 0.5*(ny-1)*hy;
02187                                             zmin = zcent - 0.5*(nz-1)*hzed;
02188                                             VASSERT(Vpmg_fillArray(pmg, pmg->rwork, VDT_LAP, 0.0, 
02189                                                                                                       pbeparm->pbetype, pbeparm));
02190                                             sprintf(title, 
02191                                                                   "POTENTIAL LAPLACIAN (kT/e/A^2)");
02192                                             break;
02193                                             
02194                                  case VDT_EDENS:
02195                                             
02196                                             Vnm_tprint(1, "  Writing energy density to ");
02197                                             xcent = pmg->pmgp->xcent;
02198                                             ycent = pmg->pmgp->ycent;
02199                                             zcent = pmg->pmgp->zcent;
02200                                             xmin = xcent - 0.5*(nx-1)*hx;
02201                                             ymin = ycent - 0.5*(ny-1)*hy;
02202                                             zmin = zcent - 0.5*(nz-1)*hzed;
02203                                             VASSERT(Vpmg_fillArray(pmg, pmg->rwork, VDT_EDENS, 0.0, 
02204                                                                                                       pbeparm->pbetype, pbeparm));
02205                                             sprintf(title, "ENERGY DENSITY (kT/e/A)^2");
02206                                             break;
02207                                             
02208                                  case VDT_NDENS:
02209                                             
02210                                             Vnm_tprint(1, "  Writing number density to ");
02211                                             xcent = pmg->pmgp->xcent;
02212                                             ycent = pmg->pmgp->ycent;
02213                                             zcent = pmg->pmgp->zcent;
02214                                             xmin = xcent - 0.5*(nx-1)*hx;
02215                                             ymin = ycent - 0.5*(ny-1)*hy;
02216                                             zmin = zcent - 0.5*(nz-1)*hzed;
02217                                             VASSERT(Vpmg_fillArray(pmg, pmg->rwork, VDT_NDENS, 0.0, 
02218                                                                                                       pbeparm->pbetype, pbeparm));
02219                                             sprintf(title, 
02220                                                                   "ION NUMBER DENSITY (M)");
02221                                             break;
02222                                             
02223                                  case VDT_QDENS:
02224                                             
02225                                             Vnm_tprint(1, "  Writing charge density to ");
02226                                             xcent = pmg->pmgp->xcent;
02227                                             ycent = pmg->pmgp->ycent;
02228                                             zcent = pmg->pmgp->zcent;
02229                                             xmin = xcent - 0.5*(nx-1)*hx;
02230                                             ymin = ycent - 0.5*(ny-1)*hy;
02231                                             zmin = zcent - 0.5*(nz-1)*hzed;
02232                                             VASSERT(Vpmg_fillArray(pmg, pmg->rwork, VDT_QDENS, 0.0, 
02233                                                                                                       pbeparm->pbetype, pbeparm));
02234                                             sprintf(title, 
02235                                                                   "ION CHARGE DENSITY (e_c * M)");
02236                                             break;
02237                                             
02238                                  case VDT_DIELX:
02239                                             
02240                                             Vnm_tprint(1, "  Writing x-shifted dielectric map to ");
02241                                             xcent = pmg->pmgp->xcent + 0.5*hx;
02242                                             ycent = pmg->pmgp->ycent;
02243                                             zcent = pmg->pmgp->zcent;
02244                                             xmin = xcent - 0.5*(nx-1)*hx;
02245                                             ymin = ycent - 0.5*(ny-1)*hy;
02246                                             zmin = zcent - 0.5*(nz-1)*hzed;
02247                                             VASSERT(Vpmg_fillArray(pmg, pmg->rwork, VDT_DIELX, 0.0, 
02248                                                                                                       pbeparm->pbetype, pbeparm));
02249                                             sprintf(title,
02250                                                                   "X-SHIFTED DIELECTRIC MAP");
02251                                             break;
02252                                             
02253                                  case VDT_DIELY:
02254                                             
02255                                             Vnm_tprint(1, "  Writing y-shifted dielectric map to ");
02256                                             xcent = pmg->pmgp->xcent;
02257                                             ycent = pmg->pmgp->ycent + 0.5*hy;
02258                                             zcent = pmg->pmgp->zcent;
02259                                             xmin = xcent - 0.5*(nx-1)*hx;
02260                                             ymin = ycent - 0.5*(ny-1)*hy;
02261                                             zmin = zcent - 0.5*(nz-1)*hzed;
02262                                             VASSERT(Vpmg_fillArray(pmg, pmg->rwork, VDT_DIELY, 0.0, 
02263                                                                                                       pbeparm->pbetype, pbeparm));
02264                                             sprintf(title,
02265                                                                   "Y-SHIFTED DIELECTRIC MAP");
02266                                             break;
02267                                             
02268                                  case VDT_DIELZ:
02269                                             
02270                                             Vnm_tprint(1, "  Writing z-shifted dielectric map to ");
02271                                             xcent = pmg->pmgp->xcent;
02272                                             ycent = pmg->pmgp->ycent;
02273                                             zcent = pmg->pmgp->zcent + 0.5*hzed;
02274                                             xmin = xcent - 0.5*(nx-1)*hx;
02275                                             ymin = ycent - 0.5*(ny-1)*hy;
02276                                             zmin = zcent - 0.5*(nz-1)*hzed;
02277                                             VASSERT(Vpmg_fillArray(pmg, pmg->rwork, VDT_DIELZ, 0.0, 
02278                                                                                                       pbeparm->pbetype, pbeparm));
02279                                             sprintf(title,
02280                                                                   "Z-SHIFTED DIELECTRIC MAP");
02281                                             break;
02282                                             
02283                                  case VDT_KAPPA:
02284                                             
02285                                             Vnm_tprint(1, "  Writing kappa map to ");
02286                                             xcent = pmg->pmgp->xcent;
02287                                             ycent = pmg->pmgp->ycent;
02288                                             zcent = pmg->pmgp->zcent;
02289                                             xmin = xcent - 0.5*(nx-1)*hx;
02290                                             ymin = ycent - 0.5*(ny-1)*hy;
02291                                             zmin = zcent - 0.5*(nz-1)*hzed;
02292                                             VASSERT(Vpmg_fillArray(pmg, pmg->rwork, VDT_KAPPA, 0.0, 
02293                                                                                                       pbeparm->pbetype, pbeparm));
02294                                             sprintf(title,
02295                                                                   "KAPPA MAP");
02296                                             break;
02297                                             
02298                                  case VDT_ATOMPOT:
02299                                             
02300                                             Vnm_tprint(1, "  Writing atom potentials to ");
02301                                             xcent = pmg->pmgp->xcent;
02302                                             ycent = pmg->pmgp->ycent;
02303                                             zcent = pmg->pmgp->zcent;
02304                                             xmin = xcent - 0.5*(nx-1)*hx;
02305                                             ymin = ycent - 0.5*(ny-1)*hy;
02306                                             zmin = zcent - 0.5*(nz-1)*hzed;
02307                                             VASSERT(Vpmg_fillArray(pmg, pmg->rwork, VDT_ATOMPOT, 0.0, 
02308                                                                                                       pbeparm->pbetype, pbeparm));
02309                                             sprintf(title,
02310                                                                   "ATOM POTENTIALS");
02311                                             break;     
02312                                  default:
02313                                             
02314                                             Vnm_tprint(2, "Invalid data type for writing!\n");
02315                                             return 0;
02316                       }
02317                       
02318                       
02319 #ifdef HAVE_MPI_H
02320                       sprintf(writestem, "%s-PE%d", pbeparm->writestem[i], rank);
02321 #else
02322                       if(nosh->ispara){
02323                                  sprintf(writestem, "%s-PE%d", pbeparm->writestem[i],nosh->proc_rank);
02324                       }else{
02325                                  sprintf(writestem, "%s", pbeparm->writestem[i]);
02326                       }
02327 #endif
02328                       
02329                       switch (pbeparm->writefmt[i]) {
02330                                  
02331                                  case VDF_DX:
02332                                             sprintf(outpath, "%s.%s", writestem, "dx");
02333                                             Vnm_tprint(1, "%s\n", outpath);
02334                                             grid = Vgrid_ctor(nx, ny, nz, hx, hy, hzed, xmin, ymin, zmin,
02335                                                                                           pmg->rwork);
02336                                             Vgrid_writeDX(grid, "FILE", "ASC", VNULL, outpath, title,
02337                                                                                pmg->pvec);
02338                                             Vgrid_dtor(&grid);
02339                                             break;
02340                                             
02341                                  case VDF_AVS:
02342                                             sprintf(outpath, "%s.%s", writestem, "ucd");
02343                                             Vnm_tprint(1, "%s\n", outpath);
02344                                             Vnm_tprint(2, "Sorry, AVS format isn't supported for \
02345 uniform meshes yet!\n");
02346                                             break;
02347 
02348                                  case VDF_MCSF:
02349                                             sprintf(outpath, "%s.%s", writestem, "mcsf");
02350                                             Vnm_tprint(1, "%s\n", outpath);
02351                                             Vnm_tprint(2, "Sorry, MCSF format isn't supported for \
02352                                                                      uniform meshes yet!\n");
02353                                             break;
02354                                             
02355                                  case VDF_UHBD:
02356                                             sprintf(outpath, "%s.%s", writestem, "grd");
02357                                             Vnm_tprint(1, "%s\n", outpath);
02358                                             grid = Vgrid_ctor(nx, ny, nz, hx, hy, hzed, xmin, ymin, zmin,
02359                                                                                           pmg->rwork);
02360                                             Vgrid_writeUHBD(grid, "FILE", "ASC", VNULL, outpath, title,
02361                                                                                         pmg->pvec);
02362                                             Vgrid_dtor(&grid);
02363                                             break;
02364                                             
02365                                  case VDF_GZ:
02366                                             sprintf(outpath, "%s.%s", writestem, "dx.gz");
02367                                             Vnm_tprint(1, "%s\n", outpath);
02368                                             grid = Vgrid_ctor(nx, ny, nz, hx, hy, hzed, xmin, ymin, zmin,
02369                                                                                           pmg->rwork);
02370                                             Vgrid_writeGZ(grid, "FILE", "ASC", VNULL, outpath, title,
02371                                                                                pmg->pvec);
02372                                             Vgrid_dtor(&grid);
02373                                             break;
02374                                  case VDF_FLAT: 
02375                                             sprintf(outpath, "%s.%s", writestem, "txt");
02376                                             Vnm_tprint(1, "%s\n", outpath);
02377                                             Vnm_print(0, "routines:  Opening virtual socket...\n");
02378                                             sock = Vio_ctor("FILE","ASC",VNULL,outpath,"w");
02379                                             if (sock == VNULL) {
02380                                                        Vnm_print(2, "routines:  Problem opening virtual socket %s\n",
02381                                                                                outpath);
02382                                                        return 0;
02383                                             }
02384                                             if (Vio_connect(sock, 0) < 0) {
02385                                                        Vnm_print(2, "routines: Problem connecting virtual socket %s\n",
02386                                                                                outpath);
02387                                                        return 0; 
02388                                             }
02389                                             Vio_printf(sock, "# Data from %s\n", PACKAGE_STRING);
02390                                             Vio_printf(sock, "# \n");
02391                                             Vio_printf(sock, "# %s\n", title);
02392                                             Vio_printf(sock, "# \n");
02393                                             natoms = pmg->pbe->alist[pbeparm->molid-1].number;
02394                                             for(i=0;i<natoms;i++)
02395                                                        Vio_printf(sock, "%12.6e\n", pmg->rwork[i]);
02396                                             break;
02397                                  default:
02398                                             Vnm_tprint(2, "Bogus data format (%d)!\n", 
02399                                                                      pbeparm->writefmt[i]);
02400                                             break;
02401                       }
02402                       
02403            }
02404            
02405            return 1;
02406 }
02407 
02408 VPUBLIC double returnEnergy(Vcom *com, NOsh *nosh, double totEnergy[NOSH_MAXCALC], int iprint){
02409            
02410            int iarg, calcid;
02411            double ltenergy, scalar;
02412            
02413            calcid = nosh->elec2calc[nosh->printcalc[iprint][0]];
02414            if (nosh->calc[calcid]->pbeparm->calcenergy != PCE_NO) {
02415                       ltenergy = Vunit_kb * (1e-3) * Vunit_Na * 
02416                       nosh->calc[calcid]->pbeparm->temp * totEnergy[calcid];
02417            } else {
02418                       Vnm_tprint( 2, " No energy available in Calculation %d\n", calcid+1);
02419                       return 0.0;
02420            }
02421            for (iarg=1; iarg<nosh->printnarg[iprint]; iarg++){
02422                       calcid = nosh->elec2calc[nosh->printcalc[iprint][iarg]];
02423                       /* Add or substract */
02424                       if (nosh->printop[iprint][iarg-1] == 0) scalar = 1.0;
02425                       else if (nosh->printop[iprint][iarg-1] == 1) scalar = -1.0;
02426                       /* Accumulate */
02427                       ltenergy += (scalar * Vunit_kb * (1e-3) * Vunit_Na *
02428                                                         nosh->calc[calcid]->pbeparm->temp * totEnergy[calcid]);
02429            }
02430            
02431            return ltenergy;
02432 }
02433 
02434 VPUBLIC int printEnergy(Vcom *com, NOsh *nosh, double totEnergy[NOSH_MAXCALC], 
02435                                                                   int iprint) {
02436            
02437            int iarg, calcid;
02438            double ltenergy, gtenergy, scalar;
02439            
02440            Vnm_tprint( 2, "Warning: The 'energy' print keyword is deprecated.\n" \
02441                                                "         Use elecEnergy for electrostatics energy calcs.\n\n");
02442            
02443            if (Vstring_strcasecmp(nosh->elecname[nosh->printcalc[iprint][0]], "") == 0){
02444                       Vnm_tprint( 1, "print energy %d ", nosh->printcalc[iprint][0]+1);
02445            } else {
02446                       Vnm_tprint( 1, "print energy %d (%s) ", nosh->printcalc[iprint][0]+1, 
02447                                                        nosh->elecname[nosh->printcalc[iprint][0]]);
02448            }
02449            for (iarg=1; iarg<nosh->printnarg[iprint]; iarg++) {
02450                       if (nosh->printop[iprint][iarg-1] == 0)
02451                                  Vnm_tprint(1, "+ ");
02452                       else if (nosh->printop[iprint][iarg-1] == 1)
02453                                  Vnm_tprint(1, "- ");
02454                       else {
02455                                  Vnm_tprint( 2, "Undefined PRINT operation!\n");
02456                                  return 0;
02457                       }
02458                       if (Vstring_strcasecmp(nosh->elecname[nosh->printcalc[iprint][iarg]], 
02459                                                                                 "") == 0) {
02460                                  Vnm_tprint( 1, "%d ", nosh->printcalc[iprint][iarg]+1);
02461                       } else {
02462                                  Vnm_tprint( 1, "%d (%s) ", nosh->printcalc[iprint][iarg]+1, 
02463                                                                   nosh->elecname[nosh->printcalc[iprint][iarg]]);
02464                       }
02465            }
02466            Vnm_tprint(1, "end\n");
02467            calcid = nosh->elec2calc[nosh->printcalc[iprint][0]];
02468            if (nosh->calc[calcid]->pbeparm->calcenergy != PCE_NO) {
02469                       ltenergy = Vunit_kb * (1e-3) * Vunit_Na *
02470                       nosh->calc[calcid]->pbeparm->temp * totEnergy[calcid];
02471            } else {
02472                       Vnm_tprint( 2, "  Didn't calculate energy in Calculation \
02473 #%d\n", calcid+1);
02474                       return 0;
02475            }
02476            for (iarg=1; iarg<nosh->printnarg[iprint]; iarg++) {
02477                       calcid = nosh->elec2calc[nosh->printcalc[iprint][iarg]];
02478                       /* Add or subtract? */
02479                       if (nosh->printop[iprint][iarg-1] == 0) scalar = 1.0;
02480                       else if (nosh->printop[iprint][iarg-1] == 1) scalar = -1.0;
02481                       /* Accumulate */
02482                       ltenergy += (scalar * Vunit_kb * (1e-3) * Vunit_Na *
02483                                                         nosh->calc[calcid]->pbeparm->temp * totEnergy[calcid]);
02484            }
02485            
02486            Vnm_tprint( 1, "  Local net energy (PE %d) = %1.12E kJ/mol\n", 
02487                                             Vcom_rank(com), ltenergy);
02488            Vnm_tprint( 0, "printEnergy:  Performing global reduction (sum)\n");
02489            Vcom_reduce(com, &ltenergy, &gtenergy, 1, 2, 0);
02490            Vnm_tprint( 1, "  Global net ELEC energy = %1.12E kJ/mol\n", gtenergy);
02491            
02492            return 1;
02493            
02494 }
02495 
02496 VPUBLIC int printElecEnergy(Vcom *com, NOsh *nosh, double totEnergy[NOSH_MAXCALC], 
02497                                                                   int iprint) {
02498            
02499            int iarg, calcid;
02500            double ltenergy, gtenergy, scalar;
02501            
02502            if (Vstring_strcasecmp(nosh->elecname[nosh->printcalc[iprint][0]], "") == 0){
02503                       Vnm_tprint( 1, "\nprint energy %d ", nosh->printcalc[iprint][0]+1);
02504            } else {
02505                       Vnm_tprint( 1, "\nprint energy %d (%s) ", nosh->printcalc[iprint][0]+1, 
02506                                                        nosh->elecname[nosh->printcalc[iprint][0]]);
02507            }
02508            for (iarg=1; iarg<nosh->printnarg[iprint]; iarg++) {
02509                       if (nosh->printop[iprint][iarg-1] == 0)
02510                                  Vnm_tprint(1, "+ ");
02511                       else if (nosh->printop[iprint][iarg-1] == 1)
02512                                  Vnm_tprint(1, "- ");
02513                       else {
02514                                  Vnm_tprint( 2, "Undefined PRINT operation!\n");
02515                                  return 0;
02516                       }
02517                       if (Vstring_strcasecmp(nosh->elecname[nosh->printcalc[iprint][iarg]], 
02518                                                                                 "") == 0) {
02519                                  Vnm_tprint( 1, "%d ", nosh->printcalc[iprint][iarg]+1);
02520                       } else {
02521                                  Vnm_tprint( 1, "%d (%s) ", nosh->printcalc[iprint][iarg]+1, 
02522                                                                   nosh->elecname[nosh->printcalc[iprint][iarg]]);
02523                       }
02524            }
02525            Vnm_tprint(1, "end\n");
02526            calcid = nosh->elec2calc[nosh->printcalc[iprint][0]];
02527            if (nosh->calc[calcid]->pbeparm->calcenergy != PCE_NO) {
02528                       ltenergy = Vunit_kb * (1e-3) * Vunit_Na *
02529                       nosh->calc[calcid]->pbeparm->temp * totEnergy[calcid];
02530            } else {
02531                       Vnm_tprint( 2, "  Didn't calculate energy in Calculation \
02532 #%d\n", calcid+1);
02533                       return 0;
02534            }
02535            for (iarg=1; iarg<nosh->printnarg[iprint]; iarg++) {
02536                       calcid = nosh->elec2calc[nosh->printcalc[iprint][iarg]];
02537                       /* Add or subtract? */
02538                       if (nosh->printop[iprint][iarg-1] == 0) scalar = 1.0;
02539                       else if (nosh->printop[iprint][iarg-1] == 1) scalar = -1.0;
02540                       /* Accumulate */
02541                       ltenergy += (scalar * Vunit_kb * (1e-3) * Vunit_Na *
02542                                                         nosh->calc[calcid]->pbeparm->temp * totEnergy[calcid]);
02543            }
02544            
02545            Vnm_tprint( 1, "  Local net energy (PE %d) = %1.12E kJ/mol\n", 
02546                                             Vcom_rank(com), ltenergy);
02547            Vnm_tprint( 0, "printEnergy:  Performing global reduction (sum)\n");
02548            Vcom_reduce(com, &ltenergy, &gtenergy, 1, 2, 0);
02549            Vnm_tprint( 1, "  Global net ELEC energy = %1.12E kJ/mol\n", gtenergy);
02550            
02551            return 1;
02552            
02553 }
02554 
02555 VPUBLIC int printApolEnergy(NOsh *nosh, int iprint) {
02556            
02557            int iarg, calcid;
02558            double gtenergy, scalar;
02559            
02560            APOLparm *apolparm = VNULL;
02561            
02562            if (Vstring_strcasecmp(nosh->apolname[nosh->printcalc[iprint][0]], "") == 0){
02563                       Vnm_tprint( 1, "\nprint APOL energy %d ", nosh->printcalc[iprint][0]+1);
02564            } else {
02565                       Vnm_tprint( 1, "\nprint APOL energy %d (%s) ", nosh->printcalc[iprint][0]+1, 
02566                                                        nosh->apolname[nosh->printcalc[iprint][0]]);
02567            }
02568            for (iarg=1; iarg<nosh->printnarg[iprint]; iarg++) {
02569                       if (nosh->printop[iprint][iarg-1] == 0)
02570                                  Vnm_tprint(1, "+ ");
02571                       else if (nosh->printop[iprint][iarg-1] == 1)
02572                                  Vnm_tprint(1, "- ");
02573                       else {
02574                                  Vnm_tprint( 2, "Undefined PRINT operation!\n");
02575                                  return 0;
02576                       }
02577                       if (Vstring_strcasecmp(nosh->apolname[nosh->printcalc[iprint][iarg]], 
02578                                                                                 "") == 0) {
02579                                  Vnm_tprint( 1, "%d ", nosh->printcalc[iprint][iarg]+1);
02580                       } else {
02581                                  Vnm_tprint( 1, "%d (%s) ", nosh->printcalc[iprint][iarg]+1, 
02582                                                                   nosh->apolname[nosh->printcalc[iprint][iarg]]);
02583                       }
02584            }
02585            Vnm_tprint(1, "end\n");
02586            
02587            calcid = nosh->apol2calc[nosh->printcalc[iprint][0]];
02588            apolparm = nosh->calc[calcid]->apolparm;
02589            
02590            if (apolparm->calcenergy == ACE_TOTAL) {
02591                       gtenergy = ((apolparm->gamma*apolparm->sasa) + (apolparm->press*apolparm->sav) + (apolparm->wcaEnergy));
02592            } else {
02593                       Vnm_tprint( 2, "  Didn't calculate energy in Calculation #%d\n", calcid+1);
02594                       return 0;
02595            }
02596            for (iarg=1; iarg<nosh->printnarg[iprint]; iarg++) {
02597                       calcid = nosh->apol2calc[nosh->printcalc[iprint][iarg]];
02598                       apolparm = nosh->calc[calcid]->apolparm;
02599                       
02600                       /* Add or subtract? */
02601                       if (nosh->printop[iprint][iarg-1] == 0) scalar = 1.0;
02602                       else if (nosh->printop[iprint][iarg-1] == 1) scalar = -1.0;
02603                       /* Accumulate */
02604                       gtenergy += (scalar * ((apolparm->gamma*apolparm->sasa) +
02605                                                                                 (apolparm->press*apolparm->sav) + 
02606                                                                                 (apolparm->wcaEnergy)));
02607 
02608            }
02609            
02610            Vnm_tprint( 1, "  Global net APOL energy = %1.12E kJ/mol\n", gtenergy);
02611            return 1;
02612 }
02613 
02614 VPUBLIC int printForce(Vcom *com, NOsh *nosh, int nforce[NOSH_MAXCALC], 
02615                                                           AtomForce *atomForce[NOSH_MAXCALC], int iprint) {
02616            
02617            int iarg, ifr, ivc, calcid, refnforce, refcalcforce;
02618            double temp, scalar;
02619            double totforce[3];
02620            AtomForce *lforce, *gforce, *aforce;
02621            
02622            Vnm_tprint( 2, "Warning: The 'force' print keyword is deprecated.\n" \
02623                                                "         Use elecForce for electrostatics force calcs.\n\n");
02624            
02625            if (Vstring_strcasecmp(nosh->elecname[nosh->printcalc[iprint][0]], "") == 0){
02626                       Vnm_tprint( 1, "print force %d ", nosh->printcalc[iprint][0]+1);
02627            } else {
02628                       Vnm_tprint( 1, "print force %d (%s) ", nosh->printcalc[iprint][0]+1, 
02629                                                        nosh->elecname[nosh->printcalc[iprint][0]]);
02630            }
02631            for (iarg=1; iarg<nosh->printnarg[iprint]; iarg++) {
02632                       if (nosh->printop[iprint][iarg-1] == 0)
02633                                  Vnm_tprint(1, "+ ");
02634                       else if (nosh->printop[iprint][iarg-1] == 1)
02635                                  Vnm_tprint(1, "- ");
02636                       else {
02637                                  Vnm_tprint( 2, "Undefined PRINT operation!\n");
02638                                  return 0;
02639                       }
02640                       if (Vstring_strcasecmp(nosh->elecname[nosh->printcalc[iprint][iarg]], 
02641                                                                                 "") == 0) {
02642                                  Vnm_tprint( 1, "%d ", nosh->printcalc[iprint][iarg]+1);
02643                       } else {
02644                                  Vnm_tprint( 1, "%d (%s) ", nosh->printcalc[iprint][iarg]+1, 
02645                                                                   nosh->elecname[nosh->printcalc[iprint][iarg]]);
02646                       }
02647            }
02648            Vnm_tprint(1, "end\n");
02649            
02650            /* First, go through and make sure we did the same type of force
02651                       * evaluation in each of the requested calculations */
02652            calcid = nosh->elec2calc[nosh->printcalc[iprint][0]];
02653            refnforce = nforce[calcid];
02654            refcalcforce = nosh->calc[calcid]->pbeparm->calcforce;
02655            if (refcalcforce == PCF_NO) {
02656                       Vnm_tprint( 2, "  Didn't calculate force in calculation \
02657 #%d\n", calcid+1);
02658                       return 0;
02659            }
02660            for (iarg=1; iarg<nosh->printnarg[iprint]; iarg++) {
02661                       calcid = nosh->elec2calc[nosh->printcalc[iprint][iarg]-1];
02662                       if (nosh->calc[calcid]->pbeparm->calcforce != refcalcforce) {
02663                                  Vnm_tprint(2, "  Inconsistent calcforce declarations in \
02664 calculations %d and %d\n", nosh->elec2calc[nosh->printcalc[iprint][0]]+1,
02665                                                           calcid+1);
02666                                  return 0;
02667                       }
02668                       if (nforce[calcid] != refnforce) {
02669                                  Vnm_tprint(2, "  Inconsistent number of forces evaluated in \
02670 calculations %d and %d\n", nosh->elec2calc[nosh->printcalc[iprint][0]]+1,
02671                                                           calcid+1);
02672                                  return 0;
02673                       }
02674            }
02675            
02676            /* Now, allocate space to accumulate the forces */
02677            lforce = (AtomForce *)Vmem_malloc(VNULL, refnforce, sizeof(AtomForce));
02678            gforce = (AtomForce *)Vmem_malloc(VNULL, refnforce, sizeof(AtomForce));
02679            
02680            /* Now, accumulate the forces */
02681            calcid = nosh->elec2calc[nosh->printcalc[iprint][0]];
02682            aforce = atomForce[calcid];
02683            temp = nosh->calc[calcid]->pbeparm->temp;
02684            
02685            /* Load up the first calculation */
02686            if (refcalcforce == PCF_TOTAL) {
02687                       /* Set to total force */
02688                       for (ivc=0; ivc<3; ivc++) {
02689                                  lforce[0].qfForce[ivc] = 
02690                                  Vunit_kb*(1e-3)*Vunit_Na*temp*aforce[0].qfForce[ivc];
02691                                  lforce[0].ibForce[ivc] = 
02692                                             Vunit_kb*(1e-3)*Vunit_Na*temp*aforce[0].ibForce[ivc];
02693                                  lforce[0].dbForce[ivc] = 
02694                                             Vunit_kb*(1e-3)*Vunit_Na*temp*aforce[0].dbForce[ivc];
02695                       }
02696            } else if (refcalcforce == PCF_COMPS) { 
02697                       for (ifr=0; ifr<refnforce; ifr++) {
02698                                  for (ivc=0; ivc<3; ivc++) {
02699                                             lforce[ifr].qfForce[ivc] = 
02700                                             Vunit_kb*(1e-3)*Vunit_Na*temp*aforce[ifr].qfForce[ivc];
02701                                             lforce[ifr].ibForce[ivc] = 
02702                                                        Vunit_kb*(1e-3)*Vunit_Na*temp*aforce[ifr].ibForce[ivc];
02703                                             lforce[ifr].dbForce[ivc] = 
02704                                                        Vunit_kb*(1e-3)*Vunit_Na*temp*aforce[ifr].dbForce[ivc];
02705                                  }
02706                       }
02707            }
02708            
02709            /* Load up the rest of the calculations */
02710            for (iarg=1; iarg<nosh->printnarg[iprint]; iarg++) {
02711                       calcid = nosh->elec2calc[nosh->printcalc[iprint][iarg]];
02712                       temp = nosh->calc[calcid]->pbeparm->temp;
02713                       aforce = atomForce[calcid];
02714                       /* Get operation */
02715                       if (nosh->printop[iprint][iarg-1] == 0) scalar = +1.0;
02716                       else if (nosh->printop[iprint][iarg-1] == 1) scalar = -1.0;
02717                       else scalar = 0.0;
02718                       /* Accumulate */
02719                       if (refcalcforce == PCF_TOTAL) {
02720                                  /* Set to total force */
02721                                  for (ivc=0; ivc<3; ivc++) {
02722                                             lforce[0].qfForce[ivc] += 
02723                                             (scalar*Vunit_kb*(1e-3)*Vunit_Na*temp*aforce[0].qfForce[ivc]);
02724                                             lforce[0].ibForce[ivc] += 
02725                                                        (scalar*Vunit_kb*(1e-3)*Vunit_Na*temp*aforce[0].ibForce[ivc]);
02726                                             lforce[0].dbForce[ivc] += 
02727                                                        (scalar*Vunit_kb*(1e-3)*Vunit_Na*temp*aforce[0].dbForce[ivc]);
02728                                  }
02729                       } else if (refcalcforce == PCF_COMPS) {
02730                                  for (ifr=0; ifr<refnforce; ifr++) {
02731                                             for (ivc=0; ivc<3; ivc++) {
02732                                                        lforce[ifr].qfForce[ivc] += 
02733                                                        (scalar*Vunit_kb*(1e-3)*Vunit_Na*temp*aforce[ifr].qfForce[ivc]);
02734                                                        lforce[ifr].ibForce[ivc] += 
02735                                                                   (scalar*Vunit_kb*(1e-3)*Vunit_Na*temp*aforce[ifr].ibForce[ivc]);
02736                                                        lforce[ifr].dbForce[ivc] += 
02737                                                                   (scalar*Vunit_kb*(1e-3)*Vunit_Na*temp*aforce[ifr].dbForce[ivc]);
02738                                             }
02739                                  }
02740                       }
02741            }
02742            
02743            Vnm_tprint( 0, "printEnergy:  Performing global reduction (sum)\n");
02744            for (ifr=0; ifr<refnforce; ifr++) {
02745                       Vcom_reduce(com, lforce[ifr].qfForce, gforce[ifr].qfForce, 3, 2, 0);
02746                       Vcom_reduce(com, lforce[ifr].ibForce, gforce[ifr].ibForce, 3, 2, 0);
02747                       Vcom_reduce(com, lforce[ifr].dbForce, gforce[ifr].dbForce, 3, 2, 0);
02748            }
02749            
02750 #if 0
02751            if (refcalcforce == PCF_TOTAL) {
02752                       Vnm_tprint( 1, "  Local net fixed charge force = \
02753 (%1.12E, %1.12E, %1.12E) kJ/mol/A\n", lforce[0].qfForce[0],
02754                                                        lforce[0].qfForce[1], lforce[0].qfForce[2]);
02755                       Vnm_tprint( 1, "  Local net ionic boundary force = \
02756 (%1.12E, %1.12E, %1.12E) kJ/mol/A\n", lforce[0].ibForce[0],
02757                                                        lforce[0].ibForce[1], lforce[0].ibForce[2]);
02758                       Vnm_tprint( 1, "  Local net dielectric boundary force = \
02759 (%1.12E, %1.12E, %1.12E) kJ/mol/A\n", lforce[0].dbForce[0],
02760                                                        lforce[0].dbForce[1], lforce[0].dbForce[2]);
02761            } else if (refcalcforce == PCF_COMPS) {
02762                       for (ifr=0; ifr<refnforce; ifr++) {
02763                                  Vnm_tprint( 1, "  Local fixed charge force \
02764 (atom %d) = (%1.12E, %1.12E, %1.12E) kJ/mol/A\n", ifr, lforce[ifr].qfForce[0],
02765                                                                   lforce[ifr].qfForce[1], lforce[ifr].qfForce[2]);
02766                                  Vnm_tprint( 1, "  Local ionic boundary force \
02767 (atom %d) = (%1.12E, %1.12E, %1.12E) kJ/mol/A\n", ifr, lforce[ifr].ibForce[0],
02768                                                                   lforce[ifr].ibForce[1], lforce[ifr].ibForce[2]);
02769                                  Vnm_tprint( 1, "  Local dielectric boundary force \
02770 (atom %d) = (%1.12E, %1.12E, %1.12E) kJ/mol/A\n", ifr, lforce[ifr].dbForce[0],
02771                                                                   lforce[ifr].dbForce[1], lforce[ifr].dbForce[2]);
02772                       }
02773            }
02774 #endif
02775            
02776            if (refcalcforce == PCF_TOTAL) {
02777                       Vnm_tprint( 1, "  Printing net forces (kJ/mol/A).\n");
02778                       Vnm_tprint( 1, "  Legend:\n");
02779                       Vnm_tprint( 1, "    tot -- Total force\n");
02780                       Vnm_tprint( 1, "    qf  -- Fixed charge force\n");
02781                       Vnm_tprint( 1, "    db  -- Dielectric boundary force\n");
02782                       Vnm_tprint( 1, "    ib  -- Ionic boundary force\n");
02783                       
02784                       for (ivc=0; ivc<3; ivc++) {
02785                                  totforce[ivc] = 
02786                                  gforce[0].qfForce[ivc] + gforce[0].ibForce[ivc] \
02787                                  + gforce[0].dbForce[ivc];
02788                       }
02789                       
02790                       Vnm_tprint( 1, "  tot %1.12E  %1.12E  %1.12E\n", totforce[0], 
02791                                                        totforce[1], totforce[2]);
02792                       Vnm_tprint( 1, "  qf  %1.12E  %1.12E  %1.12E\n", gforce[0].qfForce[0], 
02793                                                        gforce[0].qfForce[1], gforce[0].qfForce[2]);
02794                       Vnm_tprint( 1, "  ib  %1.12E  %1.12E  %1.12E\n", gforce[0].ibForce[0], 
02795                                                        gforce[0].ibForce[1], gforce[0].ibForce[2]);
02796                       Vnm_tprint( 1, "  db  %1.12E  %1.12E  %1.12E\n", gforce[0].dbForce[0], 
02797                                                        gforce[0].dbForce[1], gforce[0].dbForce[2]);
02798                       
02799            } else if (refcalcforce == PCF_COMPS) {
02800                       
02801                       Vnm_tprint( 1, "  Printing per-atom forces (kJ/mol/A).\n");
02802                       Vnm_tprint( 1, "  Legend:\n");
02803                       Vnm_tprint( 1, "    tot n -- Total force for atom n\n");
02804                       Vnm_tprint( 1, "    qf  n -- Fixed charge force for atom n\n");
02805                       Vnm_tprint( 1, "    db  n -- Dielectric boundary force for atom n\n");
02806                       Vnm_tprint( 1, "    ib  n -- Ionic boundary force for atom n\n");
02807                       Vnm_tprint( 1, "    tot all -- Total force for system\n");
02808                       
02809                       totforce[0] = 0.0;
02810                       totforce[1] = 0.0;
02811                       totforce[2] = 0.0;
02812                       
02813                       for (ifr=0; ifr<refnforce; ifr++) {
02814                                  Vnm_tprint( 1, "  qf  %d  %1.12E  %1.12E  %1.12E\n", ifr, 
02815                                                                   gforce[ifr].qfForce[0], gforce[ifr].qfForce[1], 
02816                                                                   gforce[ifr].qfForce[2]);
02817                                  Vnm_tprint( 1, "  ib  %d  %1.12E  %1.12E  %1.12E\n", ifr, 
02818                                                                   gforce[ifr].ibForce[0], gforce[ifr].ibForce[1],
02819                                                                   gforce[ifr].ibForce[2]);
02820                                  Vnm_tprint( 1, "  db  %d  %1.12E  %1.12E  %1.12E\n", ifr, 
02821                                                                   gforce[ifr].dbForce[0], gforce[ifr].dbForce[1], 
02822                                                                   gforce[ifr].dbForce[2]);
02823                                  Vnm_tprint( 1, "  tot %d  %1.12E  %1.12E  %1.12E\n", ifr, 
02824                                                                   (gforce[ifr].dbForce[0] \
02825                                                                    + gforce[ifr].ibForce[0] +
02826                                                                    gforce[ifr].qfForce[0]),
02827                                                                   (gforce[ifr].dbForce[1] \
02828                                                                    + gforce[ifr].ibForce[1] +
02829                                                                    gforce[ifr].qfForce[1]),
02830                                                                   (gforce[ifr].dbForce[2] \
02831                                                                    + gforce[ifr].ibForce[2] +
02832                                                                    gforce[ifr].qfForce[2]));
02833                                  for (ivc=0; ivc<3; ivc++) {
02834                                             totforce[ivc] += (gforce[ifr].dbForce[ivc] \
02835                                                                                         + gforce[ifr].ibForce[ivc] \
02836                                                                                           + gforce[ifr].qfForce[ivc]);
02837                                  }
02838                       }
02839                       Vnm_tprint( 1, "  tot all %1.12E  %1.12E  %1.12E\n", totforce[0],
02840                                                        totforce[1], totforce[2]);
02841            }
02842            
02843            Vmem_free(VNULL, refnforce, sizeof(AtomForce), (void **)(&lforce));
02844            Vmem_free(VNULL, refnforce, sizeof(AtomForce), (void **)(&gforce));
02845            
02846            return 1;
02847            
02848 }
02849 
02850 VPUBLIC int printElecForce(Vcom *com, NOsh *nosh, int nforce[NOSH_MAXCALC], 
02851                                                           AtomForce *atomForce[NOSH_MAXCALC], int iprint) {
02852            
02853            int iarg, ifr, ivc, calcid, refnforce, refcalcforce;
02854            double temp, scalar;
02855            double totforce[3];
02856            AtomForce *lforce, *gforce, *aforce;
02857            
02858            if (Vstring_strcasecmp(nosh->elecname[nosh->printcalc[iprint][0]], "") == 0){
02859                       Vnm_tprint( 1, "print force %d ", nosh->printcalc[iprint][0]+1);
02860            } else {
02861                       Vnm_tprint( 1, "print force %d (%s) ", nosh->printcalc[iprint][0]+1, 
02862                                                        nosh->elecname[nosh->printcalc[iprint][0]]);
02863            }
02864            for (iarg=1; iarg<nosh->printnarg[iprint]; iarg++) {
02865                       if (nosh->printop[iprint][iarg-1] == 0)
02866                                  Vnm_tprint(1, "+ ");
02867                       else if (nosh->printop[iprint][iarg-1] == 1)
02868                                  Vnm_tprint(1, "- ");
02869                       else {
02870                                  Vnm_tprint( 2, "Undefined PRINT operation!\n");
02871                                  return 0;
02872                       }
02873                       if (Vstring_strcasecmp(nosh->elecname[nosh->printcalc[iprint][iarg]], 
02874                                                                                 "") == 0) {
02875                                  Vnm_tprint( 1, "%d ", nosh->printcalc[iprint][iarg]+1);
02876                       } else {
02877                                  Vnm_tprint( 1, "%d (%s) ", nosh->printcalc[iprint][iarg]+1, 
02878                                                                   nosh->elecname[nosh->printcalc[iprint][iarg]]);
02879                       }
02880            }
02881            Vnm_tprint(1, "end\n");
02882            
02883            /* First, go through and make sure we did the same type of force
02884                       * evaluation in each of the requested calculations */
02885            calcid = nosh->elec2calc[nosh->printcalc[iprint][0]];
02886            refnforce = nforce[calcid];
02887            refcalcforce = nosh->calc[calcid]->pbeparm->calcforce;
02888            if (refcalcforce == PCF_NO) {
02889                       Vnm_tprint( 2, "  Didn't calculate force in calculation \
02890 #%d\n", calcid+1);
02891                       return 0;
02892            }
02893            for (iarg=1; iarg<nosh->printnarg[iprint]; iarg++) {
02894                       calcid = nosh->elec2calc[nosh->printcalc[iprint][iarg]-1];
02895                       if (nosh->calc[calcid]->pbeparm->calcforce != refcalcforce) {
02896                                  Vnm_tprint(2, "  Inconsistent calcforce declarations in \
02897 calculations %d and %d\n", nosh->elec2calc[nosh->printcalc[iprint][0]]+1,
02898                                                           calcid+1);
02899                                  return 0;
02900                       }
02901                       if (nforce[calcid] != refnforce) {
02902                                  Vnm_tprint(2, "  Inconsistent number of forces evaluated in \
02903 calculations %d and %d\n", nosh->elec2calc[nosh->printcalc[iprint][0]]+1,
02904                                                           calcid+1);
02905                                  return 0;
02906                       }
02907            }
02908            
02909            /* Now, allocate space to accumulate the forces */
02910            lforce = (AtomForce *)Vmem_malloc(VNULL, refnforce, sizeof(AtomForce));
02911            gforce = (AtomForce *)Vmem_malloc(VNULL, refnforce, sizeof(AtomForce));
02912            
02913            /* Now, accumulate the forces */
02914            calcid = nosh->elec2calc[nosh->printcalc[iprint][0]];
02915            aforce = atomForce[calcid];
02916            temp = nosh->calc[calcid]->pbeparm->temp;
02917            
02918            /* Load up the first calculation */
02919            if (refcalcforce == PCF_TOTAL) {
02920                       /* Set to total force */
02921                       for (ivc=0; ivc<3; ivc++) {
02922                                  lforce[0].qfForce[ivc] = 
02923                                  Vunit_kb*(1e-3)*Vunit_Na*temp*aforce[0].qfForce[ivc];
02924                                  lforce[0].ibForce[ivc] = 
02925                                             Vunit_kb*(1e-3)*Vunit_Na*temp*aforce[0].ibForce[ivc];
02926                                  lforce[0].dbForce[ivc] = 
02927                                             Vunit_kb*(1e-3)*Vunit_Na*temp*aforce[0].dbForce[ivc];
02928                       }
02929            } else if (refcalcforce == PCF_COMPS) { 
02930                       for (ifr=0; ifr<refnforce; ifr++) {
02931                                  for (ivc=0; ivc<3; ivc++) {
02932                                             lforce[ifr].qfForce[ivc] = 
02933                                             Vunit_kb*(1e-3)*Vunit_Na*temp*aforce[ifr].qfForce[ivc];
02934                                             lforce[ifr].ibForce[ivc] = 
02935                                                        Vunit_kb*(1e-3)*Vunit_Na*temp*aforce[ifr].ibForce[ivc];
02936                                             lforce[ifr].dbForce[ivc] = 
02937                                                        Vunit_kb*(1e-3)*Vunit_Na*temp*aforce[ifr].dbForce[ivc];
02938                                  }
02939                       }
02940            }
02941            
02942            /* Load up the rest of the calculations */
02943            for (iarg=1; iarg<nosh->printnarg[iprint]; iarg++) {
02944                       calcid = nosh->elec2calc[nosh->printcalc[iprint][iarg]];
02945                       temp = nosh->calc[calcid]->pbeparm->temp;
02946                       aforce = atomForce[calcid];
02947                       /* Get operation */
02948                       if (nosh->printop[iprint][iarg-1] == 0) scalar = +1.0;
02949                       else if (nosh->printop[iprint][iarg-1] == 1) scalar = -1.0;
02950                       else scalar = 0.0;
02951                       /* Accumulate */
02952                       if (refcalcforce == PCF_TOTAL) {
02953                                  /* Set to total force */
02954                                  for (ivc=0; ivc<3; ivc++) {
02955                                             lforce[0].qfForce[ivc] += 
02956                                             (scalar*Vunit_kb*(1e-3)*Vunit_Na*temp*aforce[0].qfForce[ivc]);
02957                                             lforce[0].ibForce[ivc] += 
02958                                                        (scalar*Vunit_kb*(1e-3)*Vunit_Na*temp*aforce[0].ibForce[ivc]);
02959                                             lforce[0].dbForce[ivc] += 
02960                                                        (scalar*Vunit_kb*(1e-3)*Vunit_Na*temp*aforce[0].dbForce[ivc]);
02961                                  }
02962                       } else if (refcalcforce == PCF_COMPS) {
02963                                  for (ifr=0; ifr<refnforce; ifr++) {
02964                                             for (ivc=0; ivc<3; ivc++) {
02965                                                        lforce[ifr].qfForce[ivc] += 
02966                                                        (scalar*Vunit_kb*(1e-3)*Vunit_Na*temp*aforce[ifr].qfForce[ivc]);
02967                                                        lforce[ifr].ibForce[ivc] += 
02968                                                                   (scalar*Vunit_kb*(1e-3)*Vunit_Na*temp*aforce[ifr].ibForce[ivc]);
02969                                                        lforce[ifr].dbForce[ivc] += 
02970                                                                   (scalar*Vunit_kb*(1e-3)*Vunit_Na*temp*aforce[ifr].dbForce[ivc]);
02971                                             }
02972                                  }
02973                       }
02974            }
02975            
02976            Vnm_tprint( 0, "printEnergy:  Performing global reduction (sum)\n");
02977            for (ifr=0; ifr<refnforce; ifr++) {
02978                       Vcom_reduce(com, lforce[ifr].qfForce, gforce[ifr].qfForce, 3, 2, 0);
02979                       Vcom_reduce(com, lforce[ifr].ibForce, gforce[ifr].ibForce, 3, 2, 0);
02980                       Vcom_reduce(com, lforce[ifr].dbForce, gforce[ifr].dbForce, 3, 2, 0);
02981            }
02982            
02983 #if 0
02984            if (refcalcforce == PCF_TOTAL) {
02985                       Vnm_tprint( 1, "  Local net fixed charge force = \
02986 (%1.12E, %1.12E, %1.12E) kJ/mol/A\n", lforce[0].qfForce[0],
02987                                                        lforce[0].qfForce[1], lforce[0].qfForce[2]);
02988                       Vnm_tprint( 1, "  Local net ionic boundary force = \
02989 (%1.12E, %1.12E, %1.12E) kJ/mol/A\n", lforce[0].ibForce[0],
02990                                                        lforce[0].ibForce[1], lforce[0].ibForce[2]);
02991                       Vnm_tprint( 1, "  Local net dielectric boundary force = \
02992 (%1.12E, %1.12E, %1.12E) kJ/mol/A\n", lforce[0].dbForce[0],
02993                                                        lforce[0].dbForce[1], lforce[0].dbForce[2]);
02994            } else if (refcalcforce == PCF_COMPS) {
02995                       for (ifr=0; ifr<refnforce; ifr++) {
02996                                  Vnm_tprint( 1, "  Local fixed charge force \
02997 (atom %d) = (%1.12E, %1.12E, %1.12E) kJ/mol/A\n", ifr, lforce[ifr].qfForce[0],
02998                                                                   lforce[ifr].qfForce[1], lforce[ifr].qfForce[2]);
02999                                  Vnm_tprint( 1, "  Local ionic boundary force \
03000 (atom %d) = (%1.12E, %1.12E, %1.12E) kJ/mol/A\n", ifr, lforce[ifr].ibForce[0],
03001                                                                   lforce[ifr].ibForce[1], lforce[ifr].ibForce[2]);
03002                                  Vnm_tprint( 1, "  Local dielectric boundary force \
03003 (atom %d) = (%1.12E, %1.12E, %1.12E) kJ/mol/A\n", ifr, lforce[ifr].dbForce[0],
03004                                                                   lforce[ifr].dbForce[1], lforce[ifr].dbForce[2]);
03005                       }
03006            }
03007 #endif
03008            
03009            if (refcalcforce == PCF_TOTAL) {
03010                       Vnm_tprint( 1, "  Printing net forces (kJ/mol/A).\n");
03011                       Vnm_tprint( 1, "  Legend:\n");
03012                       Vnm_tprint( 1, "    tot -- Total force\n");
03013                       Vnm_tprint( 1, "    qf  -- Fixed charge force\n");
03014                       Vnm_tprint( 1, "    db  -- Dielectric boundary force\n");
03015                       Vnm_tprint( 1, "    ib  -- Ionic boundary force\n");
03016                       
03017                       for (ivc=0; ivc<3; ivc++) {
03018                                  totforce[ivc] = 
03019                                  gforce[0].qfForce[ivc] + gforce[0].ibForce[ivc] \
03020                                  + gforce[0].dbForce[ivc];
03021                       }
03022                       
03023                       Vnm_tprint( 1, "  tot %1.12E  %1.12E  %1.12E\n", totforce[0], 
03024                                                        totforce[1], totforce[2]);
03025                       Vnm_tprint( 1, "  qf  %1.12E  %1.12E  %1.12E\n", gforce[0].qfForce[0], 
03026                                                        gforce[0].qfForce[1], gforce[0].qfForce[2]);
03027                       Vnm_tprint( 1, "  ib  %1.12E  %1.12E  %1.12E\n", gforce[0].ibForce[0], 
03028                                                        gforce[0].ibForce[1], gforce[0].ibForce[2]);
03029                       Vnm_tprint( 1, "  db  %1.12E  %1.12E  %1.12E\n", gforce[0].dbForce[0], 
03030                                                        gforce[0].dbForce[1], gforce[0].dbForce[2]);
03031                       
03032            } else if (refcalcforce == PCF_COMPS) {
03033                       
03034                       Vnm_tprint( 1, "  Printing per-atom forces (kJ/mol/A).\n");
03035                       Vnm_tprint( 1, "  Legend:\n");
03036                       Vnm_tprint( 1, "    tot n -- Total force for atom n\n");
03037                       Vnm_tprint( 1, "    qf  n -- Fixed charge force for atom n\n");
03038                       Vnm_tprint( 1, "    db  n -- Dielectric boundary force for atom n\n");
03039                       Vnm_tprint( 1, "    ib  n -- Ionic boundary force for atom n\n");
03040                       Vnm_tprint( 1, "    tot all -- Total force for system\n");
03041                       
03042                       totforce[0] = 0.0;
03043                       totforce[1] = 0.0;
03044                       totforce[2] = 0.0;
03045                       
03046                       for (ifr=0; ifr<refnforce; ifr++) {
03047                                  Vnm_tprint( 1, "  qf  %d  %1.12E  %1.12E  %1.12E\n", ifr, 
03048                                                                   gforce[ifr].qfForce[0], gforce[ifr].qfForce[1], 
03049                                                                   gforce[ifr].qfForce[2]);
03050                                  Vnm_tprint( 1, "  ib  %d  %1.12E  %1.12E  %1.12E\n", ifr, 
03051                                                                   gforce[ifr].ibForce[0], gforce[ifr].ibForce[1],
03052                                                                   gforce[ifr].ibForce[2]);
03053                                  Vnm_tprint( 1, "  db  %d  %1.12E  %1.12E  %1.12E\n", ifr, 
03054                                                                   gforce[ifr].dbForce[0], gforce[ifr].dbForce[1], 
03055                                                                   gforce[ifr].dbForce[2]);
03056                                  Vnm_tprint( 1, "  tot %d  %1.12E  %1.12E  %1.12E\n", ifr, 
03057                                                                   (gforce[ifr].dbForce[0] \
03058                                                                    + gforce[ifr].ibForce[0] +
03059                                                                    gforce[ifr].qfForce[0]),
03060                                                                   (gforce[ifr].dbForce[1] \
03061                                                                    + gforce[ifr].ibForce[1] +
03062                                                                    gforce[ifr].qfForce[1]),
03063                                                                   (gforce[ifr].dbForce[2] \
03064                                                                    + gforce[ifr].ibForce[2] +
03065                                                                    gforce[ifr].qfForce[2]));
03066                                  for (ivc=0; ivc<3; ivc++) {
03067                                             totforce[ivc] += (gforce[ifr].dbForce[ivc] \
03068                                                                                         + gforce[ifr].ibForce[ivc] \
03069                                                                                           + gforce[ifr].qfForce[ivc]);
03070                                  }
03071                       }
03072                       Vnm_tprint( 1, "  tot all %1.12E  %1.12E  %1.12E\n", totforce[0],
03073                                                        totforce[1], totforce[2]);
03074            }
03075            
03076            Vmem_free(VNULL, refnforce, sizeof(AtomForce), (void **)(&lforce));
03077            Vmem_free(VNULL, refnforce, sizeof(AtomForce), (void **)(&gforce));
03078            
03079            return 1;
03080            
03081 }
03082 
03083 VPUBLIC int printApolForce(Vcom *com, NOsh *nosh, int nforce[NOSH_MAXCALC], 
03084                                                                      AtomForce *atomForce[NOSH_MAXCALC], int iprint) {
03085            
03086            int iarg, ifr, ivc, calcid, refnforce, refcalcforce;
03087            double temp, scalar;
03088            double totforce[3];
03089            AtomForce *lforce, *gforce, *aforce;
03090            
03091            if (Vstring_strcasecmp(nosh->apolname[nosh->printcalc[iprint][0]], "") == 0){
03092                       Vnm_tprint( 1, "\nprint APOL force %d ", nosh->printcalc[iprint][0]+1);
03093            } else {
03094                       Vnm_tprint( 1, "\nprint APOL force %d (%s) ", nosh->printcalc[iprint][0]+1, 
03095                                                        nosh->apolname[nosh->printcalc[iprint][0]]);
03096            }
03097            for (iarg=1; iarg<nosh->printnarg[iprint]; iarg++) {
03098                       if (nosh->printop[iprint][iarg-1] == 0)
03099                                  Vnm_tprint(1, "+ ");
03100                       else if (nosh->printop[iprint][iarg-1] == 1)
03101                                  Vnm_tprint(1, "- ");
03102                       else {
03103                                  Vnm_tprint( 2, "Undefined PRINT operation!\n");
03104                                  return 0;
03105                       }
03106                       if (Vstring_strcasecmp(nosh->apolname[nosh->printcalc[iprint][iarg]], 
03107                                                                                 "") == 0) {
03108                                  Vnm_tprint( 1, "%d ", nosh->printcalc[iprint][iarg]+1);
03109                       } else {
03110                                  Vnm_tprint( 1, "%d (%s) ", nosh->printcalc[iprint][iarg]+1, 
03111                                                                   nosh->apolname[nosh->printcalc[iprint][iarg]]);
03112                       }
03113            }
03114            Vnm_tprint(1, "end\n");
03115            
03116            /* First, go through and make sure we did the same type of force
03117                       * evaluation in each of the requested calculations */
03118            calcid = nosh->apol2calc[nosh->printcalc[iprint][0]];
03119            refnforce = nforce[calcid];
03120            refcalcforce = nosh->calc[calcid]->apolparm->calcforce;
03121            if (refcalcforce == ACF_NO) {
03122                       Vnm_tprint( 2, "  Didn't calculate force in calculation \
03123 #%d\n", calcid+1);
03124                       return 0;
03125            }
03126            for (iarg=1; iarg<nosh->printnarg[iprint]; iarg++) {
03127                       calcid = nosh->apol2calc[nosh->printcalc[iprint][iarg]-1];
03128                       if (nosh->calc[calcid]->apolparm->calcforce != refcalcforce) {
03129                                  Vnm_tprint(2, "  Inconsistent calcforce declarations in \
03130 calculations %d and %d\n", nosh->apol2calc[nosh->printcalc[iprint][0]]+1,
03131                                                           calcid+1);
03132                                  return 0;
03133                       }
03134                       if (nforce[calcid] != refnforce) {
03135                                  Vnm_tprint(2, "  Inconsistent number of forces evaluated in \
03136 calculations %d and %d\n", nosh->apol2calc[nosh->printcalc[iprint][0]]+1,
03137                                                           calcid+1);
03138                                  return 0;
03139                       }
03140            }
03141            
03142            /* Now, allocate space to accumulate the forces */
03143            lforce = (AtomForce *)Vmem_malloc(VNULL, refnforce, sizeof(AtomForce));
03144            gforce = (AtomForce *)Vmem_malloc(VNULL, refnforce, sizeof(AtomForce));
03145            
03146            /* Now, accumulate the forces */
03147            calcid = nosh->apol2calc[nosh->printcalc[iprint][0]];
03148            aforce = atomForce[calcid];
03149            temp = nosh->calc[calcid]->apolparm->temp;
03150            
03151            /* Load up the first calculation */
03152            if (refcalcforce == ACF_TOTAL) {
03153                       /* Set to total force */
03154                       for (ivc=0; ivc<3; ivc++) {
03155                                  lforce[0].sasaForce[ivc] = aforce[0].sasaForce[ivc];
03156                                  lforce[0].savForce[ivc] = aforce[0].savForce[ivc];
03157                                  lforce[0].wcaForce[ivc] = aforce[0].wcaForce[ivc];
03158                       }
03159            } else if (refcalcforce == ACF_COMPS) { 
03160                       for (ifr=0; ifr<refnforce; ifr++) {
03161                                  for (ivc=0; ivc<3; ivc++) {
03162                                             lforce[ifr].sasaForce[ivc] = aforce[ifr].sasaForce[ivc];
03163                                             lforce[ifr].savForce[ivc] = aforce[ifr].savForce[ivc];
03164                                             lforce[ifr].wcaForce[ivc] = aforce[ifr].wcaForce[ivc];
03165                                  }
03166                       }
03167            }
03168            
03169            /* Load up the rest of the calculations */
03170            for (iarg=1; iarg<nosh->printnarg[iprint]; iarg++) {
03171                       calcid = nosh->apol2calc[nosh->printcalc[iprint][iarg]];
03172                       temp = nosh->calc[calcid]->apolparm->temp;
03173                       aforce = atomForce[calcid];
03174                       /* Get operation */
03175                       if (nosh->printop[iprint][iarg-1] == 0) scalar = +1.0;
03176                       else if (nosh->printop[iprint][iarg-1] == 1) scalar = -1.0;
03177                       else scalar = 0.0;
03178                       /* Accumulate */
03179                       if (refcalcforce == ACF_TOTAL) {
03180                                  /* Set to total force */
03181                                  for (ivc=0; ivc<3; ivc++) {
03182                                             lforce[0].sasaForce[ivc] += aforce[0].sasaForce[ivc];
03183                                             lforce[0].savForce[ivc] += aforce[0].savForce[ivc];
03184                                             lforce[0].wcaForce[ivc] += aforce[0].wcaForce[ivc];
03185                                  }
03186                       } else if (refcalcforce == ACF_COMPS) {
03187                                  for (ifr=0; ifr<refnforce; ifr++) {
03188                                             for (ivc=0; ivc<3; ivc++) {
03189                                                        lforce[ifr].sasaForce[ivc] += aforce[ifr].sasaForce[ivc];
03190                                                        lforce[ifr].savForce[ivc] += aforce[ifr].savForce[ivc];
03191                                                        lforce[ifr].wcaForce[ivc] += aforce[ifr].wcaForce[ivc];
03192                                             }
03193                                  }
03194                       }
03195            }
03196            
03197            Vnm_tprint( 0, "printForce:  Performing global reduction (sum)\n");
03198            for (ifr=0; ifr<refnforce; ifr++) {
03199                       Vcom_reduce(com, lforce[ifr].sasaForce, gforce[ifr].sasaForce, 3, 2, 0);
03200                       Vcom_reduce(com, lforce[ifr].savForce, gforce[ifr].savForce, 3, 2, 0);
03201                       Vcom_reduce(com, lforce[ifr].wcaForce, gforce[ifr].wcaForce, 3, 2, 0);
03202            }
03203            
03204            if (refcalcforce == ACF_TOTAL) {
03205                       Vnm_tprint( 1, "  Printing net forces (kJ/mol/A)\n");
03206                       Vnm_tprint( 1, "  Legend:\n");
03207                       Vnm_tprint( 1, "    tot   -- Total force\n");
03208                       Vnm_tprint( 1, "    sasa  -- SASA force\n");
03209                       Vnm_tprint( 1, "    sav   -- SAV force\n");
03210                       Vnm_tprint( 1, "    wca   -- WCA force\n\n");
03211                       
03212                       for (ivc=0; ivc<3; ivc++) {
03213                                  totforce[ivc] = 
03214                                  gforce[0].sasaForce[ivc] + gforce[0].savForce[ivc] \
03215                                  + gforce[0].wcaForce[ivc];
03216                       }
03217                       
03218                       Vnm_tprint( 1, "  tot %1.12E  %1.12E  %1.12E\n", totforce[0], 
03219                                                        totforce[1], totforce[2]);
03220                       Vnm_tprint( 1, "  sasa  %1.12E  %1.12E  %1.12E\n", gforce[0].sasaForce[0], 
03221                                                        gforce[0].sasaForce[1], gforce[0].sasaForce[2]);
03222                       Vnm_tprint( 1, "  sav  %1.12E  %1.12E  %1.12E\n", gforce[0].savForce[0], 
03223                                                        gforce[0].savForce[1], gforce[0].savForce[2]);
03224                       Vnm_tprint( 1, "  wca  %1.12E  %1.12E  %1.12E\n", gforce[0].wcaForce[0], 
03225                                                        gforce[0].wcaForce[1], gforce[0].wcaForce[2]);
03226                       
03227            } else if (refcalcforce == ACF_COMPS) {
03228                       
03229                       Vnm_tprint( 1, "  Printing per atom forces (kJ/mol/A)\n");
03230                       Vnm_tprint( 1, "  Legend:\n");
03231                       Vnm_tprint( 1, "    tot   n -- Total force for atom n\n");
03232                       Vnm_tprint( 1, "    sasa  n -- SASA force for atom n\n");
03233                       Vnm_tprint( 1, "    sav   n -- SAV force for atom n\n");
03234                       Vnm_tprint( 1, "    wca   n -- WCA force for atom n\n");
03235                       Vnm_tprint( 1, "    tot all -- Total force for system\n");
03236                       
03237                       //Vnm_tprint( 1, "    gamma, pressure, bconc are: %f %f %f\n\n",
03238                       //                               gamma,press,bconc);
03239                       
03240                       totforce[0] = 0.0;
03241                       totforce[1] = 0.0;
03242                       totforce[2] = 0.0;
03243                       
03244                       for (ifr=0; ifr<refnforce; ifr++) {
03245                                  Vnm_tprint( 1, "  sasa  %d  %1.12E  %1.12E  %1.12E\n", ifr, 
03246                                                                   gforce[ifr].sasaForce[0], gforce[ifr].sasaForce[1], 
03247                                                                   gforce[ifr].sasaForce[2]);
03248                                  Vnm_tprint( 1, "  sav   %d  %1.12E  %1.12E  %1.12E\n", ifr, 
03249                                                                   gforce[ifr].savForce[0], gforce[ifr].savForce[1],
03250                                                                   gforce[ifr].savForce[2]);
03251                                  Vnm_tprint( 1, "  wca   %d  %1.12E  %1.12E  %1.12E\n", ifr, 
03252                                                                   gforce[ifr].wcaForce[0], gforce[ifr].wcaForce[1], 
03253                                                                   gforce[ifr].wcaForce[2]);
03254                                  Vnm_tprint( 1, "  tot   %d  %1.12E  %1.12E  %1.12E\n", ifr, 
03255                                                                   (gforce[ifr].wcaForce[0] \
03256                                                                    + gforce[ifr].savForce[0] +
03257                                                                    gforce[ifr].sasaForce[0]),
03258                                                                   (gforce[ifr].wcaForce[1] \
03259                                                                    + gforce[ifr].savForce[1] +
03260                                                                    gforce[ifr].sasaForce[1]),
03261                                                                   (gforce[ifr].wcaForce[2] \
03262                                                                    + gforce[ifr].savForce[2] +
03263                                                                    gforce[ifr].sasaForce[2]));
03264                                  for (ivc=0; ivc<3; ivc++) {
03265                                             totforce[ivc] += (gforce[ifr].wcaForce[ivc] \
03266                                                                                         + gforce[ifr].savForce[ivc] \
03267                                                                                           + gforce[ifr].sasaForce[ivc]);
03268                                  }
03269                       }
03270                       Vnm_tprint( 1, "  tot all  %1.12E  %1.12E  %1.12E\n", totforce[0],
03271                                                        totforce[1], totforce[2]);
03272            }
03273            
03274            Vmem_free(VNULL, refnforce, sizeof(AtomForce), (void **)(&lforce));
03275            Vmem_free(VNULL, refnforce, sizeof(AtomForce), (void **)(&gforce));
03276 
03277            return 1;
03278 }
03279 
03280 #ifdef HAVE_MC_H
03281 
03282 
03283 VPUBLIC void killFE(NOsh *nosh, Vpbe *pbe[NOSH_MAXCALC], 
03284                                                        Vfetk *fetk[NOSH_MAXCALC], Gem *gm[NOSH_MAXMOL]) {
03285            
03286            int i;
03287            
03288 #ifndef VAPBSQUIET
03289            Vnm_tprint(1, "Destroying finite element structures.\n");
03290 #endif
03291            
03292            for(i=0;i<nosh->ncalc;i++){
03293                       Vpbe_dtor(&(pbe[i]));
03294                       Vfetk_dtor(&(fetk[i]));
03295            }
03296            for (i=0; i<nosh->nmesh; i++) Gem_dtor(&(gm[i]));
03297 }
03298 
03299 
03300 VPUBLIC Vrc_Codes initFE(int icalc, NOsh *nosh, FEMparm *feparm, PBEparm *pbeparm, 
03301                                                Vpbe *pbe[NOSH_MAXCALC], Valist *alist[NOSH_MAXMOL], 
03302                                                Vfetk *fetk[NOSH_MAXCALC], Gem *gm[NOSH_MAXMOL]) {
03303            
03304            Gem *tempGm = VNULL;
03305            int iatom, imesh, i, j, theMol, focusFlag;
03306            Vio *sock = VNULL;
03307            size_t bytesTotal, highWater;
03308            Vfetk_MeshLoad meshType;
03309            double length[3], center[3];
03310            Vrc_Codes vrc;
03311            
03312            double sparm, q, iparm;
03313            Valist *myalist;
03314            Vatom *atom = VNULL;
03315            
03316            Vnm_tstart(27, "Setup timer");
03317            
03318            /* Print some warning messages */
03319            if (pbeparm->useDielMap)  Vnm_tprint(2, "FEM ignoring dielectric map!\n");
03320            if (pbeparm->useKappaMap)  Vnm_tprint(2, "FEM ignoring kappa map!\n");
03321            if (pbeparm->useChargeMap)  Vnm_tprint(2, "FEM ignoring charge map!\n");
03322            
03323            /* Fix mesh center for "GCENT MOL #" types of declarations. */
03324            Vnm_tprint(0, "Re-centering mesh...\n");
03325            theMol = pbeparm->molid-1;
03326            myalist = alist[theMol];
03327            for (j=0; j<3; j++) {
03328                       if (theMol < nosh->nmol) {
03329                                  center[j] = (myalist)->center[j];
03330                       } else{ 
03331                                  Vnm_tprint(2, "ERROR!  Bogus molecule number (%d)!\n", 
03332                                                           (theMol+1));
03333                                  return VRC_FAILURE;
03334                       }
03335            }
03336            
03337            /* Check for completely-neutral molecule */
03338            q = 0;
03339            for (iatom=0; iatom<Valist_getNumberAtoms(myalist); iatom++) {
03340                       atom = Valist_getAtom(myalist, iatom);
03341                       q += VSQR(Vatom_getCharge(atom));
03342            }
03343            /* D. Gohara 10/22/09 - disabled
03344            if (q < (1e-6)) {
03345                       Vnm_tprint(2, "Molecule #%d is uncharged!\n", pbeparm->molid);
03346                       Vnm_tprint(2, "Sum square charge = %g!\n", q);
03347                       return VRC_FAILURE;
03348            }
03349            */
03350            
03351            /* Set the femparm pkey value based on the presence of an HB solver */
03352 #ifdef USE_HB
03353            feparm->pkey = 1;
03354 #else
03355            feparm->pkey = 0;
03356 #endif
03357            
03358            /* Set up PBE object */
03359            Vnm_tprint(0, "Setting up PBE object...\n");
03360            if (pbeparm->srfm == VSM_SPLINE) sparm = pbeparm->swin;
03361            else sparm = pbeparm->srad;
03362            if (pbeparm->nion > 0) iparm = pbeparm->ionr[0];
03363            else iparm = 0.0;
03364            focusFlag = 0;
03365            pbe[icalc] = Vpbe_ctor(myalist, pbeparm->nion,
03366                                                                      pbeparm->ionc, pbeparm->ionr, pbeparm->ionq, 
03367                                                                      pbeparm->temp, pbeparm->pdie, 
03368                                                                      pbeparm->sdie, sparm, focusFlag, pbeparm->sdens, 
03369                                                                      pbeparm->zmem, pbeparm->Lmem, pbeparm->mdie, 
03370                                                                      pbeparm->memv);
03371            
03372            /* Print a few derived parameters */
03373            Vnm_tprint(1, "  Debye length:  %g A\n", Vpbe_getDeblen(pbe[icalc]));
03374            
03375            /* Set up FEtk objects */
03376            Vnm_tprint(0, "Setting up FEtk object...\n");
03377            fetk[icalc] = Vfetk_ctor(pbe[icalc], pbeparm->pbetype);
03378            Vfetk_setParameters(fetk[icalc], pbeparm, feparm);
03379            
03380            /* Build mesh */
03381            Vnm_tprint(0, "Setting up mesh...\n");
03382            sock = VNULL;
03383            if (feparm->useMesh) {
03384                       imesh = feparm->meshID-1;
03385                       meshType = VML_EXTERNAL;
03386                       for (i=0; i<3; i++) {
03387                                  center[i] = 0.0;
03388                                  length[i] = 0.0;
03389                       }
03390                       Vnm_print(0, "Using mesh %d (%s) in calculation.\n", imesh+1,
03391                                               nosh->meshpath[imesh]);
03392                       switch (nosh->meshfmt[imesh]) {                                   
03393                                  case VDF_DX:
03394                                             Vnm_tprint(2, "DX finite element mesh input not supported yet!\n");
03395                                             return VRC_FAILURE;
03396                                  case VDF_UHBD:
03397                                             Vnm_tprint( 2, "UHBD finite element mesh input not supported!\n");
03398                                             return VRC_FAILURE;
03399                                  case VDF_AVS:
03400                                             Vnm_tprint( 2, "AVS finite element mesh input not supported!\n");
03401                                             return VRC_FAILURE;
03402                                  case VDF_MCSF:
03403                                             Vnm_tprint(1, "Reading MCSF-format input finite element mesh from %s.\n",
03404                                                                      nosh->meshpath[imesh]);
03405                                             sock = Vio_ctor("FILE", "ASC", VNULL, nosh->meshpath[imesh], "r");
03406                                             if (sock == VNULL) {
03407                                                        Vnm_print(2, "Problem opening virtual socket %s!\n", 
03408                                                                                nosh->meshpath[imesh]);
03409                                                        return VRC_FAILURE;
03410                                             }
03411                                             if (Vio_accept(sock, 0) < 0) {
03412                                                        Vnm_print(2, "Problem accepting virtual socket %s!\n",
03413                                                                                nosh->meshpath[imesh]);
03414                                                        return VRC_FAILURE;
03415                                             }
03416                                             break;
03417                                             
03418                                  default:
03419                                             Vnm_tprint( 2, "Invalid data format (%d)!\n", 
03420                                                                      nosh->meshfmt[imesh]);
03421                                             return VRC_FAILURE;
03422                       }
03423            } else { /* if (feparm->useMesh) */
03424                       meshType = VML_DIRICUBE;
03425                       for (i=0; i<3; i++) {
03426                                  center[i] = alist[theMol]->center[i];
03427                                  length[i] = feparm->glen[i];
03428                       }
03429            }
03430            
03431            vrc = Vfetk_loadMesh(fetk[icalc], center, length, meshType, sock);
03432            if (vrc == VRC_FAILURE) {
03433                       Vnm_print(2, "Error constructing finite element mesh!\n");
03434                       return VRC_FAILURE;
03435            }
03436            Vnm_redirect(0);
03437            Gem_shapeChk(fetk[icalc]->gm);
03438            Vnm_redirect(1);      
03439                       
03440            /* Uniformly refine the mesh a bit */
03441            for (j=0; j<2; j++) {
03442                       AM_markRefine(fetk[icalc]->am, 0, -1, 0, 0.0);
03443                       AM_refine(fetk[icalc]->am, 2, 0, feparm->pkey);
03444                       Vnm_redirect(0);
03445                       Gem_shapeChk(fetk[icalc]->gm);
03446                       Vnm_redirect(1);
03447            }
03448            
03449            /* Setup time statistics */
03450            Vnm_tstop(27, "Setup timer");
03451            
03452            /* Memory statistics */
03453            bytesTotal = Vmem_bytesTotal();
03454            highWater = Vmem_highWaterTotal();
03455            
03456 #ifndef VAPBSQUIET
03457            Vnm_tprint( 1, "  Current memory usage:  %4.3f MB total, \
03458 %4.3f MB high water\n", (double)(bytesTotal)/(1024.*1024.),
03459                                             (double)(highWater)/(1024.*1024.));
03460 #endif
03461            
03462            
03463            return VRC_SUCCESS;
03464 }
03465 
03466 VPUBLIC void printFEPARM(int icalc, NOsh *nosh, FEMparm *feparm, 
03467                                                                    Vfetk *fetk[NOSH_MAXCALC]) {
03468            
03469            Vnm_tprint(1, "  Domain size:  %g A x %g A x %g A\n", 
03470                                     feparm->glen[0], feparm->glen[1],
03471                                     feparm->glen[2]);
03472            switch(feparm->ekey) {
03473                       case FET_SIMP:
03474                                  Vnm_tprint(1, "  Per-simplex error tolerance:  %g\n", feparm->etol);
03475                                  break;
03476                       case FET_GLOB:
03477                                  Vnm_tprint(1, "  Global error tolerance:  %g\n", feparm->etol);
03478                                  break;
03479                       case FET_FRAC:
03480                                  Vnm_tprint(1, "  Fraction of simps to refine:  %g\n", feparm->etol);
03481                                  break;
03482                       default:
03483                                  Vnm_tprint(2, "Invalid ekey (%d)!\n", feparm->ekey);
03484                                  VASSERT(0);
03485                                  break;
03486            }
03487            switch(feparm->akeyPRE) {
03488                       case FRT_UNIF:
03489                                  Vnm_tprint(1, "  Uniform pre-solve refinement.\n");
03490                                  break;
03491                       case FRT_GEOM:
03492                                  Vnm_tprint(1, "  Geometry-based pre-solve refinement.\n");
03493                                  break;
03494                       default:
03495                                  Vnm_tprint(2, "Invalid akeyPRE (%d)!\n", feparm->akeyPRE);
03496                                  VASSERT(0);
03497                                  break;
03498            }
03499            switch(feparm->akeySOLVE) {
03500                       case FRT_RESI:
03501                                  Vnm_tprint(1, "  Residual-based a posteriori refinement.\n");
03502                                  break;
03503                       case FRT_DUAL:
03504                                  Vnm_tprint(1, "  Dual-based a posteriori refinement.\n");
03505                                  break;
03506                       case FRT_LOCA:
03507                                  Vnm_tprint(1, "  Local-based a posteriori refinement.\n");
03508                                  break;
03509                       default:
03510                                  Vnm_tprint(2, "Invalid akeySOLVE (%d)!\n", feparm->akeySOLVE);
03511                                  break;
03512            }
03513            Vnm_tprint(1, "  Refinement of initial mesh to ~%d vertices\n", 
03514                                     feparm->targetNum);
03515            Vnm_tprint(1, "  Geometry-based refinment lower bound:  %g A\n",
03516                                     feparm->targetRes);
03517            Vnm_tprint(1, "  Maximum number of solve-estimate-refine cycles:  %d\n",
03518                                     feparm->maxsolve);
03519            Vnm_tprint(1, "  Maximum number of vertices in mesh:  %d\n",
03520                                     feparm->maxvert);
03521            
03522            /* FOLLOWING IS SOLVER-RELATED; BAIL IF NOT SOLVING */
03523            if (nosh->bogus)  return;
03524 #ifdef USE_HB
03525            Vnm_tprint(1, "  HB linear solver:  AM_hPcg\n");
03526 #else
03527            Vnm_tprint(1, "  Non-HB linear solver:  ");
03528            switch (fetk[icalc]->lkey) {
03529                                  case VLT_SLU:
03530                                             Vnm_print(1, "SLU direct\n");
03531                                             break;
03532                                  case VLT_MG:
03533                                             Vnm_print(1, "multigrid\n");
03534                                             break;
03535                                  case VLT_CG:
03536                                             Vnm_print(1, "conjugate gradient\n");
03537                                             break;
03538                                  case VLT_BCG:
03539                                             Vnm_print(1, "BiCGStab\n");
03540                                             break;
03541                                  default:
03542                                             Vnm_print(1, "???\n");
03543                                             break;
03544            }
03545 #endif
03546 
03547            Vnm_tprint(1, "  Linear solver tol.:  %g\n", fetk[icalc]->ltol);
03548            Vnm_tprint(1, "  Linear solver max. iters.:  %d\n", fetk[icalc]->lmax);
03549            Vnm_tprint(1, "  Linear solver preconditioner:  ");
03550            switch (fetk[icalc]->lprec) {
03551                       case VPT_IDEN:
03552                                  Vnm_print(1, "identity\n");
03553                                  break;
03554                       case VPT_DIAG:
03555                                  Vnm_print(1, "diagonal\n");
03556                                  break;
03557                       case VPT_MG:
03558                                  Vnm_print(1, "multigrid\n");
03559                                  break;
03560                       default:
03561                                  Vnm_print(1, "???\n");
03562                                  break;
03563            }
03564            Vnm_tprint(1, "  Nonlinear solver:  ");
03565            switch (fetk[icalc]->nkey) {
03566                       case VNT_NEW:
03567                                  Vnm_print(1, "newton\n");
03568                                  break;
03569                       case VNT_INC:
03570                                  Vnm_print(1, "incremental\n");
03571                                  break;
03572                       case VNT_ARC:
03573                                  Vnm_print(1, "pseudo-arclength\n");
03574                                  break;
03575                       default:
03576                                  Vnm_print(1, "??? ");
03577                                  break;
03578            }
03579            Vnm_tprint(1, "  Nonlinear solver tol.:  %g\n", fetk[icalc]->ntol);
03580            Vnm_tprint(1, "  Nonlinear solver max. iters.:  %d\n", fetk[icalc]->nmax);
03581            Vnm_tprint(1, "     Initial guess:  ");
03582            switch (fetk[icalc]->gues) {
03583                       case VGT_ZERO:
03584                                  Vnm_tprint(1, "zero\n");
03585                                  break;
03586                       case VGT_DIRI:
03587                                  Vnm_tprint(1, "boundary function\n");
03588                                  break;
03589                       case VGT_PREV:
03590                                  Vnm_tprint(1, "interpolated previous solution\n");
03591                                  break;
03592                       default:
03593                                  Vnm_tprint(1, "???\n");
03594                                  break;
03595            }
03596            
03597 }
03598 
03599 VPUBLIC int partFE(int icalc, NOsh *nosh, FEMparm *feparm, 
03600                                                Vfetk *fetk[NOSH_MAXCALC]) {
03601            
03602            Vfetk_setAtomColors(fetk[icalc]);
03603            return 1;
03604 }
03605 
03606 VPUBLIC int preRefineFE(int icalc, NOsh *nosh, FEMparm *feparm, 
03607                                                                   Vfetk *fetk[NOSH_MAXCALC]) {
03608            
03609            int nverts, marked;
03610            
03611            switch(feparm->akeyPRE) {
03612                       case FRT_UNIF:
03613                                  Vnm_tprint(1, "  Commencing uniform refinement to %d verts.\n",
03614                                                           feparm->targetNum);
03615                                  break;
03616                       case FRT_GEOM:
03617                                  Vnm_tprint(1, "  Commencing geometry-based refinement to %d \
03618 verts or %g A resolution.\n", feparm->targetNum, feparm->targetRes);
03619                                  break;
03620                       case FRT_RESI:
03621                                  VASSERT(0);
03622                                  break;
03623                       case FRT_DUAL:
03624                                  Vnm_tprint(2, "What?  You can't do a posteriori error estimation \
03625 before you solve!\n");
03626                                  VASSERT(0);
03627                                  break;
03628                       case FRT_LOCA:
03629                                  VASSERT(0);
03630                                  break;
03631                       default:
03632                                  VASSERT(0);
03633                                  break;
03634            }
03635            
03636            Vnm_tprint(1, "  Initial mesh has %d vertices\n", 
03637                                     Gem_numVV(fetk[icalc]->gm));
03638            while (1) {
03639                       nverts = Gem_numVV(fetk[icalc]->gm);
03640                       if (nverts > feparm->targetNum) {
03641                                  Vnm_tprint(1, "  Hit vertex number limit.\n");
03642                                  break;
03643                       }
03644                       marked = AM_markRefine(fetk[icalc]->am, feparm->akeyPRE, -1, 
03645                                                                                 feparm->ekey, feparm->etol);
03646                       if (marked == 0) {
03647                                  Vnm_tprint(1, "  Marked 0 simps; hit error/size tolerance.\n");
03648                                  break;
03649                       }
03650                       Vnm_tprint(1, "    Have %d verts, marked %d.  Refining...\n", nverts,
03651                                                marked);
03652                       AM_refine(fetk[icalc]->am, 0, 0, feparm->pkey);
03653            }
03654            nverts = Gem_numVV(fetk[icalc]->gm);
03655            Vnm_tprint(1, "  Done refining; have %d verts.\n", nverts);
03656            
03657            return 1;
03658 }
03659 
03660 VPUBLIC int solveFE(int icalc, NOsh *nosh, PBEparm *pbeparm, FEMparm *feparm, 
03661                                                        Vfetk *fetk[NOSH_MAXCALC]) {
03662            
03663            int lkeyHB = 3;  
03664            int meth = 2;  
03665            int prob = 0;  
03666            int prec = 0;  
03668            if ((pbeparm->pbetype==PBE_NPBE)||(pbeparm->pbetype == PBE_NRPBE)||(pbeparm->pbetype == PBE_SMPBE) /* SMPBE Added */) {
03669 
03670                       AM_nSolve(
03671                                               fetk[icalc]->am,
03672                                               fetk[icalc]->nkey,
03673                                               fetk[icalc]->nmax, 
03674                                               fetk[icalc]->ntol,
03675                                               meth,
03676                                               fetk[icalc]->lmax, 
03677                                               fetk[icalc]->ltol,
03678                                               prec,
03679                                               fetk[icalc]->gues, 
03680                                               fetk[icalc]->pjac
03681                                               );
03682            } else if ((pbeparm->pbetype==PBE_LPBE)||(pbeparm->pbetype==PBE_LRPBE)) {
03683                       /* Note: USEHB is a compile time defined macro. The program flow
03684                       is to always take the route using AM_hlSolve when the solver
03685                       is linear. D. Gohara 6/29/06
03686                       */
03687 #ifdef USE_HB
03688                       Vnm_print(2, "SORRY!  DON'T USE HB!!!\n");
03689                       VASSERT(0);
03690                       AM_hlSolve(fetk[icalc]->am, meth, lkeyHB, fetk[icalc]->lmax, 
03691                                  fetk[icalc]->ltol, fetk[icalc]->gues, fetk[icalc]->pjac);
03692 #else
03693                       
03694                       AM_lSolve(
03695                                               fetk[icalc]->am,
03696                                               prob,
03697                                               meth, 
03698                                               fetk[icalc]->lmax, 
03699                                               fetk[icalc]->ltol,
03700                                               prec,
03701                                               fetk[icalc]->gues,
03702                                               fetk[icalc]->pjac
03703                                               );
03704 #endif
03705            }
03706            
03707            return 1;
03708 }
03709 
03710 VPUBLIC int energyFE(NOsh *nosh, int icalc, Vfetk *fetk[NOSH_MAXCALC], 
03711                                                         int *nenergy, double *totEnergy, double *qfEnergy, 
03712                                                         double *qmEnergy,
03713                                                         double *dielEnergy) {
03714            
03715            double tenergy;
03716            FEMparm *feparm;
03717            PBEparm *pbeparm;
03718            
03719            feparm = nosh->calc[icalc]->femparm;
03720            pbeparm = nosh->calc[icalc]->pbeparm;
03721            
03722            *nenergy = 1;
03723            
03724            /* Some processors don't count */
03725            if (nosh->bogus == 0) {
03726                       if ((pbeparm->pbetype==PBE_NPBE)||(pbeparm->pbetype==PBE_NRPBE)||(pbeparm->pbetype == PBE_SMPBE) /* SMPBE Added */) {
03727                                  *totEnergy = Vfetk_energy(fetk[icalc], -1, 1);
03728                       } else if ((pbeparm->pbetype==PBE_LPBE)||(pbeparm->pbetype==PBE_LRPBE)) {
03729                                  *totEnergy = Vfetk_energy(fetk[icalc], -1, 0);
03730                       } else VASSERT(0);
03731                       
03732 #ifndef VAPBSQUIET
03733                       Vnm_tprint(1, "      Total electrostatic energy = %1.12E kJ/mol\n", 
03734                                                Vunit_kb*pbeparm->temp*(1e-3)*Vunit_Na*(*totEnergy));
03735                       fflush(stdout);
03736 #endif
03737            } else *totEnergy = 0;
03738            
03739            if (pbeparm->calcenergy == PCE_COMPS) {
03740                       
03741                       Vnm_tprint(2, "Error!  Verbose energy evaluation not available for FEM yet!\n");
03742                       Vnm_tprint(2, "E-mail baker@biochem.wustl.edu if you want this.\n");
03743                       *qfEnergy = 0;
03744                       *qmEnergy = 0;
03745                       *dielEnergy = 0;
03746                       
03747            } else *nenergy = 0;
03748            
03749            return 1;
03750 }
03751 
03752 VPUBLIC int postRefineFE(int icalc, NOsh *nosh, FEMparm *feparm, 
03753                                                                    Vfetk *fetk[NOSH_MAXCALC]) {
03754            
03755            int nverts, marked;
03756            
03757            nverts = Gem_numVV(fetk[icalc]->gm);
03758            if (nverts > feparm->maxvert) {
03759                       Vnm_tprint(1, "    Current number of vertices (%d) exceeds max (%d)!\n",
03760                                                nverts, feparm->maxvert);
03761                       return 0;
03762            }
03763            Vnm_tprint(1, "      Mesh currently has %d vertices\n", nverts);
03764            
03765            switch(feparm->akeySOLVE) {
03766                       case FRT_UNIF:
03767                                  Vnm_tprint(1, "      Commencing uniform refinement.\n");
03768                                  break;
03769                       case FRT_GEOM:
03770                                  Vnm_tprint(1, "      Commencing geometry-based refinement.\n");
03771                                  break;
03772                       case FRT_RESI:
03773                                  Vnm_tprint(1, "      Commencing residual-based refinement.\n");
03774                                  break;
03775                       case FRT_DUAL:
03776                                  Vnm_tprint(1, "      Commencing dual problem-based refinement.\n");
03777                                  break;
03778                       case FRT_LOCA:
03779                                  Vnm_tprint(1, "      Commencing local-based refinement.\n.");
03780                                  break;
03781                       default:
03782                                  Vnm_tprint(2, "      Error -- unknown refinement type (%d)!\n", 
03783                                                           feparm->akeySOLVE);
03784                                  return 0;
03785                                  break;
03786            }
03787            
03788            marked = AM_markRefine(fetk[icalc]->am, feparm->akeySOLVE, -1, 
03789                                                                      feparm->ekey, feparm->etol);
03790            if (marked == 0) {
03791                       Vnm_tprint(1, "      Marked 0 simps; hit error/size tolerance.\n");
03792                       return 0;
03793            }
03794            Vnm_tprint(1, "      Have %d verts, marked %d.  Refining...\n", nverts,
03795                                     marked);
03796            AM_refine(fetk[icalc]->am, 0, 0, feparm->pkey);
03797            nverts = Gem_numVV(fetk[icalc]->gm);
03798            Vnm_tprint(1, "      Done refining; have %d verts.\n", nverts);
03799            Vnm_redirect(0);
03800            Gem_shapeChk(fetk[icalc]->gm);
03801            Vnm_redirect(1);
03802            
03803            return 1;
03804 }
03805 
03806 
03807 VPUBLIC int writedataFE(int rank, NOsh *nosh, PBEparm *pbeparm, Vfetk *fetk) {
03808            
03809            char writestem[VMAX_ARGLEN];
03810            char outpath[VMAX_ARGLEN];
03811            int i, nx, ny, nz, writeit;
03812            double hx, hy, hzed, xcent, ycent, zcent, xmin, ymin, zmin;
03813            AM *am;
03814            Bvec *vec;
03815            
03816            if (nosh->bogus) return 1;
03817            
03818            am = fetk->am;
03819            vec = am->w0;
03820            
03821            for (i=0; i<pbeparm->numwrite; i++) { 
03822                       
03823                       writeit = 1;
03824                       
03825                       switch (pbeparm->writetype[i]) {
03826                                  
03827                                  case VDT_CHARGE:
03828                                             
03829                                             Vnm_tprint(2, "    Sorry; can't write charge distribution for FEM!\n");
03830                                             writeit = 0;
03831                                             break;
03832                                             
03833                                  case VDT_POT:
03834                                             
03835                                             Vnm_tprint(1, "    Writing potential to ");
03836                                             Vfetk_fillArray(fetk, vec, VDT_POT);
03837                                             break;
03838                                             
03839                                  case VDT_SMOL:
03840                                             
03841                                             Vnm_tprint(1, "    Writing molecular accessibility to ");
03842                                             Vfetk_fillArray(fetk, vec, VDT_SMOL);
03843                                             break;
03844                                             
03845                                  case VDT_SSPL:
03846                                             
03847                                             Vnm_tprint(1, "    Writing spline-based accessibility to ");
03848                                             Vfetk_fillArray(fetk, vec, VDT_SSPL);
03849                                             break;
03850                                             
03851                                  case VDT_VDW:
03852                                             
03853                                             Vnm_tprint(1, "    Writing van der Waals accessibility to ");
03854                                             Vfetk_fillArray(fetk, vec, VDT_VDW);
03855                                             break;
03856                                             
03857                                  case VDT_IVDW:
03858                                             
03859                                             Vnm_tprint(1, "    Writing ion accessibility to ");
03860                                             Vfetk_fillArray(fetk, vec, VDT_IVDW);
03861                                             break;
03862                                             
03863                                  case VDT_LAP:
03864                                             
03865                                             Vnm_tprint(2, "    Sorry; can't write charge distribution for FEM!\n");
03866                                             writeit = 0;
03867                                             break;
03868                                             
03869                                  case VDT_EDENS:
03870                                             
03871                                             Vnm_tprint(2, "    Sorry; can't write energy density for FEM!\n");
03872                                             writeit = 0;
03873                                             break;
03874                                             
03875                                  case VDT_NDENS:
03876                                             
03877                                             Vnm_tprint(1, "    Writing number density to ");
03878                                             Vfetk_fillArray(fetk, vec, VDT_NDENS);
03879                                             break;
03880                                             
03881                                  case VDT_QDENS:
03882                                             
03883                                             Vnm_tprint(1, "    Writing charge density to ");
03884                                             Vfetk_fillArray(fetk, vec, VDT_QDENS);
03885                                             break;
03886                                             
03887                                  case VDT_DIELX:
03888                                             
03889                                             Vnm_tprint(2, "    Sorry; can't write x-shifted dielectric map for FEM!\n");
03890                                             writeit = 0;
03891                                             break;
03892                                             
03893                                  case VDT_DIELY:
03894                                             
03895                                             Vnm_tprint(2, "    Sorry; can't write y-shifted dielectric map for FEM!\n");
03896                                             writeit = 0;
03897                                             break;
03898                                             
03899                                  case VDT_DIELZ:
03900                                             
03901                                             Vnm_tprint(2, "    Sorry; can't write z-shifted dielectric map for FEM!\n");
03902                                             writeit = 0;
03903                                             break;
03904                                             
03905                                  case VDT_KAPPA:
03906                                             
03907                                             Vnm_tprint(1, "    Sorry; can't write kappa map for FEM!\n");
03908                                             writeit = 0;
03909                                             break;
03910 
03911                                  case VDT_ATOMPOT:
03912                                             
03913                                             Vnm_tprint(1, "    Sorry; can't write atom potentials for FEM!\n");
03914                                             writeit = 0;
03915                                             break;
03916                                             
03917                                  default:
03918                                             
03919                                             Vnm_tprint(2, "Invalid data type for writing!\n");
03920                                             writeit = 0;
03921                                             return 0;
03922                       }
03923                       
03924                       if (!writeit) return 0;
03925                       
03926                       
03927 #ifdef HAVE_MPI_H
03928                       sprintf(writestem, "%s-PE%d", pbeparm->writestem[i], rank);
03929 #else
03930                       if(nosh->ispara){
03931                                  sprintf(writestem, "%s-PE%d", pbeparm->writestem[i],nosh->proc_rank);
03932                       }else{
03933                                  sprintf(writestem, "%s", pbeparm->writestem[i]);
03934                       }
03935 #endif
03936                       
03937                       switch (pbeparm->writefmt[i]) {
03938                                  
03939                                  case VDF_DX:
03940                                             sprintf(outpath, "%s.%s", writestem, "dx");
03941                                             Vnm_tprint(1, "%s\n", outpath);
03942                                             Vfetk_write(fetk, "FILE", "ASC", VNULL, outpath, vec, VDF_DX);
03943                                             break;
03944                                             
03945                                  case VDF_AVS:
03946                                             sprintf(outpath, "%s.%s", writestem, "ucd");
03947                                             Vnm_tprint(1, "%s\n", outpath);
03948                                             Vfetk_write(fetk, "FILE", "ASC", VNULL, outpath, vec, VDF_AVS);
03949                                             break;
03950                                             
03951                                  case VDF_UHBD:
03952                                             Vnm_tprint(2, "UHBD format not supported for FEM!\n");
03953                                             break;
03954                                             
03955                                  case VDF_MCSF:
03956                                             Vnm_tprint(2, "MCSF format not supported yet!\n");
03957                                             break;
03958                                             
03959                                  default:
03960                                             Vnm_tprint(2, "Bogus data format (%d)!\n", 
03961                                                                      pbeparm->writefmt[i]);
03962                                             break;
03963                       }
03964                       
03965            }
03966            
03967            return 1;
03968 }
03969 #endif /* ifdef HAVE_MCX_H */
03970 
03971 VPUBLIC int initAPOL(NOsh *nosh, Vmem *mem, Vparam *param, APOLparm *apolparm,
03972                                                         int *nforce, AtomForce **atomForce, Valist *alist) {
03973 
03974            int i;
03975            
03976            Vclist *clist = VNULL;
03977            Vacc *acc = VNULL;
03978            Vatom *atom = VNULL;
03979            Vparam_AtomData *atomData = VNULL;
03980            
03981            int inhash[3];
03982            int rc = 0;
03983            
03984            double sasa, sav;
03985            
03986            double nhash[3];
03987            double sradPad, x, y, z;
03988            double atomRadius, srad;
03989            double *atomsasa, *atomwcaEnergy;
03990            double energy = 0.0;        //WCA energy per atom
03991            
03992            double dist, charge, xmin, xmax, ymin, ymax, zmin, zmax;
03993            double disp[3], center[3];
03994            double soluteXlen, soluteYlen, soluteZlen;
03995 
03996            atomsasa = (double *)Vmem_malloc(VNULL, Valist_getNumberAtoms(alist), sizeof(double));
03997            atomwcaEnergy = (double *)Vmem_malloc(VNULL, Valist_getNumberAtoms(alist), sizeof(double));
03998            
03999            /* Determine solute length and charge*/
04000     atom = Valist_getAtom(alist, 0);
04001     xmin = Vatom_getPosition(atom)[0];
04002     xmax = Vatom_getPosition(atom)[0];
04003     ymin = Vatom_getPosition(atom)[1];
04004     ymax = Vatom_getPosition(atom)[1];
04005     zmin = Vatom_getPosition(atom)[2];
04006     zmax = Vatom_getPosition(atom)[2];
04007     charge = 0;
04008     for (i=0; i < Valist_getNumberAtoms(alist); i++) {
04009         atom = Valist_getAtom(alist, i);
04010         atomRadius = Vatom_getRadius(atom);
04011         x = Vatom_getPosition(atom)[0];
04012         y = Vatom_getPosition(atom)[1];
04013         z = Vatom_getPosition(atom)[2];
04014         if ((x+atomRadius) > xmax) xmax = x + atomRadius;
04015         if ((x-atomRadius) < xmin) xmin = x - atomRadius;
04016         if ((y+atomRadius) > ymax) ymax = y + atomRadius;
04017         if ((y-atomRadius) < ymin) ymin = y - atomRadius;
04018         if ((z+atomRadius) > zmax) zmax = z + atomRadius;
04019         if ((z-atomRadius) < zmin) zmin = z - atomRadius;
04020         disp[0] = (x - center[0]);
04021         disp[1] = (y - center[1]);
04022         disp[2] = (z - center[2]);
04023         dist = (disp[0]*disp[0]) + (disp[1]*disp[1]) + (disp[2]*disp[2]); 
04024         dist = VSQRT(dist) + atomRadius;
04025         charge += Vatom_getCharge(Valist_getAtom(alist, i));
04026     }
04027     soluteXlen = xmax - xmin;
04028     soluteYlen = ymax - ymin;
04029     soluteZlen = zmax - zmin;
04030            
04031            /* Set up the hash table for the cell list */
04032            Vnm_print(0, "APOL: Setting up hash table and accessibility object...\n");
04033            nhash[0] = soluteXlen/0.5;
04034            nhash[1] = soluteYlen/0.5;
04035            nhash[2] = soluteZlen/0.5;
04036     for (i=0; i<3; i++) inhash[i] = (int)(nhash[i]);
04037            
04038            for (i=0;i<3;i++){ 
04039         if (inhash[i] < 3) inhash[i] = 3; 
04040         if (inhash[i] > MAX_HASH_DIM) inhash[i] = MAX_HASH_DIM;
04041            }
04042            
04043            /* Pad the radius by 2x the maximum displacement value */
04044            srad = apolparm->srad;
04045            sradPad = srad + (2*apolparm->dpos);
04046            clist = Vclist_ctor(alist, sradPad , inhash, CLIST_AUTO_DOMAIN, 
04047                                                                                                    VNULL, VNULL);
04048            acc = Vacc_ctor(alist, clist, apolparm->sdens);
04049            
04050            /* Get WAT (water) LJ parameters from Vparam object */
04051            if (param == VNULL && (apolparm->bconc != 0.0)) {
04052                       Vnm_tprint(2, "initAPOL:  Got NULL Vparam object!\n");
04053                       Vnm_tprint(2, "initAPOL:  You are performing an apolar calculation with the van der Waals integral term,\n");
04054                       Vnm_tprint(2, "initAPOL:  this term requires van der Waals parameters which are not available from the \n");
04055                       Vnm_tprint(2, "initAPOL:  PQR file. Therefore, you need to supply a parameter file with the parm keyword,\n");
04056                       Vnm_tprint(2, "initAPOL:  for example,\n");
04057                       Vnm_tprint(2, "initAPOL:    read parm flat amber94.dat end\n");
04058                       Vnm_tprint(2, "initAPOL:  where the relevant parameter files can be found in apbs/tools/conversion/param/vparam.\n");
04059                       return VRC_FAILURE;
04060            }
04061            
04062            if (apolparm->bconc != 0.0){
04063                       atomData = Vparam_getAtomData(param, "WAT", "OW");
04064                       if (atomData == VNULL) atomData = Vparam_getAtomData(param, "WAT", "O");
04065                       if (atomData == VNULL) {
04066                                  Vnm_tprint(2, "initAPOL:  Couldn't find parameters for WAT OW or WAT O!\n");
04067                                  Vnm_tprint(2, "initAPOL:  These parameters must be present in your file\n");
04068                                  Vnm_tprint(2, "initAPOL:  for apolar calculations.\n");
04069                                  return VRC_FAILURE;
04070                       }
04071                       apolparm->watepsilon = atomData->epsilon;
04072                       apolparm->watsigma = atomData->radius;
04073                       apolparm->setwat = 1;
04074            }
04075            
04076            /* Calculate Energy and Forces */
04077            if(apolparm->calcforce) {
04078                       rc = forceAPOL(acc, mem, apolparm, nforce, atomForce, alist, clist);
04079                       if(rc == VRC_FAILURE) {
04080                                  Vnm_print(2, "Error in apolar force calculation!\n");
04081                                  return VRC_FAILURE;
04082                       }
04083            }
04084            
04085            /* Get the SAV and SAS */
04086            sasa = 0.0;
04087            sav = 0.0;
04088            
04089            if (apolparm->calcenergy) {
04090                       if (VABS(apolparm->gamma) > VSMALL) {
04091                                  /* Total Solvent Accessible Surface Area (SASA) */
04092                                  apolparm->sasa = Vacc_totalSASA(acc, srad);
04093                                  /* SASA for each atom */
04094                                  for (i = 0; i < Valist_getNumberAtoms(alist); i++) {
04095                                             atom = Valist_getAtom(alist, i);
04096                                             atomsasa[i] = Vacc_atomSASA(acc, srad, atom);
04097                                  }
04098                } else {
04099                                  /* Total Solvent Accessible Surface Area (SASA) set to zero */
04100                                  apolparm->sasa = 0.0;
04101                                  /* SASA for each atom set to zero*/
04102                                  for (i = 0; i < Valist_getNumberAtoms(alist); i++) {
04103                                             atom = Valist_getAtom(alist, i);
04104                                             atomsasa[i] = 0.0;
04105                                  }
04106                }
04107 
04108                       /* Inflated van der Waals accessibility */
04109                       if (VABS(apolparm->press) > VSMALL){
04110                           apolparm->sav = Vacc_totalSAV(acc, clist, apolparm, srad);
04111                       } else {
04112                                  apolparm->sav = 0.0; 
04113                       }
04114 
04115                       /* wcaEnergy integral code */
04116                       if (VABS(apolparm->bconc) > VSMALL) {
04117                                  /* wcaEnergy for each atom */
04118                                  for (i = 0; i < Valist_getNumberAtoms(alist); i++) {
04119                                             rc = Vacc_wcaEnergyAtom(acc, apolparm, alist, clist, i, &energy);
04120                                             if (rc == 0)  {
04121                                                        Vnm_print(2, "Error in apolar energy calculation!\n");
04122                                                        return 0;
04123                                             }
04124                                             atomwcaEnergy[i] = energy;                  
04125                                  }
04126                                  /* Total WCA Energy */
04127                                  rc = Vacc_wcaEnergy(acc, apolparm, alist, clist);
04128                                  if (rc == 0) {
04129                                             Vnm_print(2, "Error in apolar energy calculation!\n");
04130                                             return 0;
04131                                  }                     
04132                       } else {
04133                                  apolparm->wcaEnergy = 0.0;
04134                       }
04135                       energyAPOL(apolparm, apolparm->sasa, apolparm->sav, atomsasa, atomwcaEnergy, Valist_getNumberAtoms(alist));
04136            }
04137 
04138            Vmem_free(VNULL, Valist_getNumberAtoms(alist), sizeof(double), (void **)&(atomsasa));
04139            Vmem_free(VNULL, Valist_getNumberAtoms(alist), sizeof(double), (void **)&(atomwcaEnergy));
04140            Vclist_dtor(&clist);
04141            Vacc_dtor(&acc);
04142            
04143            return VRC_SUCCESS;
04144 }
04145 
04146 VPUBLIC int energyAPOL(APOLparm *apolparm, double sasa, double sav, double atomsasa[], double atomwcaEnergy[], int numatoms){
04147 
04148            double energy = 0.0;
04149            int i = 0;
04150 
04151 #ifndef VAPBSQUIET
04152            Vnm_print(1,"\nSolvent Accessible Surface Area (SASA) for each atom:\n");
04153            for (i = 0; i < numatoms; i++) {
04154                       Vnm_print(1,"  SASA for atom %i: %1.12E\n", i, atomsasa[i]);
04155            }
04156            
04157            Vnm_print(1,"\nTotal solvent accessible surface area: %g A^2\n",sasa);
04158 #endif
04159 
04160            switch(apolparm->calcenergy){
04161                       case ACE_NO:
04162                                  break;
04163                       case ACE_COMPS:
04164                                  Vnm_print(1,"energyAPOL: Cannot calculate component energy, skipping.\n");
04165                                  break;
04166                       case ACE_TOTAL:
04167                                  energy = (apolparm->gamma*sasa) + (apolparm->press*sav) 
04168                                                                   + (apolparm->wcaEnergy);
04169 #ifndef VAPBSQUIET
04170                                  Vnm_print(1,"\nSurface tension*area energies (gamma * SASA) for each atom:\n");
04171                                  for (i = 0; i < numatoms; i++) {
04172                                             Vnm_print(1,"  Surface tension*area energy for atom %i: %1.12E\n", i, apolparm->gamma*atomsasa[i]);
04173                                  }
04174 
04175                                  Vnm_print(1,"\nTotal surface tension energy: %g kJ/mol\n", apolparm->gamma*sasa);
04176                                  Vnm_print(1,"\nTotal solvent accessible volume: %g A^3\n", sav);
04177                                  Vnm_print(1,"\nTotal pressure*volume energy: %g kJ/mol\n", apolparm->press*sav);
04178                                  Vnm_print(1,"\nWCA dispersion Energies for each atom:\n");
04179                                  for (i = 0; i < numatoms; i++) {
04180                                             Vnm_print(1,"  WCA energy for atom %i: %1.12E\n", i, atomwcaEnergy[i]);
04181                                  }
04182                                  
04183                                  Vnm_print(1,"\nTotal WCA energy: %g kJ/mol\n", (apolparm->wcaEnergy));
04184                                  Vnm_print(1,"\nTotal non-polar energy = %1.12E kJ/mol\n", energy);
04185 #endif
04186                                  break;
04187                       default:
04188                                  Vnm_print(2,"energyAPOL: Error in energyAPOL. Unknown option.\n");
04189                                  break;
04190            }
04191            
04192            return VRC_SUCCESS;
04193 }
04194 
04195 VPUBLIC int forceAPOL(Vacc *acc, Vmem *mem, APOLparm *apolparm, 
04196                                                          int *nforce, AtomForce **atomForce, Valist *alist,
04197                                                          Vclist *clist){
04198            
04199            int i,j,natom;
04200            
04201            double srad; /* Probe radius */
04202            double xF, yF, zF;    /* Individual forces */
04203            
04204            double press, gamma, offset, bconc;
04205            double dSASA[3], dSAV[3], force[3];
04206            
04207            double *apos;
04208            
04209            Vatom *atom = VNULL;
04210            
04211            srad = apolparm->srad;
04212            press = apolparm->press;
04213            gamma = apolparm->gamma;
04214            offset = apolparm->dpos;
04215            bconc = apolparm->bconc;
04216                       
04217            natom = Valist_getNumberAtoms(alist);
04218            
04219            /* Check to see if we need to build the surface */
04220     if (acc->surf == VNULL) {
04221         acc->surf = Vmem_malloc(acc->mem, natom, sizeof(VaccSurf *));
04222         for (i=0; i<natom; i++) {
04223             atom = Valist_getAtom(acc->alist, i);
04224             apos = Vatom_getPosition(atom);
04225             /* NOTE:  RIGHT NOW WE DO THIS FOR THE ENTIRE MOLECULE WHICH IS
04226                                   * INCREDIBLY INEFFICIENT, PARTICULARLY DURING FOCUSING!!! */
04227             acc->surf[i] = Vacc_atomSurf(acc, atom, acc->refSphere, srad);
04228         }
04229     }
04230            
04231            if(apolparm->calcforce == ACF_TOTAL){
04232                       *nforce = 1;
04233                       if(*atomForce == VNULL){
04234                                  *atomForce = (AtomForce *)Vmem_malloc(mem, *nforce,
04235                                                                                                                            sizeof(AtomForce));
04236                       }else{
04237                                  Vmem_free(mem,*nforce,sizeof(AtomForce), (void **)atomForce);
04238                                  *atomForce = (AtomForce *)Vmem_malloc(mem, *nforce,
04239                                                                                                                                       sizeof(AtomForce));
04240                       }
04241                       
04242                       /* Clear out force arrays */
04243                       for (j=0; j<3; j++) {
04244                                  (*atomForce)[0].sasaForce[j] = 0.0;
04245                                  (*atomForce)[0].savForce[j] = 0.0;
04246                                  (*atomForce)[0].wcaForce[j] = 0.0;
04247                       }
04248                       
04249                       for (i=0; i<natom; i++) {
04250                                  atom = Valist_getAtom(alist, i);
04251                                  
04252                                  for(j=0;j<3;j++){
04253                                             dSASA[j] = 0.0;
04254                                             dSAV[j] = 0.0;
04255                                             force[j] = 0.0;
04256                                  }
04257                                  
04258                                  if(VABS(gamma) > VSMALL) Vacc_atomdSASA(acc, offset, srad, atom, dSASA);
04259                                  if(VABS(press) > VSMALL) Vacc_atomdSAV(acc, srad, atom, dSAV);
04260                                  if(VABS(bconc) > VSMALL) Vacc_wcaForceAtom(acc, apolparm, clist, atom, force);
04261                                  
04262                                  for(j=0;j<3;j++){
04263                                             (*atomForce)[0].sasaForce[j] += dSASA[j];
04264                                             (*atomForce)[0].savForce[j] += dSAV[j];
04265                                             (*atomForce)[0].wcaForce[j] += force[j];
04266                                  }
04267                       }
04268                       
04269                       Vnm_tprint( 1, "  Printing net forces (kJ/mol/A)\n");
04270                       Vnm_tprint( 1, "  Legend:\n");
04271                       Vnm_tprint( 1, "    sasa  -- SASA force\n");
04272                       Vnm_tprint( 1, "    sav   -- SAV force\n");
04273                       Vnm_tprint( 1, "    wca   -- WCA force\n\n");
04274                                             
04275                       Vnm_tprint( 1, "  sasa  %4.3e %4.3e %4.3e\n",
04276                                                        (*atomForce)[0].sasaForce[0],
04277                                                        (*atomForce)[0].sasaForce[1],
04278                                                        (*atomForce)[0].sasaForce[2]);
04279                       Vnm_tprint( 1, "  sav   %4.3e %4.3e %4.3e\n",
04280                                                        (*atomForce)[0].savForce[0],
04281                                                        (*atomForce)[0].savForce[1],
04282                                                        (*atomForce)[0].savForce[2]);
04283                       Vnm_tprint( 1, "  wca   %4.3e %4.3e %4.3e\n",
04284                                                        (*atomForce)[0].wcaForce[0],
04285                                                        (*atomForce)[0].wcaForce[1],
04286                                                        (*atomForce)[0].wcaForce[2]);
04287                       
04288            } else if (apolparm->calcforce == ACF_COMPS ){
04289                       *nforce = Valist_getNumberAtoms(alist);
04290                       if(*atomForce == VNULL){
04291                                  *atomForce = (AtomForce *)Vmem_malloc(mem, *nforce,
04292                                                                                                                                       sizeof(AtomForce));
04293                       }else{
04294                                  Vmem_free(mem,*nforce,sizeof(AtomForce), (void **)atomForce);
04295                                  *atomForce = (AtomForce *)Vmem_malloc(mem, *nforce,
04296                                                                                                                                       sizeof(AtomForce));
04297                       }
04298 
04299 #ifndef VAPBSQUIET
04300                       Vnm_tprint( 1, "  Printing per atom forces (kJ/mol/A)\n");
04301                       Vnm_tprint( 1, "  Legend:\n");
04302                       Vnm_tprint( 1, "    tot  n -- Total force for atom n\n");
04303                       Vnm_tprint( 1, "    sasa n -- SASA force for atom n\n");
04304                       Vnm_tprint( 1, "    sav  n -- SAV force for atom n\n");
04305                       Vnm_tprint( 1, "    wca  n -- WCA force for atom n\n\n");
04306                       
04307                       Vnm_tprint( 1, "    gamma    %f\n" \
04308                                                           "    pressure %f\n" \
04309                                                           "    bconc    %f \n\n",
04310                                                                              gamma,press,bconc);
04311 #endif
04312                       
04313                       for (i=0; i<natom; i++) {
04314                                  atom = Valist_getAtom(alist, i);
04315                                  
04316                                  for(j=0;j<3;j++){
04317                                             dSASA[j] = 0.0;
04318                                             dSAV[j] = 0.0;
04319                                             force[j] = 0.0;
04320                                  }
04321                                  
04322                                  /* Clear out force arrays */
04323                                  for (j=0; j<3; j++) {
04324                                             (*atomForce)[i].sasaForce[j] = 0.0;
04325                                             (*atomForce)[i].savForce[j] = 0.0;
04326                                             (*atomForce)[i].wcaForce[j] = 0.0;
04327                                  }
04328                                  
04329                                  if(VABS(gamma) > VSMALL) Vacc_atomdSASA(acc, offset, srad, atom, dSASA);
04330                                  if(VABS(press) > VSMALL) Vacc_atomdSAV(acc, srad, atom, dSAV);
04331                                  if(VABS(bconc) > VSMALL) Vacc_wcaForceAtom(acc,apolparm,clist,atom,force);
04332                                             
04333                                  xF = -((gamma*dSASA[0]) + (press*dSAV[0]) + (bconc*force[0]));
04334                                  yF = -((gamma*dSASA[1]) + (press*dSAV[1]) + (bconc*force[1]));
04335                                  zF = -((gamma*dSASA[2]) + (press*dSAV[2]) + (bconc*force[2]));
04336                                  
04337                                  for(j=0;j<3;j++){
04338                                             (*atomForce)[i].sasaForce[j] += dSASA[j];
04339                                             (*atomForce)[i].savForce[j] += dSAV[j];
04340                                             (*atomForce)[i].wcaForce[j] += force[j];
04341                                  }
04342                                  
04343 #ifndef VAPBSQUIET
04344                                  Vnm_print( 1, "  tot  %i %4.3e %4.3e %4.3e\n",
04345                                                                   i,
04346                                                                   xF,
04347                                                                   yF,
04348                                                                   zF);
04349                                  Vnm_print( 1, "  sasa %i %4.3e %4.3e %4.3e\n",
04350                                                                   i,
04351                                                                   (*atomForce)[i].sasaForce[0],
04352                                                                   (*atomForce)[i].sasaForce[1],
04353                                                                   (*atomForce)[i].sasaForce[2]);
04354                                  Vnm_print( 1, "  sav  %i %4.3e %4.3e %4.3e\n",
04355                                                                   i,
04356                                                                   (*atomForce)[i].savForce[0],
04357                                                                   (*atomForce)[i].savForce[1],
04358                                                                   (*atomForce)[i].savForce[2]);
04359                                  Vnm_print( 1, "  wca  %i %4.3e %4.3e %4.3e\n",
04360                                                                   i,
04361                                                                   (*atomForce)[i].wcaForce[0],
04362                                                                   (*atomForce)[i].wcaForce[1],
04363                                                                   (*atomForce)[i].wcaForce[2]);
04364 #endif
04365                                  
04366                       }
04367            } else *nforce = 0;
04368            
04369 #ifndef VAPBSQUIET
04370            Vnm_print(1,"\n");
04371 #endif
04372            
04373            return VRC_SUCCESS;
04374 }
04375 
04376 

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