APBS  1.4.1
main.c
Go to the documentation of this file.
1 
68 #include <time.h>
69 
70 #include "routines.h"
71 
72 VEMBED(rcsid="$Id$")
73 
74 
80 int main(
81  int argc,
82  char **argv
83  )
84 {
85  // PCE: Adding below variables temporarily
86  clock_t ts, te;
87  // End PCE
88 
89  NOsh *nosh = VNULL;
90 
91  MGparm *mgparm = VNULL;
92  FEMparm *feparm = VNULL;
93  PBEparm *pbeparm = VNULL;
94  APOLparm *apolparm = VNULL;
95  Vparam *param = VNULL;
96 
97  Vmem *mem = VNULL;
98  Vcom *com = VNULL;
99  Vio *sock = VNULL;
100 #ifdef HAVE_MC_H
101  Vfetk *fetk[NOSH_MAXCALC];
102  Gem *gm[NOSH_MAXMOL];
103  int isolve;
104 #else
105  void *fetk[NOSH_MAXCALC];
106  void *gm[NOSH_MAXMOL];
107 #endif
108  Vpmg *pmg[NOSH_MAXCALC];
109  Vpmgp *pmgp[NOSH_MAXCALC];
110  Vpbe *pbe[NOSH_MAXCALC];
112  Vgrid *dielXMap[NOSH_MAXMOL],
113  *dielYMap[NOSH_MAXMOL],
114  *dielZMap[NOSH_MAXMOL],
115  *kappaMap[NOSH_MAXMOL],
116  *potMap[NOSH_MAXMOL],
117  *chargeMap[NOSH_MAXMOL];
118  char *input_path = VNULL,
119  *output_path = VNULL;
120  int i,
121  rank,
122  size,
123  k;
124  size_t bytesTotal,
125  highWater;
126  Voutput_Format outputformat;
127 
128  int rc = 0;
129 
130  /* The energy double arrays below store energies from various calculations. */
131  double qfEnergy[NOSH_MAXCALC],
132  qmEnergy[NOSH_MAXCALC];
133  double dielEnergy[NOSH_MAXCALC],
134  totEnergy[NOSH_MAXCALC];
135  double *atomEnergy[NOSH_MAXCALC];
136  AtomForce *atomForce[NOSH_MAXCALC]; /* Stores forces from various calculations. */
137  int nenergy[NOSH_MAXCALC], /* Stores either a flag (0,1) displaying whether
138  * energies were calculated, or, if PCE_COMPS
139  * was used, the number of atom energies stored
140  * for the given calculation. */
141  nforce[NOSH_MAXCALC]; /* Stores an integer which either says no
142  * calculation was performed (0) or gives the
143  * number of entries in the force array for each
144  * calculation. */
145 
146  /* The real partition centers */
147  double realCenter[3];
148 
149  /* Instructions: */
150  char header[] = {"\n\n\
151 ----------------------------------------------------------------------\n\
152  APBS -- Adaptive Poisson-Boltzmann Solver\n\
153  Version " PACKAGE_STRING "\n\
154  \n\
155  Nathan A. Baker (nathan.baker@pnnl.gov)\n\
156  Pacific Northwest National Laboratory\n\
157  \n\
158  Additional contributing authors listed in the code documentation.\n\
159  \n\
160  Copyright (c) 2010-2012 Battelle Memorial Institute. Developed at the Pacific\n\
161  Northwest National Laboratory, operated by Battelle Memorial Institute, Pacific\n\
162  Northwest Division for the U.S. Department of Energy.\n\
163  \n\
164  Portions Copyright (c) 2002-2010, Washington University in St. Louis.\n\
165  Portions Copyright (c) 2002-2010, Nathan A. Baker.\n\
166  Portions Copyright (c) 1999-2002, The Regents of the University of California.\n\
167  Portions Copyright (c) 1995, Michael Holst.\n\
168  All rights reserved.\n\
169  \n\
170  Redistribution and use in source and binary forms, with or without\n\
171  modification, are permitted provided that the following conditions are met:\n\
172  \n\
173  * Redistributions of source code must retain the above copyright notice, this\n\
174  list of conditions and the following disclaimer.\n\
175  \n\
176  * Redistributions in binary form must reproduce the above copyright notice,\n\
177  this list of conditions and the following disclaimer in the documentation\n\
178  and/or other materials provided with the distribution.\n\
179  \n\
180  * Neither the name of the developer nor the names of its contributors may be\n\
181  used to endorse or promote products derived from this software without\n\
182  specific prior written permission.\n\
183  \n\
184  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND\n\
185  ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\n\
186  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\n\
187  DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR\n\
188  ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n\
189  (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\n\
190  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\n\
191  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n\
192  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n\
193  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\
194 ----------------------------------------------------------------------\n\
195  APBS uses FETK (the Finite Element ToolKit) to solve the\n\
196  Poisson-Boltzmann equation numerically. FETK is a portable collection\n\
197  of finite element modeling class libraries developed by the Michael Holst\n\
198  research group and written in an object-oriented form of C. FEtk is\n\
199  designed to solve general coupled systems of nonlinear partial differential\n\
200  equations using adaptive finite element methods, inexact Newton methods,\n\
201  and algebraic multilevel methods. More information about FEtk may be found\n\
202  at <http://www.FEtk.ORG>.\n\
203 ----------------------------------------------------------------------\n\
204  APBS also uses Aqua to solve the Poisson-Boltzmann equation numerically. \n\
205  Aqua is a modified form of the Holst group PMG library <http://www.FEtk.ORG>\n\
206  which has been modified by Patrice Koehl\n\
207  <http://koehllab.genomecenter.ucdavis.edu/> for improved efficiency and\n\
208  memory usage when solving the Poisson-Boltzmann equation.\n\
209 ----------------------------------------------------------------------\n\
210  Please cite your use of APBS as:\n\n\
211  Baker NA, Sept D, Joseph S, Holst MJ, McCammon JA. Electrostatics of\n\
212  nanosystems: application to microtubules and the ribosome. Proc.\n\
213  Natl. Acad. Sci. USA 98, 10037-10041 2001.\n\
214  \n\n"};
215  char *usage =
216 {"\n\n\
217 ----------------------------------------------------------------------\n\
218  This driver program calculates electrostatic potentials, energies,\n\
219  and forces using both multigrid and finite element methods.\n\
220  It is invoked as:\n\n\
221  apbs [options] apbs.in\n\n\
222  where apbs.in is a formatted input file and [options] are:\n\n\
223 --output-file=<name> Enables output logging to the path\n\
224  listed in <name>. Uses flat-file\n\
225  format is --output-format is not used.\n\
226 --output-format=<type> Specifies format for logging. Options\n\
227  for type are either \"xml\" or \"flat\".\n\
228 --help Display this help information.\n\
229 --version Display the current APBS version.\n\
230 ----------------------------------------------------------------------\n\n"};
231 
232  /* ************** CHECK PARALLEL STATUS *************** */
233  VASSERT(Vcom_init(&argc, &argv));
234  com = Vcom_ctor(1);
235  rank = Vcom_rank(com);
236  size = Vcom_size(com);
237  startVio();
238  Vnm_setIoTag(rank, size);
239  Vnm_tprint( 0, "Hello world from PE %d\n", rank);
240 
241  /* A bit of array/pointer initialization */
242  mem = Vmem_ctor("MAIN");
243  for (i=0; i<NOSH_MAXCALC; i++) {
244  pmg[i] = VNULL;
245  pmgp[i] = VNULL;
246  fetk[i] = VNULL;
247  pbe[i] = VNULL;
248  qfEnergy[i] = 0;
249  qmEnergy[i] = 0;
250  dielEnergy[i] = 0;
251  totEnergy[i] = 0;
252  atomForce[i] = VNULL;
253  nenergy[i] = 0;
254  nforce[i] = 0;
255  }
256  for (i=0; i<NOSH_MAXMOL; i++) {
257  alist[i] = VNULL;
258  dielXMap[i] = VNULL;
259  dielYMap[i] = VNULL;
260  dielZMap[i] = VNULL;
261  kappaMap[i] = VNULL;
262  potMap[i] = VNULL;
263  chargeMap[i] = VNULL;
264  }
265 
266  /* ********* CHECK INVOCATION AND OPTIONS ************* */
267  Vnm_tstart(APBS_TIMER_WALL_CLOCK, "APBS WALL CLOCK");
268  Vnm_tprint( 1, "%s", header);
269 
270 #ifdef APBS_FAST
271  Vnm_tprint(, 2"WARNING: APBS was compiled with the --enable-fast option.\n"
272  "WARNING: This mode is experimental and subject to change in future releases.\n"
273  "WARNING: The fast mode enables: Gauess-Seidel Smoothing and \n"
274  "WARNING: Conjugate Gradient Multigrid methods.\n\n");
275 #endif
276 
277  Vnm_tprint( 1, "This executable compiled on %s at %s\n\n", __DATE__, __TIME__);
278 
279 #if defined(WITH_TINKER)
280  Vnm_tprint( 2, "This executable was compiled with TINKER support and is not intended for stand-alone execution.\n");
281  Vnm_tprint( 2, "Please compile another version without TINKER support.\n");
282  exit(2);
283 #endif
284 
285  /* Process program arguments */
286  i=0;
287  outputformat = OUTPUT_NULL;
288  while (i<argc){
289  if (strncmp(argv[i], "--", 2) == 0) {
290 
291  /* Long Options */
292  if (Vstring_strcasecmp("--version", argv[i]) == 0){
293  Vnm_tprint(2, "%s\n", PACKAGE_STRING);
294  VJMPERR1(0);
295  } else if (Vstring_strcasecmp("--help", argv[i]) == 0){
296  Vnm_tprint(2, "%s\n", usage);
297  VJMPERR1(0);
298  } else if (strncmp(argv[i], "--output-format", 15) == 0) {
299  if (strstr(argv[i], "xml") != NULL) {
300  Vnm_tprint(2, "XML output format is now deprecated, please use --output-format=flat instead!\n\n");
301  VJMPERR1(0);
302  }
303  else if (strstr(argv[i], "flat") != NULL) {
304  outputformat = OUTPUT_FLAT;
305  } else {
306  Vnm_tprint(2, "Invalid output-format type!\n");
307  VJMPERR1(0);
308  }
309  } else if (strncmp(argv[i], "--output-file=", 14) == 0){
310  output_path = strstr(argv[i], "=");
311  ++output_path;
312  if (outputformat == OUTPUT_NULL) outputformat = OUTPUT_FLAT;
313  } else {
314  Vnm_tprint(2, "UNRECOGNIZED COMMAND LINE OPTION %s!\n", argv[i]);
315  Vnm_tprint(2, "%s\n", usage);
316  VJMPERR1(0);
317  }
318  } else {
319 
320  /* Set the path to the input file */
321  if ((input_path == VNULL) && (i != 0))
322  input_path = argv[i];
323  else if (i != 0) {
324  Vnm_tprint(2, "ERROR -- CALLED WITH TOO MANY ARGUMENTS!\n", \
325  argc);
326  Vnm_tprint(2, "%s\n", usage);
327  VJMPERR1(0);
328  }
329  }
330  i++;
331  }
332 
333  /* If we set an output format but no path, error. */
334  if ((outputformat != 0) && (output_path == NULL)) {
335  Vnm_tprint(2, "The --output-path variable must be set when using --output-format!\n");
336  VJMPERR1(0);
337  }
338 
339  /* If we failed to specify an input file, error. */
340  if (input_path == NULL) {
341  Vnm_tprint(2, "ERROR -- APBS input file not specified!\n", argc);
342  Vnm_tprint(2, "%s\n", usage);
343  VJMPERR1(0);
344  }
345 
346  /* Append rank info if a parallel run */
347  if ((size > 1) && (output_path != NULL))
348  printf(output_path, "%s_%d", output_path, rank);
349 
350  /* *************** PARSE INPUT FILE ******************* */
351  nosh = NOsh_ctor(rank, size);
352  Vnm_tprint( 1, "Parsing input file %s...\n", input_path);
353  sock = Vio_ctor("FILE", "ASC", VNULL, input_path, "r");
354  if (sock == VNULL) {
355  Vnm_tprint(2, "Error while opening input file %s!\n", input_path);
356  VJMPERR1(0);
357  }
358  if (!NOsh_parseInput(nosh, sock)) {
359  Vnm_tprint( 2, "Error while parsing input file.\n");
360  VJMPERR1(0);
361  }
362  else
363  Vnm_tprint( 1, "Parsed input file.\n");
364  Vio_dtor(&sock);
365 
366  /* *************** LOAD PARAMETERS AND MOLECULES ******************* */
367  param = loadParameter(nosh);
368  if (loadMolecules(nosh, param, alist) != 1) {
369  Vnm_tprint(2, "Error reading molecules!\n");
370  VJMPERR1(0);
371  }
372 
373  /* *************** SETUP CALCULATIONS *************** */
374  if (NOsh_setupElecCalc(nosh, alist) != 1) {
375  Vnm_tprint(2, "Error setting up ELEC calculations\n");
376  VJMPERR1(0);
377  }
378 
379  if ((rc = NOsh_setupApolCalc(nosh, alist)) == ACD_ERROR) {
380  Vnm_tprint(2, "Error setting up APOL calculations\n");
381  VJMPERR1(0);
382  }
383 
384  /* ******************* CHECK APOL********************** */
385  /* if((nosh->gotparm == 0) && (rc == ACD_YES)){
386  Vnm_print(1,"\nError you must provide a parameter file if you\n" \
387  " are performing an APOLAR calculation\n");
388  VJMPERR1(0);
389  } */
390 
391 #if defined(DEBUG_MAC_OSX_OCL)
392 #include "mach_chud.h"
393 #include <stdint.h>
394  uint64_t mbeg;
395  machm_(&mbeg);
396 
397  if(clFinish != NULL)
398  {
399  int ret = initOpenCL();
400  printf("OpenCL runtime present - initialized = %i\n",ret);
401  }
402  else
403  {
404  setkOpenCLAvailable_(0);
405  printf("OpenCL is not present!\n");
406  }
407 #endif
408 
409 #if defined(DEBUG_MAC_OSX_STANDARD)
410 #include "mach_chud.h"
411 #include <stdint.h>
412  uint64_t mbeg;
413  machm_(&mbeg);
414 #endif
415 
416  /* *************** LOAD MAPS ******************* */
417  if (loadDielMaps(nosh, dielXMap, dielYMap, dielZMap) != 1) {
418  Vnm_tprint(2, "Error reading dielectric maps!\n");
419  VJMPERR1(0);
420  }
421  if (loadKappaMaps(nosh, kappaMap) != 1) {
422  Vnm_tprint(2, "Error reading kappa maps!\n");
423  VJMPERR1(0);
424  }
425  if (loadPotMaps(nosh, potMap) != 1) {
426  Vnm_tprint(2, "Error reading potential maps!\n");
427  VJMPERR1(0);
428  }
429  if (loadChargeMaps(nosh, chargeMap) != 1) {
430  Vnm_tprint(2, "Error reading charge maps!\n");
431  VJMPERR1(0);
432  }
433 
434  /* *************** DO THE CALCULATIONS ******************* */
435  Vnm_tprint( 1, "Preparing to run %d PBE calculations.\n",
436  nosh->ncalc);
437  for (i=0; i<nosh->ncalc; i++) {
438  Vnm_tprint( 1, "----------------------------------------\n");
439 
440  switch (nosh->calc[i]->calctype) {
441  /* Multigrid */
442  case NCT_MG:
443  /* What is this? This seems like a very awkward way to find
444  the right ELEC statement... */
445  for (k=0; k<nosh->nelec; k++) {
446  if (nosh->elec2calc[k] >= i) {
447  break;
448  }
449  }
450  if (Vstring_strcasecmp(nosh->elecname[k], "") == 0) {
451  Vnm_tprint( 1, "CALCULATION #%d: MULTIGRID\n", i+1);
452  } else {
453  Vnm_tprint( 1, "CALCULATION #%d (%s): MULTIGRID\n",
454  i+1, nosh->elecname[k]);
455  }
456  /* Useful local variables */
457  mgparm = nosh->calc[i]->mgparm;
458  pbeparm = nosh->calc[i]->pbeparm;
459 
460  /* Set up problem */
461  Vnm_tprint( 1, " Setting up problem...\n");
462 
463  if (!initMG(i, nosh, mgparm, pbeparm, realCenter, pbe,
464  alist, dielXMap, dielYMap, dielZMap, kappaMap,
465  chargeMap, pmgp, pmg, potMap)) {
466  Vnm_tprint( 2, "Error setting up MG calculation!\n");
467  VJMPERR1(0);
468  }
469 
470  /* Print problem parameters */
471  printMGPARM(mgparm, realCenter);
472  printPBEPARM(pbeparm);
473 
474  /* Solve PDE */
475  if (solveMG(nosh, pmg[i], mgparm->type) != 1) {
476  Vnm_tprint(2, "Error solving PDE!\n");
477  VJMPERR1(0);
478  }
479 
480  /* Set partition information for observables and I/O */
481  if (setPartMG(nosh, mgparm, pmg[i]) != 1) {
482  Vnm_tprint(2, "Error setting partition info!\n");
483  VJMPERR1(0);
484  }
485 
486  /* Write out energies */
487  energyMG(nosh, i, pmg[i],
488  &(nenergy[i]), &(totEnergy[i]), &(qfEnergy[i]),
489  &(qmEnergy[i]), &(dielEnergy[i]));
490 
491  /* Write out forces */
492  forceMG(mem, nosh, pbeparm, mgparm, pmg[i], &(nforce[i]),
493  &(atomForce[i]), alist);
494 
495  /* Write out data folks might want */
496  writedataMG(rank, nosh, pbeparm, pmg[i]);
497 
498  /* Write matrix */
499  writematMG(rank, nosh, pbeparm, pmg[i]);
500 
501  /* If needed, cache atom energies */
502  nenergy[i] = 0;
503  if ((pbeparm->calcenergy == PCE_COMPS) && (outputformat != OUTPUT_NULL)){
504  storeAtomEnergy(pmg[i], i, &(atomEnergy[i]), &(nenergy[i]));
505  }
506 
507  fflush(stdout);
508  fflush(stderr);
509 
510  break;
511 
512  /* ***** Do FEM calculation ***** */
513  case NCT_FEM:
514 #ifdef HAVE_MC_H
515  for (k=0; k<nosh->nelec; k++) {
516  if (nosh->elec2calc[k] >= i) break;
517  }
518  if (Vstring_strcasecmp(nosh->elecname[i+1], "") == 0) {
519  Vnm_tprint( 1, "CALCULATION #%d: FINITE ELEMENT\n", i+1);
520  } else {
521  Vnm_tprint( 1, "CALCULATION #%d (%s): FINITE ELEMENT\n", i+1, nosh->elecname[k+1]);
522  }
523 
524  /* Useful local variables */
525  feparm = nosh->calc[i]->femparm;
526  pbeparm = nosh->calc[i]->pbeparm;
527 
528  /* Warn the user about some things */
529  Vnm_tprint(2, "#################### WARNING ###################\n");
530  Vnm_tprint(2, "## FE support is currently very experimental! ##\n");
531  Vnm_tprint(2, "#################### WARNING ###################\n");
532 
533  /* Set up problem */
534  Vnm_tprint( 1, " Setting up problem...\n");
535  /* Attempt to initialize and do an initial refinement of the mesh data. The mesh data
536  * will be stored in the Vfetk object fetk, which contains the appropriate geometry
537  * manager (Gem) object and Vcsm object describing the mesh structure. The mesh will
538  * either be loaded from an external source or generated from scratch. */
539  if (initFE(i, nosh, feparm, pbeparm, pbe, alist, fetk) != VRC_SUCCESS) {
540  Vnm_tprint( 2, "Error setting up FE calculation!\n");
541  VJMPERR1(0);
542  }
543 
544  /* Print problem parameters */
545  printFEPARM(i, nosh, feparm, fetk);
546  printPBEPARM(pbeparm);
547 
548  /* Refine mesh - this continues to run the AM_markRefine procedure already run
549  * in initFE() to arrive at some initial refinement, but does checks of the
550  * simplices so that it refines until the error or size tolerances are reached.
551  * Once this is done, we have a mesh that has been refined to the point where
552  * we can attempt to solve - further refinement may be needed in the loop
553  * below. */
554  if (!preRefineFE(i, feparm, fetk)) {
555  Vnm_tprint( 2, "Error pre-refining mesh!\n");
556  VJMPERR1(0);
557  }
558 
559  /* Solve-estimate-refine */
560  Vnm_tprint(2, "\n\nWARNING! DO NOT EXPECT PERFORMANCE OUT OF THE APBS/FEtk\n");
561  Vnm_tprint(2, "INTERFACE AT THIS TIME. THE FINITE ELEMENT SOLVER IS\n");
562  Vnm_tprint(2, "CURRENTLY NOT OPTIMIZED FOR THE PB EQUATION. IF YOU WANT\n");
563  Vnm_tprint(2, "PERFORMANCE, PLEASE USE THE MULTIGRID-BASED METHODS, E.G.\n");
564  Vnm_tprint(2, "MG-AUTO, MG-PARA, and MG-MANUAL (SEE DOCS.)\n\n");
565  Vnm_tprint(1, " Beginning solve-estimate-refine cycle:\n");
566 
567  for (isolve=0; isolve<feparm->maxsolve; isolve++) {
568  Vnm_tprint(1, " Solve #%d...\n", isolve);
569 
570  /* Attempt to solve the mesh by using one of MC's solver types. */
571  if (!solveFE(i, pbeparm, feparm, fetk)) {
572  Vnm_tprint(2, "ERROR SOLVING EQUATION!\n");
573  VJMPERR1(0);
574  }
575 
576  /* Calculate the total electrostatic energy. */
577  if (!energyFE(nosh, i, fetk, &(nenergy[i]),
578  &(totEnergy[i]), &(qfEnergy[i]),
579  &(qmEnergy[i]), &(dielEnergy[i]))) {
580  Vnm_tprint(2, "ERROR SOLVING EQUATION!\n");
581  VJMPERR1(0);
582  }
583 
584  /* We're not going to refine if we've hit the max number
585  * of solves */
586  if (isolve < (feparm->maxsolve)-1) {
587  /* Do a final error estimation and mesh refinement. */
588  if (!postRefineFE(i, feparm, fetk)) {
589  break;
590  }
591  }
592  bytesTotal = Vmem_bytesTotal();
593  highWater = Vmem_highWaterTotal();
594  Vnm_tprint(1, " Current memory use: %g MB\n",
595  ((double)bytesTotal/(1024.)/(1024.)));
596  Vnm_tprint(1, " High-water memory use: %g MB\n",
597  ((double)highWater/(1024.)/(1024.)));
598  }
599 
600  Vnm_tprint(1, " Writing FEM data to files.\n");
601 
602  /* Save data. */
603  if (!writedataFE(rank, nosh, pbeparm, fetk[i])) {
604  Vnm_tprint(2, " Error while writing FEM data!\n");
605  }
606 #else /* ifdef HAVE_MC_H */
607  Vnm_print(2, "Error! APBS not compiled with FEtk!\n");
608  exit(2);
609 #endif /* ifdef HAVE_MC_H */
610  break;
611 
612  /* Do an apolar calculation */
613  case NCT_APOL:
614  /* Copied from NCT_MG. See the note above (top of loop) for
615  information about this loop.
616  */
617  for (k=0; k<nosh->napol; k++) {
618  if (nosh->apol2calc[k] >= i) {
619  break;
620  }
621  }
622 
623  if (Vstring_strcasecmp(nosh->apolname[k], "") == 0) {
624  Vnm_tprint( 1, "CALCULATION #%d: APOLAR\n", i+1);
625  } else {
626  Vnm_tprint( 1, "CALCULATION #%d (%s): APOLAR\n",
627  i+1, nosh->apolname[k]);
628  }
629 
630  apolparm = nosh->calc[i]->apolparm;
631  // poor man's execution timer.
632  ts = clock();
633  rc = initAPOL(nosh, mem, param, apolparm, &(nforce[i]), &(atomForce[i]),
634  alist[(apolparm->molid)-1]);
635  Vnm_print(0, "initAPOL: Time elapsed: %f\n", ((double)clock() - ts) / CLOCKS_PER_SEC);
636  if(rc == 0) {
637  Vnm_tprint(2, "Error calculating apolar solvation quantities!\n");
638  VJMPERR1(0);
639  }
640  break;
641  default:
642  Vnm_tprint(2, " Unknown calculation type (%d)!\n",
643  nosh->calc[i]->calctype);
644  exit(2);
645  }
646  }
647 
648  //Clear out the parameter file memory
649  if(param != VNULL) Vparam_dtor(&param);
650 
651  /* *************** HANDLE PRINT STATEMENTS ******************* */
652  if (nosh->nprint > 0) {
653  Vnm_tprint( 1, "----------------------------------------\n");
654  Vnm_tprint( 1, "PRINT STATEMENTS\n");
655  }
656  for (i=0; i<nosh->nprint; i++) {
657  /* Print energy */
658  if (nosh->printwhat[i] == NPT_ENERGY) {
659  printEnergy(com, nosh, totEnergy, i);
660  /* Print force */
661  } else if (nosh->printwhat[i] == NPT_FORCE) {
662  printForce(com, nosh, nforce, atomForce, i);
663  } else if (nosh->printwhat[i] == NPT_ELECENERGY) {
664  printElecEnergy(com, nosh, totEnergy, i);
665  } else if (nosh->printwhat[i] == NPT_ELECFORCE) {
666  printElecForce(com, nosh, nforce, atomForce, i);
667  } else if (nosh->printwhat[i] == NPT_APOLENERGY) {
668  printApolEnergy(nosh, i);
669  } else if (nosh->printwhat[i] == NPT_APOLFORCE) {
670  printApolForce(com, nosh, nforce, atomForce, i);
671  } else {
672  Vnm_tprint( 2, "Undefined PRINT keyword!\n");
673  break;
674  }
675  }
676  Vnm_tprint( 1, "----------------------------------------\n");
677 
678  /* *************** HANDLE LOGGING *********************** */
679 
680  if (outputformat == OUTPUT_FLAT) {
681  Vnm_tprint(2," Writing data to flat file %s...\n\n", output_path);
682  writedataFlat(nosh, com, output_path, totEnergy, qfEnergy, qmEnergy,
683  dielEnergy, nenergy, atomEnergy, nforce, atomForce);
684  }
685 
686  /* Destroy energy arrays if they still exist */
687 
688  for (i=0; i<nosh->ncalc; i++) {
689  if (nenergy[i] > 0) Vmem_free(mem, nenergy[i], sizeof(double),
690  (void **)&(atomEnergy[i]));
691  }
692 
693  /* *************** GARBAGE COLLECTION ******************* */
694 
695  Vnm_tprint( 1, "CLEANING UP AND SHUTTING DOWN...\n");
696  /* Clean up APBS structures */
697  killForce(mem, nosh, nforce, atomForce);
698  killEnergy();
699  killMG(nosh, pbe, pmgp, pmg);
700 #ifdef HAVE_MC_H
701  killFE(nosh, pbe, fetk, gm);
702 #endif
703  killChargeMaps(nosh, chargeMap);
704  killKappaMaps(nosh, kappaMap);
705  killDielMaps(nosh, dielXMap, dielYMap, dielZMap);
706  killMolecules(nosh, alist);
707  NOsh_dtor(&nosh);
708 
709  /* Memory statistics */
710  bytesTotal = Vmem_bytesTotal();
711  highWater = Vmem_highWaterTotal();
712  Vnm_tprint( 1, "Final memory usage: %4.3f MB total, %4.3f MB high water\n",
713  (double)(bytesTotal)/(1024.*1024.),
714  (double)(highWater)/(1024.*1024.));
715 
716  /* Clean up MALOC structures */
717  Vcom_dtor(&com);
718  Vmem_dtor(&mem);
719 
720  /* And now it's time to so "so long"... */
721  Vnm_tprint(1, "\n\n");
722  Vnm_tprint( 1, "Thanks for using APBS!\n\n");
723 
724 #if defined(DEBUG_MAC_OSX_OCL)
725  mets_(&mbeg, "Main Program CL");
726 #endif
727 #if defined(DEBUG_MAC_OSX_STANDARD)
728  mets_(&mbeg, "Main Program Standard");
729 #endif
730 
731  /* This should be last */
732  Vnm_tstop(APBS_TIMER_WALL_CLOCK, "APBS WALL CLOCK");
733  Vnm_flush(1);
734  Vnm_flush(2);
735  Vcom_finalize();
736 
737  fflush(NULL);
738 
739  return 0;
740 
741  VERROR1:
742  Vcom_finalize();
743  Vcom_dtor(&com);
744  Vmem_dtor(&mem);
745  return APBSRC;
746 }
VPUBLIC int NOsh_setupApolCalc(NOsh *thee, Valist *alist[NOSH_MAXMOL])
Setup the series of non-polar calculations.
Definition: nosh.c:1291
MGparm * mgparm
Definition: nosh.h:165
enum eVoutput_Format Voutput_Format
Declaration of the Voutput_Format type as the VOutput_Format enum.
Definition: vhal.h:202
int apol2calc[NOSH_MAXCALC]
Definition: nosh.h:217
VPUBLIC Vparam * loadParameter(NOsh *nosh)
Loads and returns parameter object.
Definition: routines.c:60
Definition: nosh.h:116
#define NOSH_MAXMOL
Maximum number of molecules in a run.
Definition: nosh.h:79
Contains public data members for Vpbe class/module.
Definition: vpbe.h:84
VPUBLIC int loadChargeMaps(NOsh *nosh, Vgrid *map[NOSH_MAXMOL])
Load the charge maps given in NOsh into grid objects.
Definition: routines.c:770
NOsh_PrintType printwhat[NOSH_MAXPRINT]
Definition: nosh.h:248
Electrostatic potential oracle for Cartesian mesh data.
Definition: vgrid.h:81
int nprint
Definition: nosh.h:247
#define APBS_TIMER_WALL_CLOCK
APBS total execution timer ID.
Definition: vhal.h:330
VPUBLIC void NOsh_dtor(NOsh **thee)
Object destructor.
Definition: nosh.c:289
VPUBLIC int writedataFlat(NOsh *nosh, Vcom *com, const char *fname, double totEnergy[NOSH_MAXCALC], double qfEnergy[NOSH_MAXCALC], double qmEnergy[NOSH_MAXCALC], double dielEnergy[NOSH_MAXCALC], int nenergy[NOSH_MAXCALC], double *atomEnergy[NOSH_MAXCALC], int nforce[NOSH_MAXCALC], AtomForce *atomForce[NOSH_MAXCALC])
Write out information to a flat file.
Definition: routines.c:1741
char elecname[NOSH_MAXCALC][VMAX_ARGLEN]
Definition: nosh.h:255
int molid
Definition: apolparm.h:136
VPUBLIC int postRefineFE(int icalc, FEMparm *feparm, Vfetk *fetk[NOSH_MAXCALC])
Estimate error, mark mesh, and refine mesh after solve.
Definition: routines.c:4079
NOsh_calc * calc[NOSH_MAXCALC]
Definition: nosh.h:185
Contains public data members for Vpmg class/module.
Definition: vpmg.h:116
VPUBLIC int solveMG(NOsh *nosh, Vpmg *pmg, MGparm_CalcType type)
Solve the PBE with MG.
Definition: routines.c:1341
VPUBLIC int writematMG(int rank, NOsh *nosh, PBEparm *pbeparm, Vpmg *pmg)
Write out operator matrix from MG calculation to file.
Definition: routines.c:1653
VPUBLIC int setPartMG(NOsh *nosh, MGparm *mgparm, Vpmg *pmg)
Set MG partitions for calculating observables and performing I/O.
Definition: routines.c:1377
Header file for front end auxiliary routines.
VPUBLIC void killChargeMaps(NOsh *nosh, Vgrid *map[NOSH_MAXMOL])
Destroy the loaded charge maps.
Definition: routines.c:849
VPUBLIC void killForce(Vmem *mem, NOsh *nosh, int nforce[NOSH_MAXCALC], AtomForce *atomForce[NOSH_MAXCALC])
Free memory from MG force calculation.
Definition: routines.c:1636
VPUBLIC int loadKappaMaps(NOsh *nosh, Vgrid *map[NOSH_MAXMOL])
Load the kappa maps given in NOsh into grid objects.
Definition: routines.c:575
Definition: nosh.h:114
VPUBLIC int loadDielMaps(NOsh *nosh, Vgrid *dielXMap[NOSH_MAXMOL], Vgrid *dielYMap[NOSH_MAXMOL], Vgrid *dielZMap[NOSH_MAXMOL])
Load the dielectric maps given in NOsh into grid objects.
Definition: routines.c:250
int ncalc
Definition: nosh.h:188
VPUBLIC int initMG(int icalc, NOsh *nosh, MGparm *mgparm, PBEparm *pbeparm, double realCenter[3], Vpbe *pbe[NOSH_MAXCALC], Valist *alist[NOSH_MAXMOL], Vgrid *dielXMap[NOSH_MAXMOL], Vgrid *dielYMap[NOSH_MAXMOL], Vgrid *dielZMap[NOSH_MAXMOL], Vgrid *kappaMap[NOSH_MAXMOL], Vgrid *chargeMap[NOSH_MAXMOL], Vpmgp *pmgp[NOSH_MAXCALC], Vpmg *pmg[NOSH_MAXCALC], Vgrid *potMap[NOSH_MAXMOL])
Initialize an MG calculation.
Definition: routines.c:1074
NOsh_CalcType calctype
Definition: nosh.h:169
VPUBLIC void storeAtomEnergy(Vpmg *pmg, int icalc, double **atomEnergy, int *nenergy)
Store energy in arrays for future use.
Definition: routines.c:1724
VPUBLIC void killMG(NOsh *nosh, Vpbe *pbe[NOSH_MAXCALC], Vpmgp *pmgp[NOSH_MAXCALC], Vpmg *pmg[NOSH_MAXCALC])
Kill structures initialized during an MG calculation.
Definition: routines.c:1315
VPUBLIC int printApolForce(Vcom *com, NOsh *nosh, int nforce[NOSH_MAXCALC], AtomForce *atomForce[NOSH_MAXCALC], int iprint)
Combine and pretty-print force data.
Definition: routines.c:3314
APOLparm * apolparm
Definition: nosh.h:168
VPUBLIC void printFEPARM(int icalc, NOsh *nosh, FEMparm *feparm, Vfetk *fetk[NOSH_MAXCALC])
Print out FE-specific params loaded from input.
Definition: routines.c:3743
VPUBLIC void killFE(NOsh *nosh, Vpbe *pbe[NOSH_MAXCALC], Vfetk *fetk[NOSH_MAXCALC], Gem *gm[NOSH_MAXMOL])
Kill structures initialized during an FE calculation.
Definition: routines.c:3526
PBEparm * pbeparm
Definition: nosh.h:167
MGparm_CalcType type
Definition: mgparm.h:116
VPUBLIC int printElecEnergy(Vcom *com, NOsh *nosh, double totEnergy[NOSH_MAXCALC], int iprint)
Combine and pretty-print energy data.
Definition: routines.c:2696
Definition: nosh.h:115
VPUBLIC void killKappaMaps(NOsh *nosh, Vgrid *map[NOSH_MAXMOL])
Destroy the loaded kappa maps.
Definition: routines.c:662
#define VEMBED(rctag)
Allows embedding of RCS ID tags in object files.
Definition: vhal.h:563
int nelec
Definition: nosh.h:193
VPUBLIC int NOsh_setupElecCalc(NOsh *thee, Valist *alist[NOSH_MAXMOL])
Setup the series of electrostatics calculations.
Definition: nosh.c:1208
VPUBLIC int NOsh_parseInput(NOsh *thee, Vio *sock)
Parse an input file from a socket.
Definition: nosh.c:407
VPUBLIC void Vparam_dtor(Vparam **thee)
Destroy object.
Definition: vparam.c:213
VPUBLIC int Vstring_strcasecmp(const char *s1, const char *s2)
Case-insensitive string comparison (BSD standard)
Definition: vstring.c:66
VPUBLIC int energyFE(NOsh *nosh, int icalc, Vfetk *fetk[NOSH_MAXCALC], int *nenergy, double *totEnergy, double *qfEnergy, double *qmEnergy, double *dielEnergy)
Calculate electrostatic energies from FE solution.
Definition: routines.c:4019
VPUBLIC int printForce(Vcom *com, NOsh *nosh, int nforce[NOSH_MAXCALC], AtomForce *atomForce[NOSH_MAXCALC], int iprint)
Combine and pretty-print force data (deprecated...see printElecForce)
Definition: routines.c:2823
VPUBLIC void printPBEPARM(PBEparm *pbeparm)
Print out generic PBE params loaded from input.
Definition: routines.c:867
VPUBLIC int writedataMG(int rank, NOsh *nosh, PBEparm *pbeparm, Vpmg *pmg)
Write out observables from MG calculation to file.
Definition: routines.c:2237
Parameter structure for FEM-specific variables from input files.
Definition: femparm.h:133
int napol
Definition: nosh.h:199
Structure to hold atomic forces.
Definition: routines.h:83
Reads and assigns charge/radii parameters.
Definition: vparam.h:135
int maxsolve
Definition: femparm.h:165
Contains public data members for Vpmgp class/module.
Definition: vpmgp.h:80
PBEparm_calcEnergy calcenergy
Definition: pbeparm.h:165
VPUBLIC int printEnergy(Vcom *com, NOsh *nosh, double totEnergy[NOSH_MAXCALC], int iprint)
Combine and pretty-print energy data (deprecated...see printElecEnergy)
Definition: routines.c:2628
VPUBLIC int loadPotMaps(NOsh *nosh, Vgrid *map[NOSH_MAXMOL])
Load the potential maps given in NOsh into grid objects.
Definition: routines.c:679
Parameter structure for PBE variables from input files.
Definition: pbeparm.h:117
VPUBLIC void killMolecules(NOsh *nosh, Valist *alist[NOSH_MAXMOL])
Destroy the loaded molecules.
Definition: routines.c:233
int main(int argc, char **argv)
The main APBS function.
Definition: main.c:80
VPUBLIC int forceMG(Vmem *mem, NOsh *nosh, PBEparm *pbeparm, MGparm *mgparm, Vpmg *pmg, int *nforce, AtomForce **atomForce, Valist *alist[NOSH_MAXMOL])
Calculate forces from MG solution.
Definition: routines.c:1490
Parameter structure for MG-specific variables from input files.
Definition: mgparm.h:114
VPUBLIC void killDielMaps(NOsh *nosh, Vgrid *dielXMap[NOSH_MAXMOL], Vgrid *dielYMap[NOSH_MAXMOL], Vgrid *dielZMap[NOSH_MAXMOL])
Destroy the loaded dielectric.
Definition: routines.c:550
VPUBLIC Vrc_Codes initFE(int icalc, NOsh *nosh, FEMparm *feparm, PBEparm *pbeparm, Vpbe *pbe[NOSH_MAXCALC], Valist *alist[NOSH_MAXMOL], Vfetk *fetk[NOSH_MAXCALC])
Initialize FE solver objects.
Definition: routines.c:3554
VPUBLIC int printElecForce(Vcom *com, NOsh *nosh, int nforce[NOSH_MAXCALC], AtomForce *atomForce[NOSH_MAXCALC], int iprint)
Combine and pretty-print force data.
Definition: routines.c:3071
VPUBLIC NOsh * NOsh_ctor(int rank, int size)
Construct NOsh.
Definition: nosh.c:243
VPUBLIC void printMGPARM(MGparm *mgparm, double realCenter[3])
Print out MG-specific params loaded from input.
Definition: routines.c:1041
VPUBLIC int printApolEnergy(NOsh *nosh, int iprint)
Combine and pretty-print energy data.
Definition: routines.c:2761
Container class for list of atom objects.
Definition: valist.h:78
Valist * alist
Definition: vpbe.h:88
Class for parsing fixed format input files.
Definition: nosh.h:183
int elec2calc[NOSH_MAXCALC]
Definition: nosh.h:209
Contains public data members for Vfetk class/module.
Definition: vfetk.h:176
VPUBLIC int loadMolecules(NOsh *nosh, Vparam *param, Valist *alist[NOSH_MAXMOL])
Load the molecules given in NOsh into atom lists.
Definition: routines.c:95
#define APBSRC
Return code for APBS during failure.
Definition: routines.h:77
#define NOSH_MAXCALC
Maximum number of calculations in a run.
Definition: nosh.h:83
VPUBLIC int solveFE(int icalc, PBEparm *pbeparm, FEMparm *feparm, Vfetk *fetk[NOSH_MAXCALC])
Solve-estimate-refine.
Definition: routines.c:3956
VPUBLIC void startVio()
Wrapper to start MALOC Vio layer.
Definition: routines.c:58
FEMparm * femparm
Definition: nosh.h:166
char apolname[NOSH_MAXCALC][VMAX_ARGLEN]
Definition: nosh.h:257
VPUBLIC int initAPOL(NOsh *nosh, Vmem *mem, Vparam *param, APOLparm *apolparm, int *nforce, AtomForce **atomForce, Valist *alist)
Upperlevel routine to the non-polar energy and force routines.
Definition: routines.c:4308
Parameter structure for APOL-specific variables from input files.
Definition: apolparm.h:129
VPUBLIC int energyMG(NOsh *nosh, int icalc, Vpmg *pmg, int *nenergy, double *totEnergy, double *qfEnergy, double *qmEnergy, double *dielEnergy)
Calculate electrostatic energies from MG solution.
Definition: routines.c:1423
VPUBLIC int preRefineFE(int icalc, FEMparm *feparm, Vfetk *fetk[NOSH_MAXCALC])
Pre-refine mesh before solve.
Definition: routines.c:3886
VPUBLIC int writedataFE(int rank, NOsh *nosh, PBEparm *pbeparm, Vfetk *fetk)
Write FEM data to files.
Definition: routines.c:4140
VPUBLIC void killEnergy()
Kill arrays allocated for energies.
Definition: routines.c:1628