APBS  1.4.1
nosh.c
Go to the documentation of this file.
1 
57 #include "nosh.h"
58 
59 VEMBED(rcsid="$Id$")
60 
61 
62 VPRIVATE int NOsh_parseREAD(
63  NOsh *thee,
64  Vio *sock);
65 
66 VPRIVATE int NOsh_parsePRINT(
67  NOsh *thee,
68  Vio *sock);
69 
70 VPRIVATE int NOsh_parseELEC(
71  NOsh *thee,
72  Vio *sock
73  );
74 
75 VPRIVATE int NOsh_parseAPOLAR(
76  NOsh *thee,
77  Vio *sock
78  );
79 
80 VEXTERNC int NOsh_parseFEM(
81  NOsh *thee,
82  Vio *sock,
83  NOsh_calc *elec
84  );
85 
86 VEXTERNC int NOsh_parseMG(
87  NOsh *thee,
88  Vio *sock,
89  NOsh_calc *elec
90  );
91 
92 VEXTERNC int NOsh_parseAPOL(
93  NOsh *thee,
94  Vio *sock,
95  NOsh_calc *elec
96  );
97 
98 VPRIVATE int NOsh_setupCalcMG(
99  NOsh *thee,
100  NOsh_calc *elec
101  );
102 
103 VPRIVATE int NOsh_setupCalcMGAUTO(
104  NOsh *thee,
105  NOsh_calc *elec
106  );
107 
108 VPRIVATE int NOsh_setupCalcMGMANUAL(
109  NOsh *thee,
110  NOsh_calc *elec
111  );
112 
113 VPRIVATE int NOsh_setupCalcMGPARA(
114  NOsh *thee,
115  NOsh_calc *elec
116  );
117 
118 VPRIVATE int NOsh_setupCalcFEM(
119  NOsh *thee,
120  NOsh_calc *elec
121  );
122 
123 VPRIVATE int NOsh_setupCalcFEMANUAL(
124  NOsh *thee,
125  NOsh_calc *elec
126  );
127 
128 VPRIVATE int NOsh_setupCalcAPOL(
129  NOsh *thee,
130  NOsh_calc *elec
131  );
132 
133 #if !defined(VINLINE_NOSH)
134 
135 VPUBLIC char* NOsh_getMolpath(NOsh *thee, int imol) {
136  VASSERT(thee != VNULL);
137  VASSERT(imol < thee->nmol);
138  return thee->molpath[imol];
139 }
140 VPUBLIC char* NOsh_getDielXpath(NOsh *thee, int imol) {
141  VASSERT(thee != VNULL);
142  VASSERT(imol < thee->nmol);
143  return thee->dielXpath[imol];
144 }
145 VPUBLIC char* NOsh_getDielYpath(NOsh *thee, int imol) {
146  VASSERT(thee != VNULL);
147  VASSERT(imol < thee->nmol);
148  return thee->dielYpath[imol];
149 }
150 VPUBLIC char* NOsh_getDielZpath(NOsh *thee, int imol) {
151  VASSERT(thee != VNULL);
152  VASSERT(imol < thee->nmol);
153  return thee->dielZpath[imol];
154 }
155 VPUBLIC char* NOsh_getKappapath(NOsh *thee, int imol) {
156  VASSERT(thee != VNULL);
157  VASSERT(imol < thee->nmol);
158  return thee->kappapath[imol];
159 }
160 VPUBLIC char* NOsh_getPotpath(NOsh *thee, int imol) {
161  VASSERT(thee != VNULL);
162  VASSERT(imol < thee->nmol);
163  return thee->potpath[imol];
164 }
165 VPUBLIC char* NOsh_getChargepath(NOsh *thee, int imol) {
166  VASSERT(thee != VNULL);
167  VASSERT(imol < thee->nmol);
168  return thee->chargepath[imol];
169 }
170 VPUBLIC NOsh_calc* NOsh_getCalc(NOsh *thee, int icalc) {
171  VASSERT(thee != VNULL);
172  VASSERT(icalc < thee->ncalc);
173  return thee->calc[icalc];
174 }
175 VPUBLIC int NOsh_getDielfmt(NOsh *thee, int i) {
176  VASSERT(thee != VNULL);
177  VASSERT(i < thee->ndiel);
178  return (thee->dielfmt[i]);
179 }
180 VPUBLIC int NOsh_getKappafmt(NOsh *thee, int i) {
181  VASSERT(thee != VNULL);
182  VASSERT(i < thee->nkappa);
183  return (thee->kappafmt[i]);
184 }
185 VPUBLIC int NOsh_getPotfmt(NOsh *thee, int i) {
186  VASSERT(thee != VNULL);
187  VASSERT(i < thee->npot);
188  return (thee->potfmt[i]);
189 }
190 VPUBLIC int NOsh_getChargefmt(NOsh *thee, int i) {
191  VASSERT(thee != VNULL);
192  VASSERT(i < thee->ncharge);
193  return (thee->chargefmt[i]);
194 }
195 
196 
197 #endif /* if !defined(VINLINE_NOSH) */
198 
199 VPUBLIC NOsh_PrintType NOsh_printWhat(NOsh *thee, int iprint) {
200  VASSERT(thee != VNULL);
201  VASSERT(iprint < thee->nprint);
202  return thee->printwhat[iprint];
203 }
204 
205 VPUBLIC int NOsh_printNarg(NOsh *thee, int iprint) {
206  VASSERT(thee != VNULL);
207  VASSERT(iprint < thee->nprint);
208  return thee->printnarg[iprint];
209 }
210 
211 VPUBLIC int NOsh_elec2calc(NOsh *thee, int icalc) {
212  VASSERT(thee != VNULL);
213  VASSERT(icalc < thee->ncalc);
214  return thee->elec2calc[icalc];
215 }
216 
217 VPUBLIC int NOsh_apol2calc(NOsh *thee, int icalc) {
218  VASSERT(thee != VNULL);
219  VASSERT(icalc < thee->ncalc);
220  return thee->apol2calc[icalc];
221 }
222 
223 VPUBLIC char* NOsh_elecname(NOsh *thee, int ielec) {
224  VASSERT(thee != VNULL);
225  VASSERT(ielec < thee->nelec + 1);
226  return thee->elecname[ielec];
227 }
228 
229 VPUBLIC int NOsh_printOp(NOsh *thee, int iprint, int iarg) {
230  VASSERT(thee != VNULL);
231  VASSERT(iprint < thee->nprint);
232  VASSERT(iarg < thee->printnarg[iprint]);
233  return thee->printop[iprint][iarg];
234 }
235 
236 VPUBLIC int NOsh_printCalc(NOsh *thee, int iprint, int iarg) {
237  VASSERT(thee != VNULL);
238  VASSERT(iprint < thee->nprint);
239  VASSERT(iarg < thee->printnarg[iprint]);
240  return thee->printcalc[iprint][iarg];
241 }
242 
243 VPUBLIC NOsh* NOsh_ctor(int rank, int size) {
244 
245  /* Set up the structure */
246  NOsh *thee = VNULL;
247  thee = (NOsh*)Vmem_malloc(VNULL, 1, sizeof(NOsh) );
248  VASSERT( thee != VNULL);
249  VASSERT( NOsh_ctor2(thee, rank, size) );
250 
251  return thee;
252 }
253 
254 VPUBLIC int NOsh_ctor2(NOsh *thee, int rank, int size) {
255 
256  int i;
257 
258  if (thee == VNULL) return 0;
259 
260  thee->proc_rank = rank;
261  thee->proc_size = size;
262 
263  thee->ispara = 0;
264  thee->parsed = 0;
265 
266  thee->nmol = 0;
267  thee->gotparm = 0;
268  thee->ncharge = 0;
269  thee->ndiel = 0;
270  thee->nkappa = 0;
271  thee->npot = 0;
272  thee->nprint = 0;
273 
274  for (i=0; i<NOSH_MAXCALC; i++) {
275  thee->calc[i] = VNULL;
276  thee->elec[i] = VNULL;
277  thee->apol[i] = VNULL;
278  }
279  for (i=0; i<NOSH_MAXMOL; i++) {
280  thee->alist[i] = VNULL;
281  }
282  thee->ncalc = 0;
283  thee->nelec = 0;
284  thee->napol = 0;
285 
286  return 1;
287 }
288 
289 VPUBLIC void NOsh_dtor(NOsh **thee) {
290  if ((*thee) != VNULL) {
291  NOsh_dtor2(*thee);
292  Vmem_free(VNULL, 1, sizeof(NOsh), (void **)thee);
293  (*thee) = VNULL;
294  }
295 }
296 
297 VPUBLIC void NOsh_dtor2(NOsh *thee) {
298 
299  int i;
300 
301  if (thee != VNULL) {
302  for (i=0; i<(thee->ncalc); i++) NOsh_calc_dtor(&(thee->calc[i]));
303  for (i=0; i<(thee->nelec); i++) NOsh_calc_dtor(&(thee->elec[i]));
304  for (i=0; i<(thee->napol); i++) NOsh_calc_dtor(&(thee->apol[i]));
305  }
306 
307 }
308 
310  NOsh_CalcType calctype
311  ) {
312  NOsh_calc *thee;
313  thee = (NOsh_calc *)Vmem_malloc(VNULL, 1, sizeof(NOsh_calc));
314  thee->calctype = calctype;
315  switch (calctype) {
316  case NCT_MG:
317  thee->mgparm = MGparm_ctor(MCT_NONE);
318  thee->femparm = VNULL;
319  thee->apolparm = VNULL;
320  break;
321  case NCT_FEM:
322  thee->mgparm = VNULL;
323  thee->femparm = FEMparm_ctor(FCT_NONE);
324  thee->apolparm = VNULL;
325  break;
326  case NCT_APOL:
327  thee->mgparm = VNULL;
328  thee->femparm = VNULL;
329  thee->apolparm = APOLparm_ctor();
330  break;
331  default:
332  Vnm_print(2, "NOsh_calc_ctor: unknown calculation type (%d)!\n",
333  calctype);
334  VASSERT(0);
335  }
336  thee->pbeparm = PBEparm_ctor();
337 
338  return thee;
339 }
340 
341 VPUBLIC void NOsh_calc_dtor(
342  NOsh_calc **thee
343  ) {
344 
345  NOsh_calc *calc = VNULL;
346  calc = *thee;
347  if (calc == VNULL) return;
348 
349  switch (calc->calctype) {
350  case NCT_MG:
351  MGparm_dtor(&(calc->mgparm));
352  break;
353  case NCT_FEM:
354  FEMparm_dtor(&(calc->femparm));
355  break;
356  case NCT_APOL:
357  APOLparm_dtor(&(calc->apolparm));
358  break;
359  default:
360  Vnm_print(2, "NOsh_calc_ctor: unknown calculation type (%d)!\n",
361  calc->calctype);
362  VASSERT(0);
363  }
364  PBEparm_dtor(&(calc->pbeparm));
365 
366  Vmem_free(VNULL, 1, sizeof(NOsh_calc), (void **)thee);
367  calc = VNULL;
368 
369 }
370 
371 VPUBLIC int NOsh_calc_copy(
372  NOsh_calc *thee,
373  NOsh_calc *source
374  ) {
375 
376  VASSERT(thee != VNULL);
377  VASSERT(source != VNULL);
378  VASSERT(thee->calctype == source->calctype);
379  if (source->mgparm != VNULL)
380  MGparm_copy(thee->mgparm, source->mgparm);
381  if (source->femparm != VNULL)
382  FEMparm_copy(thee->femparm, source->femparm);
383  if (source->pbeparm != VNULL)
384  PBEparm_copy(thee->pbeparm, source->pbeparm);
385  if (source->apolparm != VNULL)
386  APOLparm_copy(thee->apolparm, source->apolparm);
387 
388  return 1;
389 
390 }
391 
393  NOsh *thee,
394  char *filename
395  ) {
396 
397  Vio *sock;
398  int rc;
399 
400  sock = Vio_ctor("FILE", "ASC", VNULL, filename, "r");
401  rc = NOsh_parseInput(thee, sock);
402  Vio_dtor(&sock);
403 
404  return rc;
405 }
406 
407 VPUBLIC int NOsh_parseInput(
408  NOsh *thee,
409  Vio *sock
410  ) {
411 
412  char *MCwhiteChars = " =,;\t\r\n";
413  char *MCcommChars = "#%";
414  char tok[VMAX_BUFSIZE];
415 
416  if (thee == VNULL) {
417  Vnm_print(2, "NOsh_parseInput: Got NULL thee!\n");
418  return 0;
419  }
420 
421  if (sock == VNULL) {
422  Vnm_print(2, "NOsh_parseInput: Got pointer to NULL socket!\n");
423  Vnm_print(2, "NOsh_parseInput: The specified input file was not found!\n");
424  return 0;
425  }
426 
427  if (thee->parsed) {
428  Vnm_print(2, "NOsh_parseInput: Already parsed an input file!\n");
429  return 0;
430  }
431 
432  if (Vio_accept(sock, 0) < 0) {
433  Vnm_print(2, "NOsh_parseInput: Problem reading from socket!\n");
434  return 0;
435  }
436 
437  /* Set up the whitespace and comment character definitions */
438  Vio_setWhiteChars(sock, MCwhiteChars);
439  Vio_setCommChars(sock, MCcommChars);
440 
441  /* We parse the file until we run out of tokens */
442  Vnm_print(0, "NOsh_parseInput: Starting file parsing...\n");
443  while (Vio_scanf(sock, "%s", tok) == 1) {
444  /* At the highest level, we look for keywords that indicate functions like:
445 
446  read => Read in a molecule file
447  elec => Do an electrostatics calculation
448  print => Print some results
449  apolar => do a non-polar calculation
450  quit => Quit
451 
452  These cause the code to go to a lower-level parser routine which
453  handles keywords specific to the particular function. Each
454  lower-level parser routine then returns when it hits the "end"
455  keyword. Due to this simple layout, no nesting of these "function"
456  sections is allowed.
457  */
458  if (Vstring_strcasecmp(tok, "read") == 0) {
459  Vnm_print(0, "NOsh: Parsing READ section\n");
460  if (!NOsh_parseREAD(thee, sock)) return 0;
461  Vnm_print(0, "NOsh: Done parsing READ section \
462 (nmol=%d, ndiel=%d, nkappa=%d, ncharge=%d, npot=%d)\n", thee->nmol, thee->ndiel,
463  thee->nkappa, thee->ncharge,thee->npot);
464  } else if (Vstring_strcasecmp(tok, "print") == 0) {
465  Vnm_print(0, "NOsh: Parsing PRINT section\n");
466  if (!NOsh_parsePRINT(thee, sock)) return 0;
467  Vnm_print(0, "NOsh: Done parsing PRINT section\n");
468  } else if (Vstring_strcasecmp(tok, "elec") == 0) {
469  Vnm_print(0, "NOsh: Parsing ELEC section\n");
470  if (!NOsh_parseELEC(thee, sock)) return 0;
471  Vnm_print(0, "NOsh: Done parsing ELEC section (nelec = %d)\n",
472  thee->nelec);
473  } else if (Vstring_strcasecmp(tok, "apolar") == 0) {
474  Vnm_print(0, "NOsh: Parsing APOLAR section\n");
475  if (!NOsh_parseAPOLAR(thee, sock)) return 0;
476  Vnm_print(0, "NOsh: Done parsing APOLAR section (nelec = %d)\n",
477  thee->nelec);
478  } else if (Vstring_strcasecmp(tok, "quit") == 0) {
479  Vnm_print(0, "NOsh: Done parsing file (got QUIT)\n");
480  break;
481  } else {
482  Vnm_print(2, "NOsh_parseInput: Ignoring undefined keyword %s!\n", tok);
483  }
484  }
485 
486  thee->parsed = 1;
487  return 1;
488 
489 }
490 
491 VPRIVATE int NOsh_parseREAD_MOL(NOsh *thee, Vio *sock) {
492 
493  char tok[VMAX_BUFSIZE], str[VMAX_BUFSIZE]="", strnew[VMAX_BUFSIZE]="";
494  NOsh_MolFormat molfmt;
495 
496  VJMPERR1(Vio_scanf(sock, "%s", tok) == 1);
497  if (Vstring_strcasecmp(tok, "pqr") == 0) {
498  molfmt = NMF_PQR;
499  VJMPERR1(Vio_scanf(sock, "%s", tok) == 1);
500  if (tok[0]=='"') {
501  strcpy(strnew, "");
502  while (tok[strlen(tok)-1] != '"') {
503  strcat(str, tok);
504  strcat(str, " ");
505  VJMPERR1(Vio_scanf(sock, "%s", tok) == 1);
506  }
507  strcat(str, tok);
508  strncpy(strnew, str+1, strlen(str)-2);
509  strcpy(tok, strnew);
510  }
511  Vnm_print(0, "NOsh: Storing molecule %d path %s\n",
512  thee->nmol, tok);
513  thee->molfmt[thee->nmol] = molfmt;
514  strncpy(thee->molpath[thee->nmol], tok, VMAX_ARGLEN);
515  (thee->nmol)++;
516  } else if (Vstring_strcasecmp(tok, "pdb") == 0) {
517  molfmt = NMF_PDB;
518  VJMPERR1(Vio_scanf(sock, "%s", tok) == 1);
519  if (tok[0]=='"') {
520  strcpy(strnew, "");
521  while (tok[strlen(tok)-1] != '"') {
522  strcat(str, tok);
523  strcat(str, " ");
524  VJMPERR1(Vio_scanf(sock, "%s", tok) == 1);
525  }
526  strcat(str, tok);
527  strncpy(strnew, str+1, strlen(str)-2);
528  strcpy(tok, strnew);
529  }
530  Vnm_print(0, "NOsh: Storing molecule %d path %s\n",
531  thee->nmol, tok);
532  thee->molfmt[thee->nmol] = molfmt;
533  strncpy(thee->molpath[thee->nmol], tok, VMAX_ARGLEN);
534  (thee->nmol)++;
535  } else if (Vstring_strcasecmp(tok, "xml") == 0) {
536  molfmt = NMF_XML;
537  VJMPERR1(Vio_scanf(sock, "%s", tok) == 1);
538  if (tok[0]=='"') {
539  strcpy(strnew, "");
540  while (tok[strlen(tok)-1] != '"') {
541  strcat(str, tok);
542  strcat(str, " ");
543  VJMPERR1(Vio_scanf(sock, "%s", tok) == 1);
544  }
545  strcat(str, tok);
546  strncpy(strnew, str+1, strlen(str)-2);
547  strcpy(tok, strnew);
548  }
549  Vnm_print(0, "NOsh: Storing molecule %d path %s\n",
550  thee->nmol, tok);
551  thee->molfmt[thee->nmol] = molfmt;
552  strncpy(thee->molpath[thee->nmol], tok, VMAX_ARGLEN);
553  (thee->nmol)++;
554  } else {
555  Vnm_print(2, "NOsh_parseREAD: Ignoring undefined mol format \
556 %s!\n", tok);
557  }
558 
559  return 1;
560 
561 
562 VERROR1:
563  Vnm_print(2, "NOsh_parseREAD_MOL: Ran out of tokens while parsing READ section!\n");
564  return 0;
565 
566 }
567 
568 VPRIVATE int NOsh_parseREAD_PARM(NOsh *thee, Vio *sock) {
569 
570  char tok[VMAX_BUFSIZE], str[VMAX_BUFSIZE]="", strnew[VMAX_BUFSIZE]="";
571  NOsh_ParmFormat parmfmt;
572 
573  VJMPERR1(Vio_scanf(sock, "%s", tok) == 1);
574  if (Vstring_strcasecmp(tok, "flat") == 0) {
575  parmfmt = NPF_FLAT;
576  VJMPERR1(Vio_scanf(sock, "%s", tok) == 1);
577  if (tok[0]=='"') {
578  strcpy(strnew, "");
579  while (tok[strlen(tok)-1] != '"') {
580  strcat(str, tok);
581  strcat(str, " ");
582  VJMPERR1(Vio_scanf(sock, "%s", tok) == 1);
583  }
584  strcat(str, tok);
585  strncpy(strnew, str+1, strlen(str)-2);
586  strcpy(tok, strnew);
587  }
588  if (thee->gotparm) {
589  Vnm_print(2, "NOsh: Hey! You already specified a parameterfile (%s)!\n", thee->parmpath);
590  Vnm_print(2, "NOsh: I'm going to ignore this one (%s)!\n", tok);
591  } else {
592  thee->parmfmt = parmfmt;
593  thee->gotparm = 1;
594  strncpy(thee->parmpath, tok, VMAX_ARGLEN);
595  }
596  } else if(Vstring_strcasecmp(tok, "xml") == 0) {
597  parmfmt = NPF_XML;
598  VJMPERR1(Vio_scanf(sock, "%s", tok) == 1);
599  if (tok[0]=='"') {
600  strcpy(strnew, "");
601  while (tok[strlen(tok)-1] != '"') {
602  strcat(str, tok);
603  strcat(str, " ");
604  VJMPERR1(Vio_scanf(sock, "%s", tok) == 1);
605  }
606  strcat(str, tok);
607  strncpy(strnew, str+1, strlen(str)-2);
608  strcpy(tok, strnew);
609  }
610  if (thee->gotparm) {
611  Vnm_print(2, "NOsh: Hey! You already specified a parameterfile (%s)!\n", thee->parmpath);
612  Vnm_print(2, "NOsh: I'm going to ignore this one (%s)!\n", tok);
613  } else {
614  thee->parmfmt = parmfmt;
615  thee->gotparm = 1;
616  strncpy(thee->parmpath, tok, VMAX_ARGLEN);
617  }
618 
619  } else {
620  Vnm_print(2, "NOsh_parseREAD: Ignoring undefined parm format \
621 %s!\n", tok);
622  }
623 
624  return 1;
625 
626 VERROR1:
627  Vnm_print(2, "NOsh_parseREAD_PARM: Ran out of tokens while parsing READ section!\n");
628  return 0;
629 
630 }
631 
632 VPRIVATE int NOsh_parseREAD_DIEL(NOsh *thee, Vio *sock) {
633 
634  char tok[VMAX_BUFSIZE], str[VMAX_BUFSIZE]="", strnew[VMAX_BUFSIZE]="";
635  Vdata_Format dielfmt;
636 
637  VJMPERR1(Vio_scanf(sock, "%s", tok) == 1);
638  if (Vstring_strcasecmp(tok, "dx") == 0) {
639  dielfmt = VDF_DX;
640  } else if (Vstring_strcasecmp(tok, "gz") == 0) {
641  dielfmt = VDF_GZ;
642  } else {
643  Vnm_print(2, "NOsh_parseREAD: Ignoring undefined format \
644  %s!\n", tok);
645  return VRC_FAILURE;
646  }
647 
648  VJMPERR1(Vio_scanf(sock, "%s", tok) == 1);
649  if (tok[0]=='"') {
650  strcpy(strnew, "");
651  while (tok[strlen(tok)-1] != '"') {
652  strcat(str, tok);
653  strcat(str, " ");
654  VJMPERR1(Vio_scanf(sock, "%s", tok) == 1);
655  }
656  strcat(str, tok);
657  strncpy(strnew, str+1, strlen(str)-2);
658  strcpy(tok, strnew);
659  }
660  Vnm_print(0, "NOsh: Storing x-shifted dielectric map %d path \
661  %s\n", thee->ndiel, tok);
662  strncpy(thee->dielXpath[thee->ndiel], tok, VMAX_ARGLEN);
663  VJMPERR1(Vio_scanf(sock, "%s", tok) == 1);
664  Vnm_print(0, "NOsh: Storing y-shifted dielectric map %d path \
665  %s\n", thee->ndiel, tok);
666  strncpy(thee->dielYpath[thee->ndiel], tok, VMAX_ARGLEN);
667  VJMPERR1(Vio_scanf(sock, "%s", tok) == 1);
668  Vnm_print(0, "NOsh: Storing z-shifted dielectric map %d path \
669  %s\n", thee->ndiel, tok);
670  strncpy(thee->dielZpath[thee->ndiel], tok, VMAX_ARGLEN);
671  thee->dielfmt[thee->ndiel] = dielfmt;
672  (thee->ndiel)++;
673 
674  return 1;
675 
676 VERROR1:
677  Vnm_print(2, "NOsh_parseREAD_DIEL: Ran out of tokens while parsing READ \
678 section!\n");
679  return 0;
680 
681 }
682 
683 VPRIVATE int NOsh_parseREAD_KAPPA(NOsh *thee, Vio *sock) {
684 
685  char tok[VMAX_BUFSIZE], str[VMAX_BUFSIZE]="", strnew[VMAX_BUFSIZE]="";
686  Vdata_Format kappafmt;
687 
688  VJMPERR1(Vio_scanf(sock, "%s", tok) == 1);
689  if (Vstring_strcasecmp(tok, "dx") == 0) {
690  kappafmt = VDF_DX;
691  } else if (Vstring_strcasecmp(tok, "gz") == 0) {
692  kappafmt = VDF_GZ;
693  } else {
694  Vnm_print(2, "NOsh_parseREAD: Ignoring undefined format \
695  %s!\n", tok);
696  return VRC_FAILURE;
697  }
698 
699  VJMPERR1(Vio_scanf(sock, "%s", tok) == 1);
700  if (tok[0]=='"') {
701  strcpy(strnew, "");
702  while (tok[strlen(tok)-1] != '"') {
703  strcat(str, tok);
704  strcat(str, " ");
705  VJMPERR1(Vio_scanf(sock, "%s", tok) == 1);
706  }
707  strcat(str, tok);
708  strncpy(strnew, str+1, strlen(str)-2);
709  strcpy(tok, strnew);
710  }
711  Vnm_print(0, "NOsh: Storing kappa map %d path %s\n",
712  thee->nkappa, tok);
713  thee->kappafmt[thee->nkappa] = kappafmt;
714  strncpy(thee->kappapath[thee->nkappa], tok, VMAX_ARGLEN);
715  (thee->nkappa)++;
716 
717  return 1;
718 
719 VERROR1:
720  Vnm_print(2, "NOsh_parseREAD: Ran out of tokens while parsing READ \
721 section!\n");
722  return 0;
723 
724 }
725 
726 VPRIVATE int NOsh_parseREAD_POTENTIAL(NOsh *thee, Vio *sock) {
727 
728  char tok[VMAX_BUFSIZE], str[VMAX_BUFSIZE]="", strnew[VMAX_BUFSIZE]="";
729  Vdata_Format potfmt;
730 
731  VJMPERR1(Vio_scanf(sock, "%s", tok) == 1);
732  if (Vstring_strcasecmp(tok, "dx") == 0) {
733  potfmt = VDF_DX;
734  } else if (Vstring_strcasecmp(tok, "gz") == 0) {
735  potfmt = VDF_GZ;
736  } else {
737  Vnm_print(2, "NOsh_parseREAD: Ignoring undefined format \
738  %s!\n", tok);
739  return VRC_FAILURE;
740  }
741 
742  VJMPERR1(Vio_scanf(sock, "%s", tok) == 1);
743  if (tok[0]=='"') {
744  strcpy(strnew, "");
745  while (tok[strlen(tok)-1] != '"') {
746  strcat(str, tok);
747  strcat(str, " ");
748  VJMPERR1(Vio_scanf(sock, "%s", tok) == 1);
749  }
750  strcat(str, tok);
751  strncpy(strnew, str+1, strlen(str)-2);
752  strcpy(tok, strnew);
753  }
754  Vnm_print(0, "NOsh: Storing potential map %d path %s\n",
755  thee->npot, tok);
756  thee->potfmt[thee->npot] = potfmt;
757  strncpy(thee->potpath[thee->npot], tok, VMAX_ARGLEN);
758  (thee->npot)++;
759 
760  return 1;
761 
762 VERROR1:
763  Vnm_print(2, "NOsh_parseREAD: Ran out of tokens while parsing READ \
764  section!\n");
765  return 0;
766 
767 }
768 
769 VPRIVATE int NOsh_parseREAD_CHARGE(NOsh *thee, Vio *sock) {
770 
771  char tok[VMAX_BUFSIZE], str[VMAX_BUFSIZE]="", strnew[VMAX_BUFSIZE]="";
772  Vdata_Format chargefmt;
773 
774  VJMPERR1(Vio_scanf(sock, "%s", tok) == 1);
775  if (Vstring_strcasecmp(tok, "dx") == 0) {
776  chargefmt = VDF_DX;
777  } else if (Vstring_strcasecmp(tok, "gz") == 0) {
778  chargefmt = VDF_GZ;
779  } else {
780  Vnm_print(2, "NOsh_parseREAD: Ignoring undefined format \
781  %s!\n", tok);
782  return VRC_FAILURE;
783  }
784 
785  VJMPERR1(Vio_scanf(sock, "%s", tok) == 1);
786  if (tok[0]=='"') {
787  strcpy(strnew, "");
788  while (tok[strlen(tok)-1] != '"') {
789  strcat(str, tok);
790  strcat(str, " ");
791  VJMPERR1(Vio_scanf(sock, "%s", tok) == 1);
792  }
793  strcat(str, tok);
794  strncpy(strnew, str+1, strlen(str)-2);
795  strcpy(tok, strnew);
796  }
797  Vnm_print(0, "NOsh: Storing charge map %d path %s\n",
798  thee->ncharge, tok);
799  thee->chargefmt[thee->ncharge] = chargefmt;
800  strncpy(thee->chargepath[thee->ncharge], tok, VMAX_ARGLEN);
801  (thee->ncharge)++;
802 
803  return 1;
804 
805 VERROR1:
806  Vnm_print(2, "NOsh_parseREAD: Ran out of tokens while parsing READ \
807 section!\n");
808  return 0;
809 
810 }
811 
812 VPRIVATE int NOsh_parseREAD_MESH(NOsh *thee, Vio *sock) {
813 
814  char tok[VMAX_BUFSIZE], str[VMAX_BUFSIZE]="", strnew[VMAX_BUFSIZE]="";
815  Vdata_Format meshfmt;
816 
817  VJMPERR1(Vio_scanf(sock, "%s", tok) == 1);
818  if (Vstring_strcasecmp(tok, "mcsf") == 0) {
819  meshfmt = VDF_MCSF;
820  VJMPERR1(Vio_scanf(sock, "%s", tok) == 1);
821  if (tok[0]=='"') {
822  strcpy(strnew, "");
823  while (tok[strlen(tok)-1] != '"') {
824  strcat(str, tok);
825  strcat(str, " ");
826  VJMPERR1(Vio_scanf(sock, "%s", tok) == 1);
827  }
828  strcat(str, tok);
829  strncpy(strnew, str+1, strlen(str)-2);
830  strcpy(tok, strnew);
831  }
832  Vnm_print(0, "NOsh: Storing mesh %d path %s\n",
833  thee->nmesh, tok);
834  thee->meshfmt[thee->nmesh] = meshfmt;
835  strncpy(thee->meshpath[thee->nmesh], tok, VMAX_ARGLEN);
836  (thee->nmesh)++;
837  } else {
838  Vnm_print(2, "NOsh_parseREAD: Ignoring undefined mesh format \
839  %s!\n", tok);
840  }
841 
842  return 1;
843 
844 VERROR1:
845  Vnm_print(2, "NOsh_parseREAD: Ran out of tokens while parsing READ \
846  section!\n");
847  return 0;
848 
849 }
850 
851 
852 VPRIVATE int NOsh_parseREAD(NOsh *thee, Vio *sock) {
853 
854  char tok[VMAX_BUFSIZE];
855 
856  if (thee == VNULL) {
857  Vnm_print(2, "NOsh_parseREAD: Got NULL thee!\n");
858  return 0;
859  }
860 
861  if (sock == VNULL) {
862  Vnm_print(2, "NOsh_parseREAD: Got pointer to NULL socket!\n");
863  return 0;
864  }
865 
866  if (thee->parsed) {
867  Vnm_print(2, "NOsh_parseREAD: Already parsed an input file!\n");
868  return 0;
869  }
870 
871  /* Read until we run out of tokens (bad) or hit the "END" keyword (good) */
872  while (Vio_scanf(sock, "%s", tok) == 1) {
873  if (Vstring_strcasecmp(tok, "end") == 0) {
874  Vnm_print(0, "NOsh: Done parsing READ section\n");
875  return 1;
876  } else if (Vstring_strcasecmp(tok, "mol") == 0) {
877  NOsh_parseREAD_MOL(thee, sock);
878  } else if (Vstring_strcasecmp(tok, "parm") == 0) {
879  NOsh_parseREAD_PARM(thee,sock);
880  } else if (Vstring_strcasecmp(tok, "diel") == 0) {
881  NOsh_parseREAD_DIEL(thee,sock);
882  } else if (Vstring_strcasecmp(tok, "kappa") == 0) {
883  NOsh_parseREAD_KAPPA(thee,sock);
884  } else if (Vstring_strcasecmp(tok, "pot") == 0) {
885  NOsh_parseREAD_POTENTIAL(thee,sock);
886  } else if (Vstring_strcasecmp(tok, "charge") == 0) {
887  NOsh_parseREAD_CHARGE(thee,sock);
888  } else if (Vstring_strcasecmp(tok, "mesh") == 0) {
889  NOsh_parseREAD_MESH(thee,sock);
890  } else {
891  Vnm_print(2, "NOsh_parseREAD: Ignoring undefined keyword %s!\n",
892  tok);
893  }
894  }
895 
896  /* We ran out of tokens! */
897  Vnm_print(2, "NOsh_parseREAD: Ran out of tokens while parsing READ \
898 section!\n");
899  return 0;
900 
901 }
902 
903 VPRIVATE int NOsh_parsePRINT(NOsh *thee, Vio *sock) {
904 
905  char tok[VMAX_BUFSIZE];
906  char name[VMAX_BUFSIZE];
907  int ti, idx, expect, ielec, iapol;
908 
909  if (thee == VNULL) {
910  Vnm_print(2, "NOsh_parsePRINT: Got NULL thee!\n");
911  return 0;
912  }
913 
914  if (sock == VNULL) {
915  Vnm_print(2, "NOsh_parsePRINT: Got pointer to NULL socket!\n");
916  return 0;
917  }
918 
919  if (thee->parsed) {
920  Vnm_print(2, "NOsh_parsePRINT: Already parsed an input file!\n");
921  return 0;
922  }
923 
924  idx = thee->nprint;
925  if (thee->nprint >= NOSH_MAXPRINT) {
926  Vnm_print(2, "NOsh_parsePRINT: Exceeded max number (%d) of PRINT \
927 sections\n",
928  NOSH_MAXPRINT);
929  return 0;
930  }
931 
932 
933  /* The first thing we read is the thing we want to print */
934  VJMPERR1(Vio_scanf(sock, "%s", tok) == 1);
935  if (Vstring_strcasecmp(tok, "energy") == 0) {
936  thee->printwhat[idx] = NPT_ENERGY;
937  thee->printnarg[idx] = 0;
938  } else if (Vstring_strcasecmp(tok, "force") == 0) {
939  thee->printwhat[idx] = NPT_FORCE;
940  thee->printnarg[idx] = 0;
941  } else if (Vstring_strcasecmp(tok, "elecEnergy") == 0) {
942  thee->printwhat[idx] = NPT_ELECENERGY;
943  thee->printnarg[idx] = 0;
944  } else if (Vstring_strcasecmp(tok, "elecForce") == 0) {
945  thee->printwhat[idx] = NPT_ELECFORCE;
946  thee->printnarg[idx] = 0;
947  } else if (Vstring_strcasecmp(tok, "apolEnergy") == 0) {
948  thee->printwhat[idx] = NPT_APOLENERGY;
949  thee->printnarg[idx] = 0;
950  } else if (Vstring_strcasecmp(tok, "apolForce") == 0) {
951  thee->printwhat[idx] = NPT_APOLFORCE;
952  thee->printnarg[idx] = 0;
953  } else {
954  Vnm_print(2, "NOsh_parsePRINT: Undefined keyword %s while parsing \
955 PRINT section!\n", tok);
956  return 0;
957  }
958 
959  expect = 0; /* We first expect a calculation ID (0) then an op (1) */
960 
961  /* Read until we run out of tokens (bad) or hit the "END" keyword (good) */
962  while (Vio_scanf(sock, "%s", tok) == 1) {
963 
964  /* The next thing we read is either END or an ARG OP ARG statement */
965  if (Vstring_strcasecmp(tok, "end") == 0) {
966  if (expect != 0) {
967  (thee->nprint)++;
968  (thee->printnarg[idx])++;
969  Vnm_print(0, "NOsh: Done parsing PRINT section\n");
970  return 1;
971  } else {
972  Vnm_print(2, "NOsh_parsePRINT: Got premature END to PRINT!\n");
973  return 0;
974  }
975  } else {
976 
977  /* Grab a calculation ID */
978  if ((sscanf(tok, "%d", &ti) == 1) &&
979  (Vstring_isdigit(tok) == 1)) {
980  if (expect == 0) {
981  thee->printcalc[idx][thee->printnarg[idx]] = ti-1;
982  expect = 1;
983  } else {
984  Vnm_print(2, "NOsh_parsePRINT: Syntax error in PRINT \
985 section while reading %s!\n", tok);
986  return 0;
987  }
988  /* Grab addition operation */
989  } else if (Vstring_strcasecmp(tok, "+") == 0) {
990  if (expect == 1) {
991  thee->printop[idx][thee->printnarg[idx]] = 0;
992  (thee->printnarg[idx])++;
993  expect = 0;
994  if (thee->printnarg[idx] >= NOSH_MAXPOP) {
995  Vnm_print(2, "NOsh_parsePRINT: Exceeded max number \
996 (%d) of arguments for PRINT section!\n",
997  NOSH_MAXPOP);
998  return 0;
999  }
1000  } else {
1001  Vnm_print(2, "NOsh_parsePRINT: Syntax error in PRINT \
1002 section while reading %s!\n", tok);
1003  return 0;
1004  }
1005  /* Grab subtraction operation */
1006  } else if (Vstring_strcasecmp(tok, "-") == 0) {
1007  if (expect == 1) {
1008  thee->printop[idx][thee->printnarg[idx]] = 1;
1009  (thee->printnarg[idx])++;
1010  expect = 0;
1011  if (thee->printnarg[idx] >= NOSH_MAXPOP) {
1012  Vnm_print(2, "NOsh_parseREAD: Exceeded max number \
1013 (%d) of arguments for PRINT section!\n",
1014  NOSH_MAXPOP);
1015  return 0;
1016  }
1017  } else {
1018  Vnm_print(2, "NOsh_parsePRINT: Syntax error in PRINT \
1019 section while reading %s!\n", tok);
1020  return 0;
1021  }
1022  /* Grab a calculation name from elec ID */
1023  } else if (sscanf(tok, "%s", name) == 1) {
1024  if (expect == 0) {
1025  for (ielec=0; ielec<thee->nelec; ielec++) {
1026  if (Vstring_strcasecmp(thee->elecname[ielec], name) == 0) {
1027  thee->printcalc[idx][thee->printnarg[idx]] = ielec;
1028  expect = 1;
1029  break;
1030  }
1031  }
1032  for (iapol=0; iapol<thee->napol; iapol++) {
1033  if (Vstring_strcasecmp(thee->apolname[iapol], name) == 0) {
1034  thee->printcalc[idx][thee->printnarg[idx]] = iapol;
1035  expect = 1;
1036  break;
1037  }
1038  }
1039  if (expect == 0) {
1040  Vnm_print(2, "No ELEC or APOL statement has been named %s!\n",
1041  name);
1042  return 0;
1043  }
1044  } else {
1045  Vnm_print(2, "NOsh_parsePRINT: Syntax error in PRINT \
1046 section while reading %s!\n", tok);
1047  return 0;
1048  }
1049  /* Got bad operation */
1050  } else {
1051  Vnm_print(2, "NOsh_parsePRINT: Undefined keyword %s while \
1052 parsing PRINT section!\n", tok);
1053  return 0;
1054  }
1055  } /* end parse token */
1056 
1057  } /* end while */
1058 
1059  VJMPERR1(0);
1060 
1061  /* We ran out of tokens! */
1062 VERROR1:
1063  Vnm_print(2, "NOsh_parsePRINT: Ran out of tokens while parsing PRINT \
1064 section!\n");
1065  return 0;
1066 
1067 }
1068 
1069 VPRIVATE int NOsh_parseELEC(NOsh *thee, Vio *sock) {
1070 
1071  NOsh_calc *calc = VNULL;
1072 
1073  char tok[VMAX_BUFSIZE];
1074 
1075  if (thee == VNULL) {
1076  Vnm_print(2, "NOsh_parseELEC: Got NULL thee!\n");
1077  return 0;
1078  }
1079 
1080  if (sock == VNULL) {
1081  Vnm_print(2, "NOsh_parseELEC: Got pointer to NULL socket!\n");
1082  return 0;
1083  }
1084 
1085  if (thee->parsed) {
1086  Vnm_print(2, "NOsh_parseELEC: Already parsed an input file!\n");
1087  return 0;
1088  }
1089 
1090  /* Get a pointer to the latest ELEC calc object and update the ELEC
1091  statement number */
1092  if (thee->nelec >= NOSH_MAXCALC) {
1093  Vnm_print(2, "NOsh: Too many electrostatics calculations in this \
1094 run!\n");
1095  Vnm_print(2, "NOsh: Current max is %d; ignoring this calculation\n",
1096  NOSH_MAXCALC);
1097  return 1;
1098  }
1099 
1100  /* The next token HAS to be the method OR "name" */
1101  if (Vio_scanf(sock, "%s", tok) == 1) {
1102  if (Vstring_strcasecmp(tok, "name") == 0) {
1103  Vio_scanf(sock, "%s", tok);
1104  strncpy(thee->elecname[thee->nelec], tok, VMAX_ARGLEN);
1105  if (Vio_scanf(sock, "%s", tok) != 1) {
1106  Vnm_print(2, "NOsh_parseELEC: Ran out of tokens while reading \
1107 ELEC section!\n");
1108  return 0;
1109  }
1110  }
1111  if (Vstring_strcasecmp(tok, "mg-manual") == 0) {
1112  thee->elec[thee->nelec] = NOsh_calc_ctor(NCT_MG);
1113  calc = thee->elec[thee->nelec];
1114  (thee->nelec)++;
1115  calc->mgparm->type = MCT_MANUAL;
1116  return NOsh_parseMG(thee, sock, calc);
1117  } else if (Vstring_strcasecmp(tok, "mg-auto") == 0) {
1118  thee->elec[thee->nelec] = NOsh_calc_ctor(NCT_MG);
1119  calc = thee->elec[thee->nelec];
1120  (thee->nelec)++;
1121  calc->mgparm->type = MCT_AUTO;
1122  return NOsh_parseMG(thee, sock, calc);
1123  } else if (Vstring_strcasecmp(tok, "mg-para") == 0) {
1124  thee->elec[thee->nelec] = NOsh_calc_ctor(NCT_MG);
1125  calc = thee->elec[thee->nelec];
1126  (thee->nelec)++;
1127  calc->mgparm->type = MCT_PARALLEL;
1128  return NOsh_parseMG(thee, sock, calc);
1129  } else if (Vstring_strcasecmp(tok, "mg-dummy") == 0) {
1130  thee->elec[thee->nelec] = NOsh_calc_ctor(NCT_MG);
1131  calc = thee->elec[thee->nelec];
1132  (thee->nelec)++;
1133  calc->mgparm->type = MCT_DUMMY;
1134  return NOsh_parseMG(thee, sock, calc);
1135  } else if (Vstring_strcasecmp(tok, "fe-manual") == 0) {
1136  thee->elec[thee->nelec] = NOsh_calc_ctor(NCT_FEM);
1137  calc = thee->elec[thee->nelec];
1138  (thee->nelec)++;
1139  calc->femparm->type = FCT_MANUAL;
1140  return NOsh_parseFEM(thee, sock, calc);
1141  } else {
1142  Vnm_print(2, "NOsh_parseELEC: The method (\"mg\" or \"fem\") or \
1143 \"name\" must be the first keyword in the ELEC section\n");
1144  return 0;
1145  }
1146  }
1147 
1148  Vnm_print(2, "NOsh_parseELEC: Ran out of tokens while reading ELEC section!\n");
1149  return 0;
1150 
1151 }
1152 
1153 VPRIVATE int NOsh_parseAPOLAR(NOsh *thee, Vio *sock) {
1154 
1155  NOsh_calc *calc = VNULL;
1156 
1157  char tok[VMAX_BUFSIZE];
1158 
1159  if (thee == VNULL) {
1160  Vnm_print(2, "NOsh_parseAPOLAR: Got NULL thee!\n");
1161  return 0;
1162  }
1163 
1164  if (sock == VNULL) {
1165  Vnm_print(2, "NOsh_parseAPOLAR: Got pointer to NULL socket!\n");
1166  return 0;
1167  }
1168 
1169  if (thee->parsed) {
1170  Vnm_print(2, "NOsh_parseAPOLAR: Already parsed an input file!\n");
1171  return 0;
1172  }
1173 
1174  /* Get a pointer to the latest ELEC calc object and update the ELEC
1175  statement number */
1176  if (thee->napol >= NOSH_MAXCALC) {
1177  Vnm_print(2, "NOsh: Too many non-polar calculations in this \
1178 run!\n");
1179  Vnm_print(2, "NOsh: Current max is %d; ignoring this calculation\n",
1180  NOSH_MAXCALC);
1181  return 1;
1182  }
1183 
1184  /* The next token HAS to be the method OR "name" */
1185  if (Vio_scanf(sock, "%s", tok) == 1) {
1186  if (Vstring_strcasecmp(tok, "name") == 0) {
1187  Vio_scanf(sock, "%s", tok);
1188  strncpy(thee->apolname[thee->napol], tok, VMAX_ARGLEN);
1189 
1190  /* Parse the non-polar parameters */
1191  thee->apol[thee->napol] = NOsh_calc_ctor(NCT_APOL);
1192  calc = thee->apol[thee->napol];
1193  (thee->napol)++;
1194  return NOsh_parseAPOL(thee, sock, calc);
1195 
1196  if (Vio_scanf(sock, "%s", tok) != 1) {
1197  Vnm_print(2, "NOsh_parseAPOLAR: Ran out of tokens while reading \
1198 APOLAR section!\n");
1199  return 0;
1200  }
1201  }
1202  }
1203 
1204  return 1;
1205 
1206 }
1207 
1209  NOsh *thee,
1210  Valist *alist[NOSH_MAXMOL]
1211  ) {
1212  int ielec, imol, i;
1213  NOsh_calc *elec = VNULL;
1214  MGparm *mgparm = VNULL;
1215  Valist *mymol = VNULL;
1216 
1217  VASSERT(thee != VNULL);
1218  for (imol=0; imol<thee->nmol; imol++) {
1219  thee->alist[imol] = alist[imol];
1220  }
1221 
1222 
1223  for (ielec=0; ielec<(thee->nelec); ielec++) {
1224  /* Unload the calculation object containing the ELEC information */
1225  elec = thee->elec[ielec];
1226 
1227  if (((thee->ndiel != 0) || (thee->nkappa != 0) ||
1228  (thee->ncharge != 0) || (thee->npot != 0)) &&
1229  (elec->pbeparm->calcforce != PCF_NO)) {
1230  Vnm_print(2, "NOsh_setupElecCalc: Calculation of forces disabled because surface \
1231 map is used!\n");
1232  elec->pbeparm->calcforce = PCF_NO;
1233  }
1234 
1235  /* Setup the calculation */
1236  switch (elec->calctype) {
1237  case NCT_MG:
1238  /* Center on the molecules, if requested */
1239  mgparm = elec->mgparm;
1240  VASSERT(mgparm != VNULL);
1241  if (elec->mgparm->cmeth == MCM_MOLECULE) {
1242  VASSERT(mgparm->centmol >= 0);
1243  VASSERT(mgparm->centmol < thee->nmol);
1244  mymol = thee->alist[mgparm->centmol];
1245  VASSERT(mymol != VNULL);
1246  for (i=0; i<3; i++) {
1247  mgparm->center[i] = mymol->center[i];
1248  }
1249  }
1250  if (elec->mgparm->fcmeth == MCM_MOLECULE) {
1251  VASSERT(mgparm->fcentmol >= 0);
1252  VASSERT(mgparm->fcentmol < thee->nmol);
1253  mymol = thee->alist[mgparm->fcentmol];
1254  VASSERT(mymol != VNULL);
1255  for (i=0; i<3; i++) {
1256  mgparm->fcenter[i] = mymol->center[i];
1257  }
1258  }
1259  if (elec->mgparm->ccmeth == MCM_MOLECULE) {
1260  VASSERT(mgparm->ccentmol >= 0);
1261  VASSERT(mgparm->ccentmol < thee->nmol);
1262  mymol = thee->alist[mgparm->ccentmol];
1263  VASSERT(mymol != VNULL);
1264  for (i=0; i<3; i++) {
1265  mgparm->ccenter[i] = mymol->center[i];
1266  }
1267  }
1268  NOsh_setupCalcMG(thee, elec);
1269  break;
1270  case NCT_FEM:
1271  NOsh_setupCalcFEM(thee, elec);
1272  break;
1273  default:
1274  Vnm_print(2, "NOsh_setupCalc: Invalid calculation type (%d)!\n",
1275  elec->calctype);
1276  return 0;
1277  }
1278 
1279  /* At this point, the most recently-created NOsh_calc object should be the
1280  one we use for results for this ELEC statement. Assign it. */
1281  /* Associate ELEC statement with the calculation */
1282  thee->elec2calc[ielec] = thee->ncalc-1;
1283  Vnm_print(0, "NOsh_setupCalc: Mapping ELEC statement %d (%d) to \
1284 calculation %d (%d)\n", ielec, ielec+1, thee->elec2calc[ielec],
1285  thee->elec2calc[ielec]+1);
1286  }
1287 
1288  return 1;
1289 }
1290 
1292  NOsh *thee,
1293  Valist *alist[NOSH_MAXMOL]
1294  ) {
1295  int iapol, imol;
1296  int doCalc = ACD_NO;
1297  NOsh_calc *calc = VNULL;
1298 
1299  VASSERT(thee != VNULL);
1300  for (imol=0; imol<thee->nmol; imol++) {
1301  thee->alist[imol] = alist[imol];
1302  }
1303 
1304  for (iapol=0; iapol<(thee->napol); iapol++) {
1305  /* Unload the calculation object containing the APOL information */
1306  calc = thee->apol[iapol];
1307 
1308  /* Setup the calculation */
1309  switch (calc->calctype) {
1310  case NCT_APOL:
1311  NOsh_setupCalcAPOL(thee, calc);
1312  doCalc = ACD_YES;
1313  break;
1314  default:
1315  Vnm_print(2, "NOsh_setupCalc: Invalid calculation type (%d)!\n", calc->calctype);
1316  return ACD_ERROR;
1317  }
1318  /* At this point, the most recently-created NOsh_calc object should be the
1319  one we use for results for this APOL statement. Assign it. */
1320  /* Associate APOL statement with the calculation */
1321  thee->apol2calc[iapol] = thee->ncalc-1;
1322  Vnm_print(0, "NOsh_setupCalc: Mapping APOL statement %d (%d) to calculation %d (%d)\n", iapol, iapol+1, thee->apol2calc[iapol], thee->apol2calc[iapol]+1);
1323  }
1324 
1325  if(doCalc == ACD_YES){
1326  return ACD_YES;
1327  }else{
1328  return ACD_NO;
1329  }
1330 }
1331 
1332 VPUBLIC int NOsh_parseMG(
1333  NOsh *thee,
1334  Vio *sock,
1335  NOsh_calc *elec
1336  ) {
1337 
1338  char tok[VMAX_BUFSIZE];
1339  MGparm *mgparm = VNULL;
1340  PBEparm *pbeparm = VNULL;
1341  int rc;
1342 
1343  /* Check the arguments */
1344  if (thee == VNULL) {
1345  Vnm_print(2, "NOsh: Got NULL thee!\n");
1346  return 0;
1347  }
1348  if (sock == VNULL) {
1349  Vnm_print(2, "NOsh: Got pointer to NULL socket!\n");
1350  return 0;
1351  }
1352  if (elec == VNULL) {
1353  Vnm_print(2, "NOsh: Got pointer to NULL elec object!\n");
1354  return 0;
1355  }
1356  mgparm = elec->mgparm;
1357  if (mgparm == VNULL) {
1358  Vnm_print(2, "NOsh: Got pointer to NULL mgparm object!\n");
1359  return 0;
1360  }
1361  pbeparm = elec->pbeparm;
1362  if (pbeparm == VNULL) {
1363  Vnm_print(2, "NOsh: Got pointer to NULL pbeparm object!\n");
1364  return 0;
1365  }
1366 
1367  Vnm_print(0, "NOsh_parseMG: Parsing parameters for MG calculation\n");
1368 
1369  /* Parallel stuff */
1370  if (mgparm->type == MCT_PARALLEL) {
1371  mgparm->proc_rank = thee->proc_rank;
1372  mgparm->proc_size = thee->proc_size;
1373  mgparm->setrank = 1;
1374  mgparm->setsize = 1;
1375  }
1376 
1377 
1378  /* Start snarfing tokens from the input stream */
1379  rc = 1;
1380  while (Vio_scanf(sock, "%s", tok) == 1) {
1381 
1382  Vnm_print(0, "NOsh_parseMG: Parsing %s...\n", tok);
1383 
1384  /* See if it's an END token */
1385  if (Vstring_strcasecmp(tok, "end") == 0) {
1386  mgparm->parsed = 1;
1387  pbeparm->parsed = 1;
1388  rc = 1;
1389  break;
1390  }
1391 
1392  /* Pass the token through a series of parsers */
1393  rc = PBEparm_parseToken(pbeparm, tok, sock);
1394  if (rc == -1) {
1395  Vnm_print(0, "NOsh_parseMG: parsePBE error!\n");
1396  break;
1397  } else if (rc == 0) {
1398  /* Pass the token to the generic MG parser */
1399  rc = MGparm_parseToken(mgparm, tok, sock);
1400  if (rc == -1) {
1401  Vnm_print(0, "NOsh_parseMG: parseMG error!\n");
1402  break;
1403  } else if (rc == 0) {
1404  /* We ran out of parsers! */
1405  Vnm_print(2, "NOsh: Unrecognized keyword: %s\n", tok);
1406  break;
1407  }
1408  }
1409  }
1410 
1411  /* Handle various errors arising in the token-snarfing loop -- these all
1412  just result in simple returns right now */
1413  if (rc == -1) return 0;
1414  if (rc == 0) return 0;
1415 
1416  /* Check the status of the parameter objects */
1417  if ((MGparm_check(mgparm) == VRC_FAILURE) || (!PBEparm_check(pbeparm))) {
1418  Vnm_print(2, "NOsh: MG parameters not set correctly!\n");
1419  return 0;
1420  }
1421 
1422  return 1;
1423 }
1424 
1425 VPRIVATE int NOsh_setupCalcMG(
1426  NOsh *thee,
1427  NOsh_calc *calc
1428  ) {
1429 
1430  MGparm *mgparm = VNULL;
1431 
1432  VASSERT(thee != VNULL);
1433  VASSERT(calc != VNULL);
1434  mgparm = calc->mgparm;
1435  VASSERT(mgparm != VNULL);
1436 
1437 
1438  /* Now we're ready to whatever sorts of post-processing operations that are
1439  necessary for the various types of calculations */
1440  switch (mgparm->type) {
1441  case MCT_MANUAL:
1442  return NOsh_setupCalcMGMANUAL(thee, calc);
1443  case MCT_DUMMY:
1444  return NOsh_setupCalcMGMANUAL(thee, calc);
1445  case MCT_AUTO:
1446  return NOsh_setupCalcMGAUTO(thee, calc);
1447  case MCT_PARALLEL:
1448  return NOsh_setupCalcMGPARA(thee, calc);
1449  default:
1450  Vnm_print(2, "NOsh_setupCalcMG: undefined MG calculation type (%d)!\n",
1451  mgparm->type);
1452  return 0;
1453  }
1454 
1455  /* Shouldn't get here */
1456  return 0;
1457 }
1458 
1459 VPRIVATE int NOsh_setupCalcFEM(
1460  NOsh *thee,
1461  NOsh_calc *calc
1462  ) {
1463 
1464  VASSERT(thee != VNULL);
1465  VASSERT(calc != VNULL);
1466  VASSERT(calc->femparm != VNULL);
1467 
1468  /* Now we're ready to whatever sorts of post-processing operations that are
1469  * necessary for the various types of calculations */
1470  switch (calc->femparm->type) {
1471  case FCT_MANUAL:
1472  return NOsh_setupCalcFEMANUAL(thee, calc);
1473  default:
1474  Vnm_print(2, "NOsh_parseFEM: unknown calculation type (%d)!\n",
1475  calc->femparm->type);
1476  return 0;
1477  }
1478 
1479  /* Shouldn't get here */
1480  return 0;
1481 }
1482 
1483 
1484 VPRIVATE int NOsh_setupCalcMGMANUAL(
1485  NOsh *thee,
1486  NOsh_calc *elec
1487  ) {
1488 
1489  MGparm *mgparm = VNULL;
1490  PBEparm *pbeparm = VNULL;
1491  NOsh_calc *calc = VNULL;
1492 
1493  if (thee == VNULL) {
1494  Vnm_print(2, "NOsh_setupCalcMGMANUAL: Got NULL thee!\n");
1495  return 0;
1496  }
1497  if (elec == VNULL) {
1498  Vnm_print(2, "NOsh_setupCalcMGMANUAL: Got NULL calc!\n");
1499  return 0;
1500  }
1501  mgparm = elec->mgparm;
1502  if (mgparm == VNULL) {
1503  Vnm_print(2, "NOsh_setupCalcMGMANUAL: Got NULL mgparm -- was this calculation \
1504 set up?\n");
1505  return 0;
1506  }
1507  pbeparm = elec->pbeparm;
1508  if (pbeparm == VNULL) {
1509  Vnm_print(2, "NOsh_setupCalcMGMANUAL: Got NULL pbeparm -- was this calculation \
1510 set up?\n");
1511  return 0;
1512  }
1513 
1514  /* Set up missing MG parameters */
1515  if (mgparm->setgrid == 0) {
1516  VASSERT(mgparm->setglen);
1517  mgparm->grid[0] = mgparm->glen[0]/((double)(mgparm->dime[0]-1));
1518  mgparm->grid[1] = mgparm->glen[1]/((double)(mgparm->dime[1]-1));
1519  mgparm->grid[2] = mgparm->glen[2]/((double)(mgparm->dime[2]-1));
1520  }
1521  if (mgparm->setglen == 0) {
1522  VASSERT(mgparm->setgrid);
1523  mgparm->glen[0] = mgparm->grid[0]*((double)(mgparm->dime[0]-1));
1524  mgparm->glen[1] = mgparm->grid[1]*((double)(mgparm->dime[1]-1));
1525  mgparm->glen[2] = mgparm->grid[2]*((double)(mgparm->dime[2]-1));
1526  }
1527 
1528  /* Check to see if he have any room left for this type of calculation, if
1529  so: set the calculation type, update the number of calculations of this type,
1530  and parse the rest of the section */
1531  if (thee->ncalc >= NOSH_MAXCALC) {
1532  Vnm_print(2, "NOsh: Too many calculations in this run!\n");
1533  Vnm_print(2, "NOsh: Current max is %d; ignoring this calculation\n",
1534  NOSH_MAXCALC);
1535  return 0;
1536  }
1537 
1538  /* Get the next calculation object and increment the number of calculations */
1539  thee->calc[thee->ncalc] = NOsh_calc_ctor(NCT_MG);
1540  calc = thee->calc[thee->ncalc];
1541  (thee->ncalc)++;
1542 
1543 
1544 
1545  /* Copy over contents of ELEC */
1546  NOsh_calc_copy(calc, elec);
1547 
1548 
1549  return 1;
1550 }
1551 
1552 VPUBLIC int NOsh_setupCalcMGAUTO(
1553  NOsh *thee,
1554  NOsh_calc *elec
1555  ) {
1556 
1557  NOsh_calc *calcf = VNULL;
1558  NOsh_calc *calcc = VNULL;
1559  double fgrid[3], cgrid[3];
1560  double d[3], minf[3], maxf[3], minc[3], maxc[3];
1561  double redfrac, redrat[3], td;
1562  int ifocus, nfocus, tnfocus[3];
1563  int j;
1564  int icalc;
1565  int dofix;
1566 
1567  /* A comment about the coding style in this function. I use lots and lots
1568  and lots of pointer deferencing. I could (and probably should) save
1569  these in temporary variables. However, since there are so many MGparm,
1570  etc. and NOsh_calc, etc. objects running around in this function, the
1571  current scheme is easiest to debug. */
1572 
1573 
1574  if (thee == VNULL) {
1575  Vnm_print(2, "NOsh_setupCalcMGAUTO: Got NULL thee!\n");
1576  return 0;
1577  }
1578  if (elec == VNULL) {
1579  Vnm_print(2, "NOsh_setupCalcMGAUTO: Got NULL elec!\n");
1580  return 0;
1581  }
1582  if (elec->mgparm == VNULL) {
1583  Vnm_print(2, "NOsh_setupCalcMGAUTO: Got NULL mgparm!\n");
1584  return 0;
1585  }
1586  if (elec->pbeparm == VNULL) {
1587  Vnm_print(2, "NOsh_setupCalcMGAUTO: Got NULL pbeparm!\n");
1588  return 0;
1589  }
1590 
1591  Vnm_print(0, "NOsh_setupCalcMGAUTO(%s, %d): coarse grid center = %g %g %g\n",
1592  __FILE__, __LINE__,
1593  elec->mgparm->ccenter[0],
1594  elec->mgparm->ccenter[1],
1595  elec->mgparm->ccenter[2]);
1596  Vnm_print(0, "NOsh_setupCalcMGAUTO(%s, %d): fine grid center = %g %g %g\n",
1597  __FILE__, __LINE__,
1598  elec->mgparm->fcenter[0],
1599  elec->mgparm->fcenter[1],
1600  elec->mgparm->fcenter[2]);
1601 
1602  /* Calculate the grid spacing on the coarse and fine levels */
1603  for (j=0; j<3; j++) {
1604  cgrid[j] = (elec->mgparm->cglen[j])/((double)(elec->mgparm->dime[j]-1));
1605  fgrid[j] = (elec->mgparm->fglen[j])/((double)(elec->mgparm->dime[j]-1));
1606  d[j] = elec->mgparm->fcenter[j] - elec->mgparm->ccenter[j];
1607  }
1608  Vnm_print(0, "NOsh_setupCalcMGAUTO (%s, %d): Coarse grid spacing = %g, %g, %g\n",
1609  __FILE__, __LINE__, cgrid[0], cgrid[1], cgrid[2]);
1610  Vnm_print(0, "NOsh_setupCalcMGAUTO (%s, %d): Fine grid spacing = %g, %g, %g\n",
1611  __FILE__, __LINE__, fgrid[0], fgrid[1], fgrid[2]);
1612  Vnm_print(0, "NOsh_setupCalcMGAUTO (%s, %d): Displacement between fine and \
1613 coarse grids = %g, %g, %g\n", __FILE__, __LINE__, d[0], d[1], d[2]);
1614 
1615  /* Now calculate the number of focusing levels, never reducing the grid
1616  spacing by more than redfrac at each level */
1617  for (j=0; j<3; j++) {
1618  if (fgrid[j]/cgrid[j] < VREDFRAC) {
1619  redfrac = fgrid[j]/cgrid[j];
1620  td = log(redfrac)/log(VREDFRAC);
1621  tnfocus[j] = (int)ceil(td) + 1;
1622  } else tnfocus[j] = 2;
1623  }
1624  nfocus = VMAX2(VMAX2(tnfocus[0], tnfocus[1]), tnfocus[2]);
1625 
1626  /* Now set redrat to the actual value by which the grid spacing is reduced
1627  at each level of focusing */
1628  for (j=0; j<3; j++) {
1629  redrat[j] = VPOW((fgrid[j]/cgrid[j]), 1.0/((double)nfocus-1.0));
1630  }
1631  Vnm_print(0, "NOsh: %d levels of focusing with %g, %g, %g reductions\n",
1632  nfocus, redrat[0], redrat[1], redrat[2]);
1633 
1634  /* Now that we know how many focusing levels to use, we're ready to set up
1635  the parameter objects */
1636  if (nfocus > (NOSH_MAXCALC-(thee->ncalc))) {
1637  Vnm_print(2, "NOsh: Require more calculations than max (%d)!\n",
1638  NOSH_MAXCALC);
1639  return 0;
1640  }
1641 
1642  for (ifocus=0; ifocus<nfocus; ifocus++) {
1643 
1644  /* Generate the new calc object */
1645  icalc = thee->ncalc;
1646  thee->calc[icalc] = NOsh_calc_ctor(NCT_MG);
1647  (thee->ncalc)++;
1648 
1649  /* This is the _current_ NOsh_calc object */
1650  calcf = thee->calc[icalc];
1651  /* This is the _previous_ Nosh_calc object */
1652  if (ifocus != 0) {
1653  calcc = thee->calc[icalc-1];
1654  } else {
1655  calcc = VNULL;
1656  }
1657 
1658  /* Copy over most of the parameters from the ELEC object */
1659  NOsh_calc_copy(calcf, elec);
1660 
1661  /* Set up the grid lengths and spacings */
1662  if (ifocus == 0) {
1663  for (j=0; j<3; j++) {
1664  calcf->mgparm->grid[j] = cgrid[j];
1665  calcf->mgparm->glen[j] = elec->mgparm->cglen[j];
1666  }
1667  } else {
1668  for (j=0; j<3; j++) {
1669  calcf->mgparm->grid[j] = redrat[j]*(calcc->mgparm->grid[j]);
1670  calcf->mgparm->glen[j] = redrat[j]*(calcc->mgparm->glen[j]);
1671  }
1672  }
1673  calcf->mgparm->setgrid = 1;
1674  calcf->mgparm->setglen = 1;
1675 
1676  /* Get centers and centering method from coarse and fine meshes */
1677  if (ifocus == 0) {
1678  calcf->mgparm->cmeth = elec->mgparm->ccmeth;
1679  calcf->mgparm->centmol = elec->mgparm->ccentmol;
1680  for (j=0; j<3; j++) {
1681  calcf->mgparm->center[j] = elec->mgparm->ccenter[j];
1682  }
1683  } else if (ifocus == (nfocus-1)) {
1684  calcf->mgparm->cmeth = elec->mgparm->fcmeth;
1685  calcf->mgparm->centmol = elec->mgparm->fcentmol;
1686  for (j=0; j<3; j++) {
1687  calcf->mgparm->center[j] = elec->mgparm->fcenter[j];
1688  }
1689  } else {
1690  calcf->mgparm->cmeth = MCM_FOCUS;
1691  /* TEMPORARILY move the current grid center
1692  to the fine grid center. In general, this will move portions of
1693  the current mesh off the immediately-coarser mesh. We'll fix that
1694  in the next step. */
1695  for (j=0; j<3; j++) {
1696  calcf->mgparm->center[j] = elec->mgparm->fcenter[j];
1697  }
1698  }
1699 
1700 
1701  /* As mentioned above, it is highly likely that the previous "jump"
1702  to the fine grid center put portions of the current mesh off the
1703  previous (coarser) mesh. Fix this by displacing the current mesh
1704  back onto the previous coarser mesh. */
1705  if (ifocus != 0) {
1706  Vnm_print(0, "NOsh_setupCalcMGAUTO (%s, %d): starting mesh \
1707 repositioning.\n", __FILE__, __LINE__);
1708  Vnm_print(0, "NOsh_setupCalcMGAUTO (%s, %d): coarse mesh center = \
1709 %g %g %g\n", __FILE__, __LINE__,
1710  calcc->mgparm->center[0],
1711  calcc->mgparm->center[1],
1712  calcc->mgparm->center[2]);
1713  Vnm_print(0, "NOsh_setupCalcMGAUTO (%s, %d): coarse mesh upper corner = \
1714 %g %g %g\n", __FILE__, __LINE__,
1715  calcc->mgparm->center[0]+0.5*(calcc->mgparm->glen[0]),
1716  calcc->mgparm->center[1]+0.5*(calcc->mgparm->glen[1]),
1717  calcc->mgparm->center[2]+0.5*(calcc->mgparm->glen[2]));
1718  Vnm_print(0, "NOsh_setupCalcMGAUTO (%s, %d): coarse mesh lower corner = \
1719 %g %g %g\n", __FILE__, __LINE__,
1720  calcc->mgparm->center[0]-0.5*(calcc->mgparm->glen[0]),
1721  calcc->mgparm->center[1]-0.5*(calcc->mgparm->glen[1]),
1722  calcc->mgparm->center[2]-0.5*(calcc->mgparm->glen[2]));
1723  Vnm_print(0, "NOsh_setupCalcMGAUTO (%s, %d): initial fine mesh upper corner = \
1724 %g %g %g\n", __FILE__, __LINE__,
1725  calcf->mgparm->center[0]+0.5*(calcf->mgparm->glen[0]),
1726  calcf->mgparm->center[1]+0.5*(calcf->mgparm->glen[1]),
1727  calcf->mgparm->center[2]+0.5*(calcf->mgparm->glen[2]));
1728  Vnm_print(0, "NOsh_setupCalcMGAUTO (%s, %d): initial fine mesh lower corner = \
1729 %g %g %g\n", __FILE__, __LINE__,
1730  calcf->mgparm->center[0]-0.5*(calcf->mgparm->glen[0]),
1731  calcf->mgparm->center[1]-0.5*(calcf->mgparm->glen[1]),
1732  calcf->mgparm->center[2]-0.5*(calcf->mgparm->glen[2]));
1733  for (j=0; j<3; j++) {
1734  /* Check if we've fallen off of the lower end of the mesh */
1735  dofix = 0;
1736  minf[j] = calcf->mgparm->center[j]
1737  - 0.5*(calcf->mgparm->glen[j]);
1738  minc[j] = calcc->mgparm->center[j]
1739  - 0.5*(calcc->mgparm->glen[j]);
1740  d[j] = minc[j] - minf[j];
1741  if (d[j] >= VSMALL) {
1742  if (ifocus == (nfocus-1)) {
1743  Vnm_print(2, "NOsh_setupCalcMGAUTO: Error! Finest \
1744 mesh has fallen off the coarser meshes!\n");
1745  Vnm_print(2, "NOsh_setupCalcMGAUTO: difference in min %d-\
1746 direction = %g\n", j, d[j]);
1747  Vnm_print(2, "NOsh_setupCalcMGAUTO: min fine = %g %g %g\n",
1748  minf[0], minf[1], minf[2]);
1749  Vnm_print(2, "NOsh_setupCalcMGAUTO: min coarse = %g %g %g\n",
1750  minc[0], minc[1], minc[2]);
1751  VASSERT(0);
1752  } else {
1753  Vnm_print(0, "NOsh_setupCalcMGAUTO (%s, %d): ifocus = %d, \
1754 fixing mesh min violation (%g in %d-direction).\n", __FILE__, __LINE__, ifocus,
1755  d[j], j);
1756  calcf->mgparm->center[j] += d[j];
1757  dofix = 1;
1758  }
1759  }
1760  /* Check if we've fallen off of the upper end of the mesh */
1761  maxf[j] = calcf->mgparm->center[j] \
1762  + 0.5*(calcf->mgparm->glen[j]);
1763  maxc[j] = calcc->mgparm->center[j] \
1764  + 0.5*(calcc->mgparm->glen[j]);
1765  d[j] = maxf[j] - maxc[j];
1766  if (d[j] >= VSMALL) {
1767  if (ifocus == (nfocus-1)) {
1768  Vnm_print(2, "NOsh_setupCalcMGAUTO: Error! Finest \
1769 mesh has fallen off the coarser meshes!\n");
1770  Vnm_print(2, "NOsh_setupCalcMGAUTO: difference in %d-\
1771 direction = %g\n", j, d[j]);
1772  VASSERT(0);
1773  } else {
1774  /* If we already fixed the lower boundary and we now need
1775  to fix the upper boundary, we have a serious problem. */
1776  if (dofix) {
1777  Vnm_print(2, "NOsh_setupCalcMGAUTO: Error! Both \
1778 ends of the finer mesh do not fit in the bigger mesh!\n");
1779  VASSERT(0);
1780  }
1781  Vnm_print(0, "NOsh_setupCalcMGAUTO(%s, %d): ifocus = %d, \
1782 fixing mesh max violation (%g in %d-direction).\n", __FILE__, __LINE__, ifocus,
1783  d[j], j);
1784  calcf->mgparm->center[j] -= d[j];
1785  dofix = 1;
1786  }
1787  }
1788  }
1789  Vnm_print(0, "NOsh_setupCalcMGAUTO (%s, %d): final fine mesh upper corner = \
1790 %g %g %g\n", __FILE__, __LINE__,
1791  calcf->mgparm->center[0]+0.5*(calcf->mgparm->glen[0]),
1792  calcf->mgparm->center[1]+0.5*(calcf->mgparm->glen[1]),
1793  calcf->mgparm->center[2]+0.5*(calcf->mgparm->glen[2]));
1794  Vnm_print(0, "NOsh_setupCalcMGAUTO (%s, %d): final fine mesh lower corner = \
1795 %g %g %g\n", __FILE__, __LINE__,
1796  calcf->mgparm->center[0]-0.5*(calcf->mgparm->glen[0]),
1797  calcf->mgparm->center[1]-0.5*(calcf->mgparm->glen[1]),
1798  calcf->mgparm->center[2]-0.5*(calcf->mgparm->glen[2]));
1799  }
1800 
1801  /* Finer levels have focusing boundary conditions */
1802  if (ifocus != 0) calcf->pbeparm->bcfl = BCFL_FOCUS;
1803 
1804  /* Only the finest level handles I/O and needs to worry about disjoint
1805  partitioning */
1806  if (ifocus != (nfocus-1)) calcf->pbeparm->numwrite = 0;
1807 
1808  /* Reset boundary flags for everything except parallel focusing */
1809  if (calcf->mgparm->type != MCT_PARALLEL) {
1810  Vnm_print(0, "NOsh_setupMGAUTO: Resetting boundary flags\n");
1811  for (j=0; j<6; j++) calcf->mgparm->partDisjOwnSide[j] = 0;
1812  for (j=0; j<3; j++) {
1813  calcf->mgparm->partDisjCenter[j] = 0;
1814  calcf->mgparm->partDisjLength[j] = calcf->mgparm->glen[j];
1815  }
1816  }
1817 
1818 
1819  calcf->mgparm->parsed = 1;
1820  }
1821 
1822 
1823  return 1;
1824 }
1825 
1826 /* Author: Nathan Baker and Todd Dolinsky */
1827 VPUBLIC int NOsh_setupCalcMGPARA(
1828  NOsh *thee,
1829  NOsh_calc *elec
1830  ) {
1831 
1832  /* NEW (25-Jul-2006): This code should produce modify the ELEC statement
1833  and pass it on to MGAUTO for further processing. */
1834 
1835  MGparm *mgparm = VNULL;
1836  double ofrac;
1837  double hx, hy, hzed;
1838  double xofrac, yofrac, zofrac;
1839  int rank, size, npx, npy, npz, nproc, ip, jp, kp;
1840  int xeffGlob, yeffGlob, zeffGlob, xDisj, yDisj, zDisj;
1841  int xigminDisj, xigmaxDisj, yigminDisj, yigmaxDisj, zigminDisj, zigmaxDisj;
1842  int xigminOlap, xigmaxOlap, yigminOlap, yigmaxOlap, zigminOlap, zigmaxOlap;
1843  int xOlapReg, yOlapReg, zOlapReg;
1844  double xlenDisj, ylenDisj, zlenDisj;
1845  double xcentDisj, ycentDisj, zcentDisj;
1846  double xcentOlap, ycentOlap, zcentOlap;
1847  double xlenOlap, ylenOlap, zlenOlap;
1848  double xminOlap, xmaxOlap, yminOlap, ymaxOlap, zminOlap, zmaxOlap;
1849  double xminDisj, xmaxDisj, yminDisj, ymaxDisj, zminDisj, zmaxDisj;
1850  double xcent, ycent, zcent;
1851 
1852  /* Grab some useful variables */
1853  VASSERT(thee != VNULL);
1854  VASSERT(elec != VNULL);
1855  mgparm = elec->mgparm;
1856  VASSERT(mgparm != VNULL);
1857 
1858  /* Grab some useful variables */
1859  ofrac = mgparm->ofrac;
1860  npx = mgparm->pdime[0];
1861  npy = mgparm->pdime[1];
1862  npz = mgparm->pdime[2];
1863  nproc = npx*npy*npz;
1864 
1865  /* If this is not an asynchronous calculation, then we need to make sure we
1866  have all the necessary MPI information */
1867  if (mgparm->setasync == 0) {
1868 
1869 #ifndef HAVE_MPI_H
1870 
1871  Vnm_tprint(2, "NOsh_setupCalcMGPARA: Oops! You're trying to perform \
1872 an 'mg-para' (parallel) calculation\n");
1873  Vnm_tprint(2, "NOsh_setupCalcMGPARA: with a version of APBS that wasn't \
1874 compiled with MPI!\n");
1875  Vnm_tprint(2, "NOsh_setupCalcMGPARA: Perhaps you meant to use the \
1876 'async' flag?\n");
1877  Vnm_tprint(2, "NOsh_setupCalcMGPARA: Bailing out!\n");
1878 
1879  return 0;
1880 
1881 #endif
1882 
1883  rank = thee->proc_rank;
1884  size = thee->proc_size;
1885  Vnm_print(0, "NOsh_setupCalcMGPARA: Hello from processor %d of %d\n", rank,
1886  size);
1887 
1888  /* Check to see if we have too many processors. If so, then simply set
1889  this processor to duplicating the work of processor 0. */
1890  if (rank > (nproc-1)) {
1891  Vnm_print(2, "NOsh_setupMGPARA: There are more processors available than\
1892 the %d you requested.\n", nproc);
1893  Vnm_print(2, "NOsh_setupMGPARA: Eliminating processor %d\n", rank);
1894  thee->bogus = 1;
1895  rank = 0;
1896  }
1897 
1898  /* Check to see if we have too few processors. If so, this is a fatal
1899  error. */
1900  if (size < nproc) {
1901  Vnm_print(2, "NOsh_setupMGPARA: There are too few processors (%d) to \
1902 satisfy requirements (%d)\n", size, nproc);
1903  return 0;
1904  }
1905 
1906  Vnm_print(0, "NOsh_setupMGPARA: Hello (again) from processor %d of %d\n",
1907  rank, size);
1908 
1909  } else { /* Setting up for an asynchronous calculation. */
1910 
1911  rank = mgparm->async;
1912 
1913  thee->ispara = 1;
1914  thee->proc_rank = rank;
1915 
1916  /* Check to see if the async id is greater than the number of
1917  * processors. If so, this is a fatal error. */
1918  if (rank > (nproc-1)) {
1919  Vnm_print(2, "NOsh_setupMGPARA: The processor id you requested (%d) \
1920 is not within the range of processors available (0-%d)\n", rank, (nproc-1));
1921  return 0;
1922  }
1923  }
1924 
1925  /* Calculate the processor's coordinates in the processor grid */
1926  kp = (int)floor(rank/(npx*npy));
1927  jp = (int)floor((rank-kp*npx*npy)/npx);
1928  ip = rank - kp*npx*npy - jp*npx;
1929  Vnm_print(0, "NOsh_setupMGPARA: Hello world from PE (%d, %d, %d)\n",
1930  ip, jp, kp);
1931 
1932  /* Calculate effective overlap fractions for uneven processor distributions */
1933  if (npx == 1) xofrac = 0.0;
1934  else xofrac = ofrac;
1935  if (npy == 1) yofrac = 0.0;
1936  else yofrac = ofrac;
1937  if (npz == 1) zofrac = 0.0;
1938  else zofrac = ofrac;
1939 
1940  /* Calculate the global grid size and spacing */
1941  xDisj = (int)VFLOOR(mgparm->dime[0]/(1 + 2*xofrac) + 0.5);
1942  xeffGlob = npx*xDisj;
1943  hx = mgparm->fglen[0]/(double)(xeffGlob-1);
1944  yDisj = (int)VFLOOR(mgparm->dime[1]/(1 + 2*yofrac) + 0.5);
1945  yeffGlob = npy*yDisj;
1946  hy = mgparm->fglen[1]/(double)(yeffGlob-1);
1947  zDisj = (int)VFLOOR(mgparm->dime[2]/(1 + 2*zofrac) + 0.5);
1948  zeffGlob = npz*zDisj;
1949  hzed = mgparm->fglen[2]/(double)(zeffGlob-1);
1950  Vnm_print(0, "NOsh_setupMGPARA: Global Grid size = (%d, %d, %d)\n",
1951  xeffGlob, yeffGlob, zeffGlob);
1952  Vnm_print(0, "NOsh_setupMGPARA: Global Grid Spacing = (%.3f, %.3f, %.3f)\n",
1953  hx, hy, hzed);
1954  Vnm_print(0, "NOsh_setupMGPARA: Processor Grid Size = (%d, %d, %d)\n",
1955  xDisj, yDisj, zDisj);
1956 
1957  /* Calculate the maximum and minimum processor grid points */
1958  xigminDisj = ip*xDisj;
1959  xigmaxDisj = xigminDisj + xDisj - 1;
1960  yigminDisj = jp*yDisj;
1961  yigmaxDisj = yigminDisj + yDisj - 1;
1962  zigminDisj = kp*zDisj;
1963  zigmaxDisj = zigminDisj + zDisj - 1;
1964  Vnm_print(0, "NOsh_setupMGPARA: Min Grid Points for this proc. (%d, %d, %d)\n",
1965  xigminDisj, yigminDisj, zigminDisj);
1966  Vnm_print(0, "NOsh_setupMGPARA: Max Grid Points for this proc. (%d, %d, %d)\n",
1967  xigmaxDisj, yigmaxDisj, zigmaxDisj);
1968 
1969 
1970  /* Calculate the disjoint partition length and center displacement */
1971  xminDisj = VMAX2(hx*(xigminDisj-0.5), 0.0);
1972  xmaxDisj = VMIN2(hx*(xigmaxDisj+0.5), mgparm->fglen[0]);
1973  xlenDisj = xmaxDisj - xminDisj;
1974  yminDisj = VMAX2(hy*(yigminDisj-0.5), 0.0);
1975  ymaxDisj = VMIN2(hy*(yigmaxDisj+0.5), mgparm->fglen[1]);
1976  ylenDisj = ymaxDisj - yminDisj;
1977  zminDisj = VMAX2(hzed*(zigminDisj-0.5), 0.0);
1978  zmaxDisj = VMIN2(hzed*(zigmaxDisj+0.5), mgparm->fglen[2]);
1979  zlenDisj = zmaxDisj - zminDisj;
1980 
1981  xcent = 0.5*mgparm->fglen[0];
1982  ycent = 0.5*mgparm->fglen[1];
1983  zcent = 0.5*mgparm->fglen[2];
1984 
1985  xcentDisj = xminDisj + 0.5*xlenDisj - xcent;
1986  ycentDisj = yminDisj + 0.5*ylenDisj - ycent;
1987  zcentDisj = zminDisj + 0.5*zlenDisj - zcent;
1988  if (VABS(xcentDisj) < VSMALL) xcentDisj = 0.0;
1989  if (VABS(ycentDisj) < VSMALL) ycentDisj = 0.0;
1990  if (VABS(zcentDisj) < VSMALL) zcentDisj = 0.0;
1991 
1992  Vnm_print(0, "NOsh_setupMGPARA: Disj part length = (%g, %g, %g)\n",
1993  xlenDisj, ylenDisj, zlenDisj);
1994  Vnm_print(0, "NOsh_setupMGPARA: Disj part center displacement = (%g, %g, %g)\n",
1995  xcentDisj, ycentDisj, zcentDisj);
1996 
1997  /* Calculate the overlapping partition length and center displacement */
1998  xOlapReg = 0;
1999  yOlapReg = 0;
2000  zOlapReg = 0;
2001  if (npx != 1) xOlapReg = (int)VFLOOR(xofrac*mgparm->fglen[0]/npx/hx + 0.5) + 1;
2002  if (npy != 1) yOlapReg = (int)VFLOOR(yofrac*mgparm->fglen[1]/npy/hy + 0.5) + 1;
2003  if (npz != 1) zOlapReg = (int)VFLOOR(zofrac*mgparm->fglen[2]/npz/hzed + 0.5) + 1;
2004 
2005  Vnm_print(0, "NOsh_setupMGPARA: No. of Grid Points in Overlap (%d, %d, %d)\n",
2006  xOlapReg, yOlapReg, zOlapReg);
2007 
2008  if (ip == 0) xigminOlap = 0;
2009  else if (ip == (npx - 1)) xigminOlap = xeffGlob - mgparm->dime[0];
2010  else xigminOlap = xigminDisj - xOlapReg;
2011  xigmaxOlap = xigminOlap + mgparm->dime[0] - 1;
2012 
2013  if (jp == 0) yigminOlap = 0;
2014  else if (jp == (npy - 1)) yigminOlap = yeffGlob - mgparm->dime[1];
2015  else yigminOlap = yigminDisj - yOlapReg;
2016  yigmaxOlap = yigminOlap + mgparm->dime[1] - 1;
2017 
2018  if (kp == 0) zigminOlap = 0;
2019  else if (kp == (npz - 1)) zigminOlap = zeffGlob - mgparm->dime[2];
2020  else zigminOlap = zigminDisj - zOlapReg;
2021  zigmaxOlap = zigminOlap + mgparm->dime[2] - 1;
2022 
2023  Vnm_print(0, "NOsh_setupMGPARA: Min Grid Points with Overlap (%d, %d, %d)\n",
2024  xigminOlap, yigminOlap, zigminOlap);
2025  Vnm_print(0, "NOsh_setupMGPARA: Max Grid Points with Overlap (%d, %d, %d)\n",
2026  xigmaxOlap, yigmaxOlap, zigmaxOlap);
2027 
2028  xminOlap = hx * xigminOlap;
2029  xmaxOlap = hx * xigmaxOlap;
2030  yminOlap = hy * yigminOlap;
2031  ymaxOlap = hy * yigmaxOlap;
2032  zminOlap = hzed * zigminOlap;
2033  zmaxOlap = hzed * zigmaxOlap;
2034 
2035  xlenOlap = xmaxOlap - xminOlap;
2036  ylenOlap = ymaxOlap - yminOlap;
2037  zlenOlap = zmaxOlap - zminOlap;
2038 
2039  xcentOlap = (xminOlap + 0.5*xlenOlap) - xcent;
2040  ycentOlap = (yminOlap + 0.5*ylenOlap) - ycent;
2041  zcentOlap = (zminOlap + 0.5*zlenOlap) - zcent;
2042  if (VABS(xcentOlap) < VSMALL) xcentOlap = 0.0;
2043  if (VABS(ycentOlap) < VSMALL) ycentOlap = 0.0;
2044  if (VABS(zcentOlap) < VSMALL) zcentOlap = 0.0;
2045 
2046  Vnm_print(0, "NOsh_setupMGPARA: Olap part length = (%g, %g, %g)\n",
2047  xlenOlap, ylenOlap, zlenOlap);
2048  Vnm_print(0, "NOsh_setupMGPARA: Olap part center displacement = (%g, %g, %g)\n",
2049  xcentOlap, ycentOlap, zcentOlap);
2050 
2051 
2052  /* Calculate the boundary flags:
2053  Flags are set to 1 when another processor is present along the boundary
2054  Flags are otherwise set to 0. */
2055 
2056  if (ip == 0) mgparm->partDisjOwnSide[VAPBS_LEFT] = 0;
2057  else mgparm->partDisjOwnSide[VAPBS_LEFT] = 1;
2058  if (ip == (npx-1)) mgparm->partDisjOwnSide[VAPBS_RIGHT] = 0;
2059  else mgparm->partDisjOwnSide[VAPBS_RIGHT] = 1;
2060  if (jp == 0) mgparm->partDisjOwnSide[VAPBS_BACK] = 0;
2061  else mgparm->partDisjOwnSide[VAPBS_BACK] = 1;
2062  if (jp == (npy-1)) mgparm->partDisjOwnSide[VAPBS_FRONT] = 0;
2063  else mgparm->partDisjOwnSide[VAPBS_FRONT] = 1;
2064  if (kp == 0) mgparm->partDisjOwnSide[VAPBS_DOWN] = 0;
2065  else mgparm->partDisjOwnSide[VAPBS_DOWN] = 1;
2066  if (kp == (npz-1)) mgparm->partDisjOwnSide[VAPBS_UP] = 0;
2067  else mgparm->partDisjOwnSide[VAPBS_UP] = 1;
2068 
2069  Vnm_print(0, "NOsh_setupMGPARA: partDisjOwnSide[LEFT] = %d\n",
2070  mgparm->partDisjOwnSide[VAPBS_LEFT]);
2071  Vnm_print(0, "NOsh_setupMGPARA: partDisjOwnSide[RIGHT] = %d\n",
2072  mgparm->partDisjOwnSide[VAPBS_RIGHT]);
2073  Vnm_print(0, "NOsh_setupMGPARA: partDisjOwnSide[FRONT] = %d\n",
2074  mgparm->partDisjOwnSide[VAPBS_FRONT]);
2075  Vnm_print(0, "NOsh_setupMGPARA: partDisjOwnSide[BACK] = %d\n",
2076  mgparm->partDisjOwnSide[VAPBS_BACK]);
2077  Vnm_print(0, "NOsh_setupMGPARA: partDisjOwnSide[UP] = %d\n",
2078  mgparm->partDisjOwnSide[VAPBS_UP]);
2079  Vnm_print(0, "NOsh_setupMGPARA: partDisjOwnSide[DOWN] = %d\n",
2080  mgparm->partDisjOwnSide[VAPBS_DOWN]);
2081 
2082  /* Set the mesh parameters */
2083  mgparm->fglen[0] = xlenOlap;
2084  mgparm->fglen[1] = ylenOlap;
2085  mgparm->fglen[2] = zlenOlap;
2086  mgparm->partDisjLength[0] = xlenDisj;
2087  mgparm->partDisjLength[1] = ylenDisj;
2088  mgparm->partDisjLength[2] = zlenDisj;
2089  mgparm->partDisjCenter[0] = mgparm->fcenter[0] + xcentDisj;
2090  mgparm->partDisjCenter[1] = mgparm->fcenter[1] + ycentDisj;
2091  mgparm->partDisjCenter[2] = mgparm->fcenter[2] + zcentDisj;
2092  mgparm->fcenter[0] += xcentOlap;
2093  mgparm->fcenter[1] += ycentOlap;
2094  mgparm->fcenter[2] += zcentOlap;
2095 
2096  Vnm_print(0, "NOsh_setupCalcMGPARA (%s, %d): Set up *relative* partition \
2097 centers...\n", __FILE__, __LINE__);
2098  Vnm_print(0, "NOsh_setupCalcMGPARA (%s, %d): Absolute centers will be set \
2099 in NOsh_setupMGAUTO\n", __FILE__, __LINE__);
2100  Vnm_print(0, "NOsh_setupCalcMGPARA (%s, %d): partDisjCenter = %g %g %g\n",
2101  __FILE__, __LINE__,
2102  mgparm->partDisjCenter[0],
2103  mgparm->partDisjCenter[1],
2104  mgparm->partDisjCenter[2]);
2105  Vnm_print(0, "NOsh_setupCalcMGPARA (%s, %d): ccenter = %g %g %g\n",
2106  __FILE__, __LINE__,
2107  mgparm->ccenter[0],
2108  mgparm->ccenter[1],
2109  mgparm->ccenter[2]);
2110  Vnm_print(0, "NOsh_setupCalcMGPARA (%s, %d): fcenter = %g %g %g\n",
2111  __FILE__, __LINE__,
2112  mgparm->fcenter[0],
2113  mgparm->fcenter[1],
2114  mgparm->fcenter[2]);
2115 
2116 
2117  /* Setup the automatic focusing calculations associated with this processor */
2118  return NOsh_setupCalcMGAUTO(thee, elec);
2119 
2120 }
2121 
2122 VPUBLIC int NOsh_parseFEM(
2123  NOsh *thee,
2124  Vio *sock,
2125  NOsh_calc *elec
2126  ) {
2127 
2128  char tok[VMAX_BUFSIZE];
2129  FEMparm *feparm = VNULL;
2130  PBEparm *pbeparm = VNULL;
2131  int rc;
2132  Vrc_Codes vrc;
2133 
2134  /* Check the arguments */
2135  if (thee == VNULL) {
2136  Vnm_print(2, "NOsh_parseFEM: Got NULL thee!\n");
2137  return 0;
2138  }
2139  if (sock == VNULL) {
2140  Vnm_print(2, "NOsh_parseFEM: Got pointer to NULL socket!\n");
2141  return 0;
2142  }
2143  if (elec == VNULL) {
2144  Vnm_print(2, "NOsh_parseFEM: Got pointer to NULL elec object!\n");
2145  return 0;
2146  }
2147  feparm = elec->femparm;
2148  if (feparm == VNULL) {
2149  Vnm_print(2, "NOsh_parseFEM: Got pointer to NULL feparm object!\n");
2150  return 0;
2151  }
2152  pbeparm = elec->pbeparm;
2153  if (feparm == VNULL) {
2154  Vnm_print(2, "NOsh_parseFEM: Got pointer to NULL pbeparm object!\n");
2155  return 0;
2156  }
2157 
2158  Vnm_print(0, "NOsh_parseFEM: Parsing parameters for FEM calculation\n");
2159 
2160  /* Start snarfing tokens from the input stream */
2161  rc = 1;
2162  while (Vio_scanf(sock, "%s", tok) == 1) {
2163 
2164  Vnm_print(0, "NOsh_parseFEM: Parsing %s...\n", tok);
2165 
2166  /* See if it's an END token */
2167  if (Vstring_strcasecmp(tok, "end") == 0) {
2168  feparm->parsed = 1;
2169  pbeparm->parsed = 1;
2170  rc = 1;
2171  break;
2172  }
2173 
2174  /* Pass the token through a series of parsers */
2175  rc = PBEparm_parseToken(pbeparm, tok, sock);
2176  if (rc == -1) {
2177  Vnm_print(0, "NOsh_parseFEM: parsePBE error!\n");
2178  break;
2179  } else if (rc == 0) {
2180  /* Pass the token to the generic MG parser */
2181  vrc = FEMparm_parseToken(feparm, tok, sock);
2182  if (vrc == VRC_FAILURE) {
2183  Vnm_print(0, "NOsh_parseFEM: parseMG error!\n");
2184  break;
2185  } else if (vrc == VRC_WARNING) {
2186  /* We ran out of parsers! */
2187  Vnm_print(2, "NOsh: Unrecognized keyword: %s\n", tok);
2188  break;
2189  }
2190  }
2191  }
2192 
2193  /* Handle various errors arising in the token-snarfing loop -- these all
2194  * just result in simple returns right now */
2195  if (rc == -1) return 0;
2196  if (rc == 0) return 0;
2197 
2198  /* Check the status of the parameter objects */
2199  if ((!FEMparm_check(feparm)) || (!PBEparm_check(pbeparm))) {
2200  Vnm_print(2, "NOsh: FEM parameters not set correctly!\n");
2201  return 0;
2202  }
2203 
2204  return 1;
2205 
2206 }
2207 
2208 VPRIVATE int NOsh_setupCalcFEMANUAL(
2209  NOsh *thee,
2210  NOsh_calc *elec
2211  ) {
2212 
2213  FEMparm *feparm = VNULL;
2214  PBEparm *pbeparm = VNULL;
2215  NOsh_calc *calc = VNULL;
2216 
2217  VASSERT(thee != VNULL);
2218  VASSERT(elec != VNULL);
2219  feparm = elec->femparm;
2220  VASSERT(feparm != VNULL);
2221  pbeparm = elec->pbeparm;
2222  VASSERT(pbeparm);
2223 
2224  /* Check to see if he have any room left for this type of
2225  * calculation, if so: set the calculation type, update the number
2226  * of calculations of this type, and parse the rest of the section
2227  */
2228  if (thee->ncalc >= NOSH_MAXCALC) {
2229  Vnm_print(2, "NOsh: Too many calculations in this run!\n");
2230  Vnm_print(2, "NOsh: Current max is %d; ignoring this calculation\n",
2231  NOSH_MAXCALC);
2232  return 0;
2233  }
2234  thee->calc[thee->ncalc] = NOsh_calc_ctor(NCT_FEM);
2235  calc = thee->calc[thee->ncalc];
2236  (thee->ncalc)++;
2237 
2238  /* Copy over contents of ELEC */
2239  NOsh_calc_copy(calc, elec);
2240 
2241 
2242  return 1;
2243 }
2244 
2245 VPUBLIC int NOsh_parseAPOL(
2246  NOsh *thee,
2247  Vio *sock,
2248  NOsh_calc *elec
2249  ) {
2250 
2251  char tok[VMAX_BUFSIZE];
2252  APOLparm *apolparm = VNULL;
2253  int rc;
2254 
2255  /* Check the arguments */
2256  if (thee == VNULL) {
2257  Vnm_print(2, "NOsh_parseAPOL: Got NULL thee!\n");
2258  return 0;
2259  }
2260  if (sock == VNULL) {
2261  Vnm_print(2, "NOsh_parseAPOL: Got pointer to NULL socket!\n");
2262  return 0;
2263  }
2264  if (elec == VNULL) {
2265  Vnm_print(2, "NOsh_parseAPOL: Got pointer to NULL elec object!\n");
2266  return 0;
2267  }
2268  apolparm = elec->apolparm;
2269  if (apolparm == VNULL) {
2270  Vnm_print(2, "NOsh_parseAPOL: Got pointer to NULL feparm object!\n");
2271  return 0;
2272  }
2273 
2274  Vnm_print(0, "NOsh_parseAPOL: Parsing parameters for APOL calculation\n");
2275 
2276  /* Start snarfing tokens from the input stream */
2277  rc = 1;
2278  while (Vio_scanf(sock, "%s", tok) == 1) {
2279 
2280  Vnm_print(0, "NOsh_parseAPOL: Parsing %s...\n", tok);
2281  /* See if it's an END token */
2282  if (Vstring_strcasecmp(tok, "end") == 0) {
2283  apolparm->parsed = 1;
2284  rc = 1;
2285  break;
2286  }
2287 
2288  /* Pass the token through a series of parsers */
2289  /* Pass the token to the generic non-polar parser */
2290  rc = APOLparm_parseToken(apolparm, tok, sock);
2291  if (rc == -1) {
2292  Vnm_print(0, "NOsh_parseFEM: parseMG error!\n");
2293  break;
2294  } else if (rc == 0) {
2295  /* We ran out of parsers! */
2296  Vnm_print(2, "NOsh: Unrecognized keyword: %s\n", tok);
2297  break;
2298  }
2299 
2300  }
2301 
2302  /* Handle various errors arising in the token-snarfing loop -- these all
2303  * just result in simple returns right now */
2304  if (rc == -1) return 0;
2305  if (rc == 0) return 0;
2306 
2307  /* Check the status of the parameter objects */
2308  if (!APOLparm_check(apolparm)) {
2309  Vnm_print(2, "NOsh: APOL parameters not set correctly!\n");
2310  return 0;
2311  }
2312 
2313  return 1;
2314 
2315 }
2316 
2317 VPRIVATE int NOsh_setupCalcAPOL(
2318  NOsh *thee,
2319  NOsh_calc *apol
2320  ) {
2321 
2322  NOsh_calc *calc = VNULL;
2323 
2324  VASSERT(thee != VNULL);
2325  VASSERT(apol != VNULL);
2326 
2327  /* Check to see if he have any room left for this type of
2328  * calculation, if so: set the calculation type, update the number
2329  * of calculations of this type, and parse the rest of the section
2330  */
2331  if (thee->ncalc >= NOSH_MAXCALC) {
2332  Vnm_print(2, "NOsh: Too many calculations in this run!\n");
2333  Vnm_print(2, "NOsh: Current max is %d; ignoring this calculation\n",
2334  NOSH_MAXCALC);
2335  return 0;
2336  }
2337  thee->calc[thee->ncalc] = NOsh_calc_ctor(NCT_APOL);
2338  calc = thee->calc[thee->ncalc];
2339  (thee->ncalc)++;
2340 
2341  /* Copy over contents of APOL */
2342  NOsh_calc_copy(calc, apol);
2343 
2344  return 1;
2345 }
VPUBLIC Vrc_Codes MGparm_parseToken(MGparm *thee, char tok[VMAX_BUFSIZE], Vio *sock)
Parse an MG keyword from an input file.
Definition: mgparm.c:919
VPUBLIC FEMparm * FEMparm_ctor(FEMparm_CalcType type)
Construct FEMparm.
Definition: femparm.c:65
Definition: vhal.h:316
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
Vdata_Format meshfmt[NOSH_MAXMOL]
Definition: nosh.h:246
#define VFLOOR(value)
Wrapped floor to fix floating point issues in the Intel compiler.
Definition: vhal.h:554
VPUBLIC int NOsh_apol2calc(NOsh *thee, int icalc)
Return the name of an apol statement.
Definition: nosh.c:217
VPUBLIC int NOsh_printNarg(NOsh *thee, int iprint)
Return number of arguments to PRINT statement (.
Definition: nosh.c:205
enum eVdata_Format Vdata_Format
Declaration of the Vdata_Format type as the Vdata_Format enum.
Definition: vhal.h:324
int apol2calc[NOSH_MAXCALC]
Definition: nosh.h:217
VPUBLIC char * NOsh_getPotpath(NOsh *thee, int imol)
Returns path to specified potential map.
Definition: nosh.c:160
Definition: nosh.h:116
int gotparm
Definition: nosh.h:224
VPUBLIC Vrc_Codes APOLparm_parseToken(APOLparm *thee, char tok[VMAX_BUFSIZE], Vio *sock)
Parse an MG keyword from an input file.
Definition: apolparm.c:577
#define NOSH_MAXMOL
Maximum number of molecules in a run.
Definition: nosh.h:79
VPUBLIC int NOsh_ctor2(NOsh *thee, int rank, int size)
FORTRAN stub to construct NOsh.
Definition: nosh.c:254
Vdata_Format dielfmt[NOSH_MAXMOL]
Definition: nosh.h:234
#define NOSH_MAXPRINT
Maximum number of PRINT statements in a run.
Definition: nosh.h:87
MGparm_CentMeth cmeth
Definition: mgparm.h:137
#define VAPBS_DOWN
Face definition for a volume.
Definition: vhal.h:445
char potpath[NOSH_MAXMOL][VMAX_ARGLEN]
Definition: nosh.h:239
int setasync
Definition: mgparm.h:187
VPUBLIC char * NOsh_getDielXpath(NOsh *thee, int imol)
Returns path to specified x-shifted dielectric map.
Definition: nosh.c:140
FEMparm_CalcType type
Definition: femparm.h:138
int setsize
Definition: mgparm.h:183
NOsh_PrintType printwhat[NOSH_MAXPRINT]
Definition: nosh.h:248
enum eNOsh_PrintType NOsh_PrintType
Declare NOsh_PrintType type.
Definition: nosh.h:157
int nprint
Definition: nosh.h:247
VPUBLIC void MGparm_dtor(MGparm **thee)
Object destructor.
Definition: mgparm.c:175
VPUBLIC void NOsh_dtor(NOsh **thee)
Object destructor.
Definition: nosh.c:289
Definition: nosh.h:99
char elecname[NOSH_MAXCALC][VMAX_ARGLEN]
Definition: nosh.h:255
VPUBLIC void FEMparm_copy(FEMparm *thee, FEMparm *source)
Copy target object into thee.
Definition: femparm.c:100
VPUBLIC PBEparm * PBEparm_ctor()
Construct PBEparm object.
Definition: pbeparm.c:104
NOsh_calc * calc[NOSH_MAXCALC]
Definition: nosh.h:185
Definition: nosh.h:98
double cglen[3]
Definition: mgparm.h:152
int proc_size
Definition: mgparm.h:182
Contains declarations for class NOsh.
int setgrid
Definition: mgparm.h:134
VPRIVATE char * MCcommChars
Comment characters for socket reads.
Definition: vparam.c:71
VPUBLIC Vrc_Codes FEMparm_parseToken(FEMparm *thee, char tok[VMAX_BUFSIZE], Vio *sock)
Parse an MG keyword from an input file.
Definition: femparm.c:431
#define VAPBS_UP
Face definition for a volume.
Definition: vhal.h:427
double fcenter[3]
Definition: mgparm.h:163
VPUBLIC int FEMparm_check(FEMparm *thee)
Consistency check for parameter values stored in object.
Definition: femparm.c:143
int fcentmol
Definition: mgparm.h:164
VPUBLIC int NOsh_parseInputFile(NOsh *thee, char *filename)
Parse an input file only from a file.
Definition: nosh.c:392
VPUBLIC void NOsh_calc_dtor(NOsh_calc **thee)
Object destructor.
Definition: nosh.c:341
char dielXpath[NOSH_MAXMOL][VMAX_ARGLEN]
Definition: nosh.h:228
Definition: nosh.h:114
double center[3]
Definition: mgparm.h:138
int ncalc
Definition: nosh.h:188
VPUBLIC void FEMparm_dtor(FEMparm **thee)
Object destructor.
Definition: femparm.c:133
NOsh_CalcType calctype
Definition: nosh.h:169
VPUBLIC Vrc_Codes APOLparm_check(APOLparm *thee)
Consistency check for parameter values stored in object.
Definition: apolparm.c:179
double fglen[3]
Definition: mgparm.h:154
#define NOSH_MAXPOP
Maximum number of operations in a PRINT statement.
Definition: nosh.h:91
double glen[3]
Definition: mgparm.h:135
VPUBLIC NOsh_PrintType NOsh_printWhat(NOsh *thee, int iprint)
Return an integer ID of the observable to print (.
Definition: nosh.c:199
MGparm_CentMeth fcmeth
Definition: mgparm.h:162
Definition: vhal.h:315
Definition: pbeparm.h:98
APOLparm * apolparm
Definition: nosh.h:168
VPUBLIC char * NOsh_getDielZpath(NOsh *thee, int imol)
Returns path to specified z-shifted dielectric map.
Definition: nosh.c:150
int nkappa
Definition: nosh.h:235
VPUBLIC MGparm * MGparm_ctor(MGparm_CalcType type)
Construct MGparm object.
Definition: mgparm.c:114
Vdata_Format potfmt[NOSH_MAXMOL]
Definition: nosh.h:240
VPUBLIC NOsh_calc * NOsh_getCalc(NOsh *thee, int icalc)
Returns specified calculation object.
Definition: nosh.c:170
NOsh_calc * elec[NOSH_MAXCALC]
Definition: nosh.h:190
PBEparm * pbeparm
Definition: nosh.h:167
int parsed
Definition: mgparm.h:117
VPUBLIC int PBEparm_parseToken(PBEparm *thee, char tok[VMAX_BUFSIZE], Vio *sock)
Parse a keyword from an input file.
Definition: pbeparm.c:1206
MGparm_CalcType type
Definition: mgparm.h:116
int npot
Definition: nosh.h:238
int proc_rank
Definition: nosh.h:203
Vdata_Format kappafmt[NOSH_MAXMOL]
Definition: nosh.h:237
VPUBLIC void MGparm_copy(MGparm *thee, MGparm *parm)
Copy MGparm object into thee.
Definition: mgparm.c:341
Definition: nosh.h:115
#define VEMBED(rctag)
Allows embedding of RCS ID tags in object files.
Definition: vhal.h:563
int nelec
Definition: nosh.h:193
int setrank
Definition: mgparm.h:181
int ncharge
Definition: nosh.h:241
int setglen
Definition: mgparm.h:136
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
Definition: vhal.h:312
VPUBLIC int Vstring_strcasecmp(const char *s1, const char *s2)
Case-insensitive string comparison (BSD standard)
Definition: vstring.c:66
double center[3]
Definition: valist.h:81
int async
Definition: mgparm.h:186
int ndiel
Definition: nosh.h:227
VPUBLIC int Vstring_isdigit(const char *tok)
A modified sscanf that examines the complete string.
Definition: vstring.c:130
VPUBLIC void PBEparm_copy(PBEparm *thee, PBEparm *parm)
Copy PBEparm object into thee.
Definition: pbeparm.c:283
VPUBLIC int NOsh_printOp(NOsh *thee, int iprint, int iarg)
Return integer ID for specified operation (.
Definition: nosh.c:229
Parameter structure for FEM-specific variables from input files.
Definition: femparm.h:133
double grid[3]
Definition: mgparm.h:133
VPUBLIC void APOLparm_copy(APOLparm *thee, APOLparm *source)
Copy target object into thee.
Definition: apolparm.c:108
VPUBLIC void PBEparm_dtor(PBEparm **thee)
Object destructor.
Definition: pbeparm.c:173
Definition: nosh.h:130
int napol
Definition: nosh.h:199
VPUBLIC int NOsh_getPotfmt(NOsh *thee, int i)
Returns format of specified potential map.
Definition: nosh.c:185
int printcalc[NOSH_MAXPRINT][NOSH_MAXPOP]
Definition: nosh.h:251
VPUBLIC int PBEparm_check(PBEparm *thee)
Consistency check for parameter values stored in object.
Definition: pbeparm.c:183
NOsh_ParmFormat parmfmt
Definition: nosh.h:226
#define VAPBS_BACK
Face definition for a volume.
Definition: vhal.h:439
int pdime[3]
Definition: mgparm.h:178
NOsh_MolFormat molfmt[NOSH_MAXMOL]
Definition: nosh.h:221
char chargepath[NOSH_MAXMOL][VMAX_ARGLEN]
Definition: nosh.h:242
Valist * alist[NOSH_MAXMOL]
Definition: nosh.h:222
VPUBLIC Vrc_Codes MGparm_check(MGparm *thee)
Consistency check for parameter values stored in object.
Definition: mgparm.c:185
Parameter structure for PBE variables from input files.
Definition: pbeparm.h:117
int proc_size
Definition: nosh.h:204
Definition: nosh.h:131
enum eNOsh_ParmFormat NOsh_ParmFormat
Declare NOsh_ParmFormat type.
Definition: nosh.h:138
int parsed
Definition: femparm.h:135
#define VAPBS_FRONT
Face definition for a volume.
Definition: vhal.h:421
PBEparm_calcForce calcforce
Definition: pbeparm.h:167
Vbcfl bcfl
Definition: pbeparm.h:136
int printnarg[NOSH_MAXPRINT]
Definition: nosh.h:250
enum eNOsh_CalcType NOsh_CalcType
Declare NOsh_CalcType type.
Definition: nosh.h:123
double partDisjLength[3]
Definition: mgparm.h:173
NOsh_calc * apol[NOSH_MAXCALC]
Definition: nosh.h:196
char dielZpath[NOSH_MAXMOL][VMAX_ARGLEN]
Definition: nosh.h:232
Parameter structure for MG-specific variables from input files.
Definition: mgparm.h:114
Vdata_Format chargefmt[NOSH_MAXMOL]
Definition: nosh.h:243
int nmol
Definition: nosh.h:219
int bogus
Definition: nosh.h:205
VPUBLIC char * NOsh_getMolpath(NOsh *thee, int imol)
Returns path to specified molecule.
Definition: nosh.c:135
VPUBLIC void NOsh_dtor2(NOsh *thee)
FORTRAN stub for object destructor.
Definition: nosh.c:297
VPUBLIC NOsh * NOsh_ctor(int rank, int size)
Construct NOsh.
Definition: nosh.c:243
VPUBLIC APOLparm * APOLparm_ctor()
Construct APOLparm.
Definition: apolparm.c:65
double ofrac
Definition: mgparm.h:184
VPUBLIC void APOLparm_dtor(APOLparm **thee)
Object destructor.
Definition: apolparm.c:167
int dime[3]
Definition: mgparm.h:120
Container class for list of atom objects.
Definition: valist.h:78
MGparm_CentMeth ccmeth
Definition: mgparm.h:156
VPUBLIC int NOsh_getChargefmt(NOsh *thee, int i)
Returns format of specified charge map.
Definition: nosh.c:190
VPUBLIC char * NOsh_getKappapath(NOsh *thee, int imol)
Returns path to specified kappa map.
Definition: nosh.c:155
VPUBLIC int NOsh_printCalc(NOsh *thee, int iprint, int iarg)
Return calculation ID for specified PRINT statement (.
Definition: nosh.c:236
Class for parsing fixed format input files.
Definition: nosh.h:183
char meshpath[NOSH_MAXMOL][VMAX_ARGLEN]
Definition: nosh.h:245
Calculation class for use when parsing fixed format input files.
Definition: nosh.h:164
int elec2calc[NOSH_MAXCALC]
Definition: nosh.h:209
VPUBLIC char * NOsh_getDielYpath(NOsh *thee, int imol)
Returns path to specified y-shifted dielectric map.
Definition: nosh.c:145
int proc_rank
Definition: mgparm.h:180
VPUBLIC char * NOsh_elecname(NOsh *thee, int ielec)
Return an integer mapping of an ELEC statement to a calculation ID (.
Definition: nosh.c:223
#define NOSH_MAXCALC
Maximum number of calculations in a run.
Definition: nosh.h:83
int partDisjOwnSide[6]
Definition: mgparm.h:175
enum eNOsh_MolFormat NOsh_MolFormat
Declare NOsh_MolFormat type.
Definition: nosh.h:107
VPUBLIC int NOsh_calc_copy(NOsh_calc *thee, NOsh_calc *source)
Copy NOsh_calc object into thee.
Definition: nosh.c:371
VPUBLIC NOsh_calc * NOsh_calc_ctor(NOsh_CalcType calctype)
Construct NOsh_calc.
Definition: nosh.c:309
int parsed
Definition: nosh.h:254
int centmol
Definition: mgparm.h:146
int numwrite
Definition: pbeparm.h:185
int parsed
Definition: apolparm.h:131
double partDisjCenter[3]
Definition: mgparm.h:171
char parmpath[VMAX_ARGLEN]
Definition: nosh.h:225
int ispara
Definition: nosh.h:202
int ccentmol
Definition: mgparm.h:158
int printop[NOSH_MAXPRINT][NOSH_MAXPOP]
Definition: nosh.h:252
char molpath[NOSH_MAXMOL][VMAX_ARGLEN]
Definition: nosh.h:220
Definition: nosh.h:100
VPUBLIC int NOsh_getKappafmt(NOsh *thee, int i)
Returns format of specified kappa map.
Definition: nosh.c:180
VPRIVATE char * MCwhiteChars
Whitespace characters for socket reads.
Definition: vparam.c:65
int parsed
Definition: pbeparm.h:201
VPUBLIC int NOsh_elec2calc(NOsh *thee, int icalc)
Return the name of an elec statement.
Definition: nosh.c:211
FEMparm * femparm
Definition: nosh.h:166
char apolname[NOSH_MAXCALC][VMAX_ARGLEN]
Definition: nosh.h:257
VPUBLIC char * NOsh_getChargepath(NOsh *thee, int imol)
Returns path to specified charge distribution map.
Definition: nosh.c:165
Parameter structure for APOL-specific variables from input files.
Definition: apolparm.h:129
double ccenter[3]
Definition: mgparm.h:157
VPUBLIC int NOsh_getDielfmt(NOsh *thee, int i)
Returns format of specified dielectric map.
Definition: nosh.c:175
int nmesh
Definition: nosh.h:244
#define VREDFRAC
Maximum reduction of grid spacing during a focusing calculation.
Definition: vhal.h:393
#define VAPBS_LEFT
Face definition for a volume.
Definition: vhal.h:433
#define VAPBS_RIGHT
Face definition for a volume.
Definition: vhal.h:409
char dielYpath[NOSH_MAXMOL][VMAX_ARGLEN]
Definition: nosh.h:230
char kappapath[NOSH_MAXMOL][VMAX_ARGLEN]
Definition: nosh.h:236