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 }
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
00146
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
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
00194
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 }
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:
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){
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
00964 for (j=0; j<3; j++) realCenter[j] = mgparm->center[j];
00965
00966
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
00974
00975
00976
00977
00978
00979
00980
00981
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
01003 Vnm_tprint(0, "Setting up PDE object...\n");
01004 switch (pbeparm->pbetype) {
01005 case PBE_NPBE:
01006
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
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:
01026 mgparm->nonlintype = NONLIN_SMPBE;
01027 pmgp[icalc] = Vpmgp_ctor(mgparm);
01028
01029
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
01051
01052 pmg[icalc] = Vpmg_ctor(pmgp[icalc], pbe[icalc], 1, pmg[icalc-1],
01053 mgparm, pbeparm->calcenergy);
01054
01055
01056
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
01140 #ifndef VAPBSQUIET
01141 Vnm_tprint(1, " Debye length: %g A\n", Vpbe_getDeblen(pbe[icalc]));
01142 #endif
01143
01144
01145 Vnm_tstop(APBS_TIMER_SETUP, "Setup timer");
01146
01147
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
01172
01173
01174
01175
01176
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
01253
01254
01255
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
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
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
01527 if (pbeparm->writematflag == 0) {
01528 Vnm_tprint( 1, " Writing Poisson operator matrix \
01529 to %s...\n", outpath);
01530
01531
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
01544
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
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
01604
01605 now = time(VNULL);
01606 timestring = ctime(&now);
01607 fprintf(file,"%s\n", timestring);
01608
01609 for (ielec=0; ielec<nosh->nelec;ielec++) {
01610
01611
01612
01613 mgparm = nosh->calc[icalc]->mgparm;
01614 pbeparm = nosh->calc[icalc]->pbeparm;
01615
01616
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++){
01709
01710
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
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
01784 if (nosh->printop[i][j-1] == 0) scalar = 1.0;
01785 else if (nosh->printop[i][j-1] == 1) scalar = -1.0;
01786
01787 ltenergy += (scalar * Vunit_kb * (1e-3) * Vunit_Na *
01788 nosh->calc[icalc]->pbeparm->temp * totEnergy[icalc]);
01789
01790 Vcom_reduce(com, <energy, >energy, 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
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
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++){
01849
01850
01851
01852 mgparm = nosh->calc[icalc]->mgparm;
01853 pbeparm = nosh->calc[icalc]->pbeparm;
01854
01855
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++){
01955
01956
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
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
02042 if (nosh->printop[i][j-1] == 0) scalar = 1.0;
02043 else if (nosh->printop[i][j-1] == 1) scalar = -1.0;
02044
02045 ltenergy += (scalar * Vunit_kb * (1e-3) * Vunit_Na *
02046 nosh->calc[icalc]->pbeparm->temp * totEnergy[icalc]);
02047 }
02048 Vcom_reduce(com, <energy, >energy, 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
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
02424 if (nosh->printop[iprint][iarg-1] == 0) scalar = 1.0;
02425 else if (nosh->printop[iprint][iarg-1] == 1) scalar = -1.0;
02426
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
02479 if (nosh->printop[iprint][iarg-1] == 0) scalar = 1.0;
02480 else if (nosh->printop[iprint][iarg-1] == 1) scalar = -1.0;
02481
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, <energy, >energy, 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
02538 if (nosh->printop[iprint][iarg-1] == 0) scalar = 1.0;
02539 else if (nosh->printop[iprint][iarg-1] == 1) scalar = -1.0;
02540
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, <energy, >energy, 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
02601 if (nosh->printop[iprint][iarg-1] == 0) scalar = 1.0;
02602 else if (nosh->printop[iprint][iarg-1] == 1) scalar = -1.0;
02603
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
02651
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
02677 lforce = (AtomForce *)Vmem_malloc(VNULL, refnforce, sizeof(AtomForce));
02678 gforce = (AtomForce *)Vmem_malloc(VNULL, refnforce, sizeof(AtomForce));
02679
02680
02681 calcid = nosh->elec2calc[nosh->printcalc[iprint][0]];
02682 aforce = atomForce[calcid];
02683 temp = nosh->calc[calcid]->pbeparm->temp;
02684
02685
02686 if (refcalcforce == PCF_TOTAL) {
02687
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
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
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
02719 if (refcalcforce == PCF_TOTAL) {
02720
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
02884
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
02910 lforce = (AtomForce *)Vmem_malloc(VNULL, refnforce, sizeof(AtomForce));
02911 gforce = (AtomForce *)Vmem_malloc(VNULL, refnforce, sizeof(AtomForce));
02912
02913
02914 calcid = nosh->elec2calc[nosh->printcalc[iprint][0]];
02915 aforce = atomForce[calcid];
02916 temp = nosh->calc[calcid]->pbeparm->temp;
02917
02918
02919 if (refcalcforce == PCF_TOTAL) {
02920
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
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
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
02952 if (refcalcforce == PCF_TOTAL) {
02953
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
03117
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
03143 lforce = (AtomForce *)Vmem_malloc(VNULL, refnforce, sizeof(AtomForce));
03144 gforce = (AtomForce *)Vmem_malloc(VNULL, refnforce, sizeof(AtomForce));
03145
03146
03147 calcid = nosh->apol2calc[nosh->printcalc[iprint][0]];
03148 aforce = atomForce[calcid];
03149 temp = nosh->calc[calcid]->apolparm->temp;
03150
03151
03152 if (refcalcforce == ACF_TOTAL) {
03153
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
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
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
03179 if (refcalcforce == ACF_TOTAL) {
03180
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
03238
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
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
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
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
03344
03345
03346
03347
03348
03349
03350
03351
03352 #ifdef USE_HB
03353 feparm->pkey = 1;
03354 #else
03355 feparm->pkey = 0;
03356 #endif
03357
03358
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
03373 Vnm_tprint(1, " Debye length: %g A\n", Vpbe_getDeblen(pbe[icalc]));
03374
03375
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
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 {
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
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
03450 Vnm_tstop(27, "Setup timer");
03451
03452
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
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) ) {
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
03684
03685
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
03725 if (nosh->bogus == 0) {
03726 if ((pbeparm->pbetype==PBE_NPBE)||(pbeparm->pbetype==PBE_NRPBE)||(pbeparm->pbetype == PBE_SMPBE) ) {
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
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;
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
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
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
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
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
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
04086 sasa = 0.0;
04087 sav = 0.0;
04088
04089 if (apolparm->calcenergy) {
04090 if (VABS(apolparm->gamma) > VSMALL) {
04091
04092 apolparm->sasa = Vacc_totalSASA(acc, srad);
04093
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
04100 apolparm->sasa = 0.0;
04101
04102 for (i = 0; i < Valist_getNumberAtoms(alist); i++) {
04103 atom = Valist_getAtom(alist, i);
04104 atomsasa[i] = 0.0;
04105 }
04106 }
04107
04108
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
04116 if (VABS(apolparm->bconc) > VSMALL) {
04117
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
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;
04202 double xF, yF, zF;
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
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
04226
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
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
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