00001
00067 #include "apbscfg.h"
00068 #include "apbs/apbs.h"
00069 #include "apbs/nosh.h"
00070 #include "apbs/mgparm.h"
00071 #include "apbs/pbeparm.h"
00072 #include "apbs/femparm.h"
00073
00074 #include "routines.h"
00075
00076 VEMBED(rcsid="$Id: main.c 1595 2010-08-24 15:26:42Z yhuang01 $")
00077
00078
00084 int main(
00085 int argc,
00086 char **argv
00087 )
00088 {
00089
00090 NOsh *nosh = VNULL;
00091
00092 MGparm *mgparm = VNULL;
00093 FEMparm *feparm = VNULL;
00094 PBEparm *pbeparm = VNULL;
00095 APOLparm *apolparm = VNULL;
00096 Vparam *param = VNULL;
00097
00098 Vmem *mem = VNULL;
00099 Vcom *com = VNULL;
00100 Vio *sock = VNULL;
00101 #ifdef HAVE_MC_H
00102 Vfetk *fetk[NOSH_MAXCALC];
00103 Gem *gm[NOSH_MAXMOL];
00104 #else
00105 void *fetk[NOSH_MAXCALC];
00106 void *gm[NOSH_MAXMOL];
00107 #endif
00108 Vpmg *pmg[NOSH_MAXCALC];
00109 Vpmgp *pmgp[NOSH_MAXCALC];
00110 Vpbe *pbe[NOSH_MAXCALC];
00111 Valist *alist[NOSH_MAXMOL];
00112 Vgrid *dielXMap[NOSH_MAXMOL],*dielYMap[NOSH_MAXMOL],*dielZMap[NOSH_MAXMOL];
00113 Vgrid *kappaMap[NOSH_MAXMOL];
00114 Vgrid *potMap[NOSH_MAXMOL];
00115 Vgrid *chargeMap[NOSH_MAXMOL];
00116 char *input_path = VNULL;
00117 char *output_path = VNULL;
00118 int i, rank, size, isolve, k;
00119 size_t bytesTotal, highWater;
00120 Voutput_Format outputformat;
00121
00122 int rc = 0;
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133 double qfEnergy[NOSH_MAXCALC], qmEnergy[NOSH_MAXCALC];
00134 double dielEnergy[NOSH_MAXCALC], totEnergy[NOSH_MAXCALC];
00135 AtomForce *atomForce[NOSH_MAXCALC];
00136 double *atomEnergy[NOSH_MAXCALC];
00137 int nenergy[NOSH_MAXCALC], nforce[NOSH_MAXCALC];
00138
00139 double realCenter[3];
00140
00141
00142 char header[] = {"\n\n\
00143 ----------------------------------------------------------------------\n\
00144 APBS -- Adaptive Poisson-Boltzmann Solver\n\
00145 Version 1.3\n\
00146 \n\
00147 Nathan A. Baker (baker@biochem.wustl.edu)\n\
00148 Dept. Biochemistry and Molecular Biophysics\n\
00149 Center for Computational Biology\n\
00150 Washington University in St. Louis\n\
00151 \n\
00152 Additional contributing authors listed in the code documentation.\n\
00153 \n\
00154 Copyright (c) 2002-2010, Washington University in St. Louis.\n\
00155 Portions Copyright (c) 2002-2010. Nathan A. Baker\n\
00156 Portions Copyright (c) 1999-2002. The Regents of the University of California.\n\
00157 Portions Copyright (c) 1995. Michael Holst\n\
00158 \n\
00159 All rights reserved.\n\
00160 \n\
00161 Redistribution and use in source and binary forms, with or without\n\
00162 modification, are permitted provided that the following conditions are met: \n\
00163 \n\
00164 * Redistributions of source code must retain the above copyright notice, this\n\
00165 list of conditions and the following disclaimer. \n\
00166 \n\
00167 * Redistributions in binary form must reproduce the above copyright notice,\n\
00168 this list of conditions and the following disclaimer in the documentation\n\
00169 and/or other materials provided with the distribution.\n\
00170 \n\
00171 * Neither the name of Washington University in St. Louis nor the names of its\n\
00172 contributors may be used to endorse or promote products derived from this\n\
00173 software without specific prior written permission.\n\
00174 \n\
00175 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n\
00176 \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n\
00177 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n\
00178 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR\n\
00179 CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\n\
00180 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n\
00181 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\n\
00182 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\n\
00183 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\n\
00184 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n\
00185 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\
00186 ----------------------------------------------------------------------\n\
00187 APBS uses FETK (the Finite Element ToolKit) to solve the\n\
00188 Poisson-Boltzmann equation numerically. FETK is a portable collection\n\
00189 of finite element modeling class libraries developed by the Michael Holst\n\
00190 research group and written in an object-oriented form of C. FEtk is\n\
00191 designed to solve general coupled systems of nonlinear partial differential\n\
00192 equations using adaptive finite element methods, inexact Newton methods,\n\
00193 and algebraic multilevel methods. More information about FEtk may be found\n\
00194 at <http://www.FEtk.ORG>.\n\
00195 ----------------------------------------------------------------------\n\
00196 APBS also uses Aqua to solve the Poisson-Boltzmann equation numerically. \n\
00197 Aqua is a modified form of the Holst group PMG library <http://www.FEtk.ORG>\n\
00198 which has been modified by Patrice Koehl\n\
00199 <http://koehllab.genomecenter.ucdavis.edu/> for improved efficiency and\n\
00200 memory usage when solving the Poisson-Boltzmann equation.\n\
00201 ----------------------------------------------------------------------\n\
00202 Please cite your use of APBS as:\n\n\
00203 Baker NA, Sept D, Joseph S, Holst MJ, McCammon JA. Electrostatics of\n\
00204 nanosystems: application to microtubules and the ribosome. Proc.\n\
00205 Natl. Acad. Sci. USA 98, 10037-10041 2001.\n\
00206 \n\n"};
00207 char *usage =
00208 {"\n\n\
00209 ----------------------------------------------------------------------\n\
00210 This driver program calculates electrostatic potentials, energies,\n\
00211 and forces using both multigrid and finite element methods.\n\
00212 It is invoked as:\n\n\
00213 apbs [options] apbs.in\n\n\
00214 where apbs.in is a formatted input file and [options] are:\n\n\
00215 --output-file=<name> Enables output logging to the path\n\
00216 listed in <name>. Uses flat-file\n\
00217 format is --output-format is not used.\n\
00218 --output-format=<type> Specifies format for logging. Options\n\
00219 for type are either \"xml\" or \"flat\".\n\
00220 --help Display this help information.\n\
00221 --version Display the current APBS version.\n\
00222 ----------------------------------------------------------------------\n\n"};
00223
00224
00225 VASSERT(Vcom_init(&argc, &argv));
00226 com = Vcom_ctor(1);
00227 rank = Vcom_rank(com);
00228 size = Vcom_size(com);
00229 startVio();
00230 Vnm_setIoTag(rank, size);
00231 Vnm_tprint( 0, "Hello world from PE %d\n", rank);
00232
00233
00234 mem = Vmem_ctor("MAIN");
00235 for (i=0; i<NOSH_MAXCALC; i++) {
00236 pmg[i] = VNULL;
00237 pmgp[i] = VNULL;
00238 fetk[i] = VNULL;
00239 pbe[i] = VNULL;
00240 qfEnergy[i] = 0;
00241 qmEnergy[i] = 0;
00242 dielEnergy[i] = 0;
00243 totEnergy[i] = 0;
00244 atomForce[i] = VNULL;
00245 nenergy[i] = 0;
00246 nforce[i] = 0;
00247 }
00248 for (i=0; i<NOSH_MAXMOL; i++) {
00249 alist[i] = VNULL;
00250 dielXMap[i] = VNULL;
00251 dielYMap[i] = VNULL;
00252 dielZMap[i] = VNULL;
00253 kappaMap[i] = VNULL;
00254 potMap[i] = VNULL;
00255 chargeMap[i] = VNULL;
00256 }
00257
00258
00259 Vnm_tstart(APBS_TIMER_WALL_CLOCK, "APBS WALL CLOCK");
00260 Vnm_tprint( 1, "%s", header);
00261
00262 #ifdef APBS_FAST
00263 printf("WARNING: APBS was compiled with the --enable-fast option.\n"
00264 "WARNING: This mode is experimental and subject to change in future releases.\n"
00265 "WARNING: The fast mode enables: Gauess-Seidel Smoothing and \n"
00266 "WARNING: Conjugate Gradient Multigrid methods.\n\n");
00267 #endif
00268
00269 Vnm_tprint( 1, "This executable compiled on %s at %s\n\n", __DATE__, __TIME__);
00270
00271 #if defined(WITH_TINKER)
00272 Vnm_tprint( 2, "This executable was compiled with TINKER support and is not intended for stand-alone execution.\n");
00273 Vnm_tprint( 2, "Please compile another version without TINKER support.\n");
00274 exit(2);
00275 #endif
00276
00277 i=0;
00278 outputformat = OUTPUT_NULL;
00279 while (i<argc){
00280 if (strncmp(argv[i], "--", 2) == 0) {
00281
00282
00283 if (Vstring_strcasecmp("--version", argv[i]) == 0){
00284 Vnm_tprint(2, "%s\n", PACKAGE_STRING);
00285 VJMPERR1(0);
00286 } else if (Vstring_strcasecmp("--help", argv[i]) == 0){
00287 Vnm_tprint(2, "%s\n", usage);
00288 VJMPERR1(0);
00289 } else if (strncmp(argv[i], "--output-format", 15) == 0) {
00290 if (strstr(argv[i], "xml") != NULL) {
00291 Vnm_tprint(2, "XML output format is now deprecated, please use --output-format=flat instead!\n\n");
00292 VJMPERR1(0);
00293 }
00294 else if (strstr(argv[i], "flat") != NULL) {
00295 outputformat = OUTPUT_FLAT;
00296 } else {
00297 Vnm_tprint(2, "Invalid output-format type!\n");
00298 VJMPERR1(0);
00299 }
00300 } else if (strncmp(argv[i], "--output-file=", 14) == 0){
00301 output_path = strstr(argv[i], "=");
00302 ++output_path;
00303 if (outputformat == OUTPUT_NULL) outputformat = OUTPUT_FLAT;
00304 } else {
00305 Vnm_tprint(2, "UNRECOGNIZED COMMAND LINE OPTION %s!\n", argv[i]);
00306 Vnm_tprint(2, "%s\n", usage);
00307 VJMPERR1(0);
00308 }
00309 } else {
00310
00311
00312 if ((input_path == VNULL) && (i != 0)) input_path = argv[i];
00313 else if (i != 0) {
00314 Vnm_tprint(2, "ERROR -- CALLED WITH TOO MANY ARGUMENTS!\n", \
00315 argc);
00316 Vnm_tprint(2, "%s\n", usage);
00317 VJMPERR1(0);
00318 }
00319 }
00320 i++;
00321 }
00322
00323 if ((outputformat != 0) && (output_path == NULL)) {
00324 Vnm_tprint(2, "The --output-path variable must be set when using --output-format!\n");
00325 VJMPERR1(0);
00326 }
00327
00328 if (input_path == NULL) {
00329 Vnm_tprint(2, "ERROR -- APBS input file not specified!\n", argc);
00330 Vnm_tprint(2, "%s\n", usage);
00331 VJMPERR1(0);
00332 }
00333
00334
00335 if ((size > 1) && (output_path != NULL))
00336 printf(output_path, "%s_%d", output_path, rank);
00337
00338
00339 nosh = NOsh_ctor(rank, size);
00340 Vnm_tprint( 1, "Parsing input file %s...\n", input_path);
00341 sock = Vio_ctor("FILE", "ASC", VNULL, input_path, "r");
00342 if (sock == VNULL) {
00343 Vnm_tprint(2, "Error while opening input file %s!\n", input_path);
00344 VJMPERR1(0);
00345 }
00346 if (!NOsh_parseInput(nosh, sock)) {
00347 Vnm_tprint( 2, "Error while parsing input file.\n");
00348 VJMPERR1(0);
00349 } else Vnm_tprint( 1, "Parsed input file.\n");
00350 Vio_dtor(&sock);
00351
00352
00353 param = loadParameter(nosh);
00354 if (loadMolecules(nosh, param, alist) != 1) {
00355 Vnm_tprint(2, "Error reading molecules!\n");
00356 VJMPERR1(0);
00357 }
00358
00359
00360 if (NOsh_setupElecCalc(nosh, alist) != 1) {
00361 Vnm_tprint(2, "Error setting up ELEC calculations\n");
00362 VJMPERR1(0);
00363 }
00364
00365 if ((rc = NOsh_setupApolCalc(nosh, alist)) == ACD_ERROR) {
00366 Vnm_tprint(2, "Error setting up APOL calculations\n");
00367 VJMPERR1(0);
00368 }
00369
00370
00371
00372
00373
00374
00375
00376
00377 #if defined(DEBUG_MAC_OSX_OCL)
00378 #include "mach_chud.h"
00379 #include <stdint.h>
00380 uint64_t mbeg;
00381 machm_(&mbeg);
00382
00383 if(clFinish != NULL)
00384 {
00385 int ret = initOpenCL();
00386 printf("OpenCL runtime present - initialized = %i\n",ret);
00387 }
00388 else
00389 {
00390 setkOpenCLAvailable_(0);
00391 printf("OpenCL is not present!\n");
00392 }
00393 #endif
00394
00395 #if defined(DEBUG_MAC_OSX_STANDARD)
00396 #include "mach_chud.h"
00397 #include <stdint.h>
00398 uint64_t mbeg;
00399 machm_(&mbeg);
00400 #endif
00401
00402
00403 if (loadDielMaps(nosh, dielXMap, dielYMap, dielZMap) != 1) {
00404 Vnm_tprint(2, "Error reading dielectric maps!\n");
00405 VJMPERR1(0);
00406 }
00407 if (loadKappaMaps(nosh, kappaMap) != 1) {
00408 Vnm_tprint(2, "Error reading kappa maps!\n");
00409 VJMPERR1(0);
00410 }
00411 if (loadPotMaps(nosh, potMap) != 1) {
00412 Vnm_tprint(2, "Error reading potential maps!\n");
00413 VJMPERR1(0);
00414 }
00415 if (loadChargeMaps(nosh, chargeMap) != 1) {
00416 Vnm_tprint(2, "Error reading charge maps!\n");
00417 VJMPERR1(0);
00418 }
00419
00420
00421 Vnm_tprint( 1, "Preparing to run %d PBE calculations.\n",
00422 nosh->ncalc);
00423 for (i=0; i<nosh->ncalc; i++) {
00424 Vnm_tprint( 1, "----------------------------------------\n");
00425
00426 switch (nosh->calc[i]->calctype) {
00427 case NCT_MG:
00428
00429
00430 for (k=0; k<nosh->nelec; k++) {
00431 if (nosh->elec2calc[k] >= i) {
00432 break;
00433 }
00434 }
00435 if (Vstring_strcasecmp(nosh->elecname[k], "") == 0) {
00436 Vnm_tprint( 1, "CALCULATION #%d: MULTIGRID\n", i+1);
00437 } else {
00438 Vnm_tprint( 1, "CALCULATION #%d (%s): MULTIGRID\n",
00439 i+1, nosh->elecname[k]);
00440 }
00441
00442 mgparm = nosh->calc[i]->mgparm;
00443 pbeparm = nosh->calc[i]->pbeparm;
00444
00445
00446 Vnm_tprint( 1, " Setting up problem...\n");
00447
00448 if (!initMG(i, nosh, mgparm, pbeparm, realCenter, pbe,
00449 alist, dielXMap, dielYMap, dielZMap, kappaMap,
00450 chargeMap, pmgp, pmg, potMap)) {
00451 Vnm_tprint( 2, "Error setting up MG calculation!\n");
00452 VJMPERR1(0);
00453 }
00454
00455
00456 printMGPARM(mgparm, realCenter);
00457 printPBEPARM(pbeparm);
00458
00459
00460 if (solveMG(nosh, pmg[i], mgparm->type) != 1) {
00461 Vnm_tprint(2, "Error solving PDE!\n");
00462 VJMPERR1(0);
00463 }
00464
00465
00466 if (setPartMG(nosh, mgparm, pmg[i]) != 1) {
00467 Vnm_tprint(2, "Error setting partition info!\n");
00468 VJMPERR1(0);
00469 }
00470
00471
00472 energyMG(nosh, i, pmg[i],
00473 &(nenergy[i]), &(totEnergy[i]), &(qfEnergy[i]),
00474 &(qmEnergy[i]), &(dielEnergy[i]));
00475
00476
00477 forceMG(mem, nosh, pbeparm, mgparm, pmg[i], &(nforce[i]),
00478 &(atomForce[i]), alist);
00479
00480
00481 writedataMG(rank, nosh, pbeparm, pmg[i]);
00482
00483
00484 writematMG(rank, nosh, pbeparm, pmg[i]);
00485
00486
00487 nenergy[i] = 0;
00488 if ((pbeparm->calcenergy == PCE_COMPS) && (outputformat != OUTPUT_NULL)){
00489 storeAtomEnergy(pmg[i], i, &(atomEnergy[i]), &(nenergy[i]));
00490 }
00491
00492 fflush(stdout);
00493 fflush(stderr);
00494
00495 break;
00496
00497
00498 case NCT_FEM:
00499 #ifdef HAVE_MC_H
00500 for (k=0; k<nosh->nelec; k++) {
00501 if (nosh->elec2calc[k] >= i) break;
00502 }
00503 if (Vstring_strcasecmp(nosh->elecname[i+1], "") == 0) {
00504 Vnm_tprint( 1, "CALCULATION #%d: FINITE ELEMENT\n", i+1);
00505 } else {
00506 Vnm_tprint( 1, "CALCULATION #%d (%s): FINITE ELEMENT\n", i+1, nosh->elecname[k+1]);
00507 }
00508
00509
00510 feparm = nosh->calc[i]->femparm;
00511 pbeparm = nosh->calc[i]->pbeparm;
00512
00513
00514 Vnm_tprint(2, "#################### WARNING ###################\n");
00515 Vnm_tprint(2, "## FE support is currently very experimental! ##\n");
00516 Vnm_tprint(2, "#################### WARNING ###################\n");
00517
00518
00519 Vnm_tprint( 1, " Setting up problem...\n");
00520 if (initFE(i, nosh, feparm, pbeparm, pbe, alist, fetk, gm) != VRC_SUCCESS) {
00521 Vnm_tprint( 2, "Error setting up FE calculation!\n");
00522 VJMPERR1(0);
00523 }
00524
00525
00526 printFEPARM(i, nosh, feparm, fetk);
00527 printPBEPARM(pbeparm);
00528
00529
00530 if (!preRefineFE(i, nosh, feparm, fetk)) {
00531 Vnm_tprint( 2, "Error pre-refining mesh!\n");
00532 VJMPERR1(0);
00533 }
00534
00535
00536 Vnm_tprint(2, "\n\nWARNING! DO NOT EXPECT PERFORMANCE OUT OF THE APBS/FEtk\n");
00537 Vnm_tprint(2, "INTERFACE AT THIS TIME. THE FINITE ELEMENT SOLVER IS\n");
00538 Vnm_tprint(2, "CURRENTLY NOT OPTIMIZED FOR THE PB EQUATION. IF YOU WANT\n");
00539 Vnm_tprint(2, "PERFORMANCE, PLEASE USE THE MULTIGRID-BASED METHODS, E.G.\n");
00540 Vnm_tprint(2, "MG-AUTO, MG-PARA, and MG-MANUAL (SEE DOCS.)\n\n");
00541 Vnm_tprint(1, " Beginning solve-estimate-refine cycle:\n");
00542 for (isolve=0; isolve<feparm->maxsolve; isolve++) {
00543 Vnm_tprint(1, " Solve #%d...\n", isolve);
00544 if (!solveFE(i, nosh, pbeparm, feparm, fetk)) {
00545 Vnm_tprint(2, "ERROR SOLVING EQUATION!\n");
00546 VJMPERR1(0);
00547 }
00548 if (!energyFE(nosh, i, fetk, &(nenergy[i]),
00549 &(totEnergy[i]), &(qfEnergy[i]),
00550 &(qmEnergy[i]), &(dielEnergy[i]))) {
00551 Vnm_tprint(2, "ERROR SOLVING EQUATION!\n");
00552 VJMPERR1(0);
00553 }
00554
00555
00556 if (isolve < (feparm->maxsolve)-1) {
00557 if (!postRefineFE(i, nosh, feparm, fetk)) break;
00558 }
00559 bytesTotal = Vmem_bytesTotal();
00560 highWater = Vmem_highWaterTotal();
00561 Vnm_tprint(1, " Currently memory use: %g MB\n",
00562 ((double)bytesTotal/(1024.)/(1024.)));
00563 Vnm_tprint(1, " High-water memory use: %g MB\n",
00564 ((double)highWater/(1024.)/(1024.)));
00565 }
00566
00567 Vnm_tprint(1, " Writing FEM data to files.\n");
00568 if (!writedataFE(rank, nosh, pbeparm, fetk[i])) {
00569 Vnm_tprint(2, " Error while writing FEM data!\n");
00570 }
00571 #else
00572 Vnm_print(2, "Error! APBS not compiled with FEtk!\n");
00573 exit(2);
00574 #endif
00575 break;
00576
00577
00578 case NCT_APOL:
00579
00580
00581
00582 for (k=0; k<nosh->napol; k++) {
00583 if (nosh->apol2calc[k] >= i) {
00584 break;
00585 }
00586 }
00587
00588 if (Vstring_strcasecmp(nosh->apolname[k], "") == 0) {
00589 Vnm_tprint( 1, "CALCULATION #%d: APOLAR\n", i+1);
00590 } else {
00591 Vnm_tprint( 1, "CALCULATION #%d (%s): APOLAR\n",
00592 i+1, nosh->apolname[k]);
00593 }
00594
00595 apolparm = nosh->calc[i]->apolparm;
00596 rc = initAPOL(nosh, mem, param, apolparm, &(nforce[i]), &(atomForce[i]),
00597 alist[(apolparm->molid)-1]);
00598 if(rc == 0) {
00599 Vnm_tprint(2, "Error calculating apolar solvation quantities!\n");
00600 VJMPERR1(0);
00601 }
00602 break;
00603 default:
00604 Vnm_tprint(2, " Unknown calculation type (%d)!\n",
00605 nosh->calc[i]->calctype);
00606 exit(2);
00607 }
00608 }
00609
00610
00611 if(param != VNULL) Vparam_dtor(¶m);
00612
00613
00614 if (nosh->nprint > 0) {
00615 Vnm_tprint( 1, "----------------------------------------\n");
00616 Vnm_tprint( 1, "PRINT STATEMENTS\n");
00617 }
00618 for (i=0; i<nosh->nprint; i++) {
00619
00620 if (nosh->printwhat[i] == NPT_ENERGY) {
00621 printEnergy(com, nosh, totEnergy, i);
00622
00623 } else if (nosh->printwhat[i] == NPT_FORCE) {
00624 printForce(com, nosh, nforce, atomForce, i);
00625 } else if (nosh->printwhat[i] == NPT_ELECENERGY) {
00626 printElecEnergy(com, nosh, totEnergy, i);
00627 } else if (nosh->printwhat[i] == NPT_ELECFORCE) {
00628 printElecForce(com, nosh, nforce, atomForce, i);
00629 } else if (nosh->printwhat[i] == NPT_APOLENERGY) {
00630 printApolEnergy(nosh, i);
00631 } else if (nosh->printwhat[i] == NPT_APOLFORCE) {
00632 printApolForce(com, nosh, nforce, atomForce, i);
00633 } else {
00634 Vnm_tprint( 2, "Undefined PRINT keyword!\n");
00635 break;
00636 }
00637 }
00638 Vnm_tprint( 1, "----------------------------------------\n");
00639
00640
00641
00642 if (outputformat == OUTPUT_FLAT) {
00643 Vnm_tprint(2," Writing data to flat file %s...\n\n", output_path);
00644 writedataFlat(nosh, com, output_path, totEnergy, qfEnergy, qmEnergy,
00645 dielEnergy, nenergy, atomEnergy, nforce, atomForce);
00646 }
00647
00648
00649
00650 for (i=0; i<nosh->ncalc; i++) {
00651 if (nenergy[i] > 0) Vmem_free(mem, nenergy[i], sizeof(double),
00652 (void **)&(atomEnergy[i]));
00653 }
00654
00655
00656
00657 Vnm_tprint( 1, "CLEANING UP AND SHUTTING DOWN...\n");
00658
00659 killForce(mem, nosh, nforce, atomForce);
00660 killEnergy();
00661 killMG(nosh, pbe, pmgp, pmg);
00662 #ifdef HAVE_MC_H
00663 killFE(nosh, pbe, fetk, gm);
00664 #endif
00665 killChargeMaps(nosh, chargeMap);
00666 killKappaMaps(nosh, kappaMap);
00667 killDielMaps(nosh, dielXMap, dielYMap, dielZMap);
00668 killMolecules(nosh, alist);
00669 NOsh_dtor(&nosh);
00670
00671
00672 bytesTotal = Vmem_bytesTotal();
00673 highWater = Vmem_highWaterTotal();
00674 Vnm_tprint( 1, "Final memory usage: %4.3f MB total, %4.3f MB high water\n",
00675 (double)(bytesTotal)/(1024.*1024.),
00676 (double)(highWater)/(1024.*1024.));
00677
00678
00679 Vcom_dtor(&com);
00680 Vmem_dtor(&mem);
00681
00682
00683 Vnm_tprint(1, "\n\n");
00684 Vnm_tprint( 1, "Thanks for using APBS!\n\n");
00685
00686 #if defined(DEBUG_MAC_OSX_OCL)
00687 mets_(&mbeg, "Main Program CL");
00688 #endif
00689 #if defined(DEBUG_MAC_OSX_STANDARD)
00690 mets_(&mbeg, "Main Program Standard");
00691 #endif
00692
00693
00694 Vnm_tstop(APBS_TIMER_WALL_CLOCK, "APBS WALL CLOCK");
00695 Vnm_flush(1);
00696 Vnm_flush(2);
00697 Vcom_finalize();
00698
00699 fflush(NULL);
00700
00701 return 0;
00702
00703 VERROR1:
00704 Vcom_finalize();
00705 Vcom_dtor(&com);
00706 Vmem_dtor(&mem);
00707 return APBSRC;
00708 }