1 /**
2 * @file nosh.c
3 * @ingroup NOsh
4 * @author Nathan Baker
5 * @brief Class NOsh methods
6 * @version $Id$
7 * @attention
8 * @verbatim
9 *
10 * APBS -- Adaptive Poisson-Boltzmann Solver
11 *
12 * Nathan A. Baker (nathan.baker@pnnl.gov)
13 * Pacific Northwest National Laboratory
14 *
15 * Additional contributing authors listed in the code documentation.
16 *
17 * Copyright (c) 2010-2014 Battelle Memorial Institute. Developed at the
18 * Pacific Northwest National Laboratory, operated by Battelle Memorial
19 * Institute, Pacific Northwest Division for the U.S. Department of Energy.
20 *
21 * Portions Copyright (c) 2002-2010, Washington University in St. Louis.
22 * Portions Copyright (c) 2002-2010, Nathan A. Baker.
23 * Portions Copyright (c) 1999-2002, The Regents of the University of
24 * California.
25 * Portions Copyright (c) 1995, Michael Holst.
26 * All rights reserved.
27 *
28 * Redistribution and use in source and binary forms, with or without
29 * modification, are permitted provided that the following conditions are met:
30 *
31 * Redistributions of source code must retain the above copyright notice, this
32 * list of conditions and the following disclaimer.
33 *
34 * Redistributions in binary form must reproduce the above copyright notice,
35 * this list of conditions and the following disclaimer in the documentation
36 * and/or other materials provided with the distribution.
37 *
38 * Neither the name of the developer nor the names of its contributors may be
39 * used to endorse or promote products derived from this software without
40 * specific prior written permission.
41 *
42 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
43 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
44 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
45 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
46 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
47 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
48 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
49 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
50 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
51 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
52 * THE POSSIBILITY OF SUCH DAMAGE.
53 *
54 * @endverbatim
55 */
56
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_parseBEM(
93 NOsh *thee,
94 Vio *sock,
95 NOsh_calc *elec
96 );
97
98 VEXTERNC int NOsh_parseGEOFLOW(
99 NOsh *thee,
100 Vio *sock,
101 NOsh_calc *elec
102 );
103
104 VEXTERNC int NOsh_parsePBAM(
105 NOsh *thee,
106 Vio *sock,
107 NOsh_calc *elec
108 );
109
110 VEXTERNC int NOsh_parsePBSAM(
111 NOsh *thee,
112 Vio *sock,
113 NOsh_calc *elec
114 );
115
116 VEXTERNC int NOsh_parseAPOL(
117 NOsh *thee,
118 Vio *sock,
119 NOsh_calc *elec
120 );
121
122 VPRIVATE int NOsh_setupCalcMG(
123 NOsh *thee,
124 NOsh_calc *elec
125 );
126
127
128 VPRIVATE int NOsh_setupCalcMGAUTO(
129 NOsh *thee,
130 NOsh_calc *elec
131 );
132
133 VPRIVATE int NOsh_setupCalcMGMANUAL(
134 NOsh *thee,
135 NOsh_calc *elec
136 );
137
138 VPRIVATE int NOsh_setupCalcMGPARA(
139 NOsh *thee,
140 NOsh_calc *elec
141 );
142
143 VPRIVATE int NOsh_setupCalcFEM(
144 NOsh *thee,
145 NOsh_calc *elec
146 );
147
148 VPRIVATE int NOsh_setupCalcFEMANUAL(
149 NOsh *thee,
150 NOsh_calc *elec
151 );
152
153 VPRIVATE int NOsh_setupCalcBEM(
154 NOsh *thee,
155 NOsh_calc *elec
156 );
157
158 VPRIVATE int NOsh_setupCalcGEOFLOW(
159 NOsh *thee,
160 NOsh_calc *elec
161 );
162
163 VPRIVATE int NOsh_setupCalcPBAM(
164 NOsh *thee,
165 NOsh_calc *elec
166 );
167
168 VPRIVATE int NOsh_setupCalcPBSAM(
169 NOsh *thee,
170 NOsh_calc *elec
171 );
172
173 VPRIVATE int NOsh_setupCalcBEMMANUAL(
174 NOsh *thee,
175 NOsh_calc *elec
176 );
177
178 VPRIVATE int NOsh_setupCalcGEOFLOWMANUAL(
179 NOsh *thee,
180 NOsh_calc *elec
181 );
182
183 VPRIVATE int NOsh_setupCalcPBAMAUTO(
184 NOsh *thee,
185 NOsh_calc *elec
186 );
187
188 VPRIVATE int NOsh_setupCalcPBSAMAUTO(
189 NOsh *thee,
190 NOsh_calc *elec
191 );
192
193 VPRIVATE int NOsh_setupCalcAPOL(
194 NOsh *thee,
195 NOsh_calc *elec
196 );
197
198 #if !defined(VINLINE_NOSH)
199
NOsh_getMolpath(NOsh * thee,int imol)200 VPUBLIC char* NOsh_getMolpath(NOsh *thee, int imol) {
201 VASSERT(thee != VNULL);
202 VASSERT(imol < thee->nmol);
203 return thee->molpath[imol];
204 }
NOsh_getDielXpath(NOsh * thee,int imol)205 VPUBLIC char* NOsh_getDielXpath(NOsh *thee, int imol) {
206 VASSERT(thee != VNULL);
207 VASSERT(imol < thee->nmol);
208 return thee->dielXpath[imol];
209 }
NOsh_getDielYpath(NOsh * thee,int imol)210 VPUBLIC char* NOsh_getDielYpath(NOsh *thee, int imol) {
211 VASSERT(thee != VNULL);
212 VASSERT(imol < thee->nmol);
213 return thee->dielYpath[imol];
214 }
NOsh_getDielZpath(NOsh * thee,int imol)215 VPUBLIC char* NOsh_getDielZpath(NOsh *thee, int imol) {
216 VASSERT(thee != VNULL);
217 VASSERT(imol < thee->nmol);
218 return thee->dielZpath[imol];
219 }
NOsh_getKappapath(NOsh * thee,int imol)220 VPUBLIC char* NOsh_getKappapath(NOsh *thee, int imol) {
221 VASSERT(thee != VNULL);
222 VASSERT(imol < thee->nmol);
223 return thee->kappapath[imol];
224 }
NOsh_getPotpath(NOsh * thee,int imol)225 VPUBLIC char* NOsh_getPotpath(NOsh *thee, int imol) {
226 VASSERT(thee != VNULL);
227 VASSERT(imol < thee->nmol);
228 return thee->potpath[imol];
229 }
NOsh_getChargepath(NOsh * thee,int imol)230 VPUBLIC char* NOsh_getChargepath(NOsh *thee, int imol) {
231 VASSERT(thee != VNULL);
232 VASSERT(imol < thee->nmol);
233 return thee->chargepath[imol];
234 }
NOsh_getCalc(NOsh * thee,int icalc)235 VPUBLIC NOsh_calc* NOsh_getCalc(NOsh *thee, int icalc) {
236 VASSERT(thee != VNULL);
237 VASSERT(icalc < thee->ncalc);
238 return thee->calc[icalc];
239 }
NOsh_getDielfmt(NOsh * thee,int i)240 VPUBLIC int NOsh_getDielfmt(NOsh *thee, int i) {
241 VASSERT(thee != VNULL);
242 VASSERT(i < thee->ndiel);
243 return (thee->dielfmt[i]);
244 }
NOsh_getKappafmt(NOsh * thee,int i)245 VPUBLIC int NOsh_getKappafmt(NOsh *thee, int i) {
246 VASSERT(thee != VNULL);
247 VASSERT(i < thee->nkappa);
248 return (thee->kappafmt[i]);
249 }
NOsh_getPotfmt(NOsh * thee,int i)250 VPUBLIC int NOsh_getPotfmt(NOsh *thee, int i) {
251 VASSERT(thee != VNULL);
252 VASSERT(i < thee->npot);
253 return (thee->potfmt[i]);
254 }
NOsh_getChargefmt(NOsh * thee,int i)255 VPUBLIC int NOsh_getChargefmt(NOsh *thee, int i) {
256 VASSERT(thee != VNULL);
257 VASSERT(i < thee->ncharge);
258 return (thee->chargefmt[i]);
259 }
260
261
262 #endif /* if !defined(VINLINE_NOSH) */
263
NOsh_printWhat(NOsh * thee,int iprint)264 VPUBLIC NOsh_PrintType NOsh_printWhat(NOsh *thee, int iprint) {
265 VASSERT(thee != VNULL);
266 VASSERT(iprint < thee->nprint);
267 return thee->printwhat[iprint];
268 }
269
NOsh_printNarg(NOsh * thee,int iprint)270 VPUBLIC int NOsh_printNarg(NOsh *thee, int iprint) {
271 VASSERT(thee != VNULL);
272 VASSERT(iprint < thee->nprint);
273 return thee->printnarg[iprint];
274 }
275
NOsh_elec2calc(NOsh * thee,int icalc)276 VPUBLIC int NOsh_elec2calc(NOsh *thee, int icalc) {
277 VASSERT(thee != VNULL);
278 VASSERT(icalc < thee->ncalc);
279 return thee->elec2calc[icalc];
280 }
281
NOsh_apol2calc(NOsh * thee,int icalc)282 VPUBLIC int NOsh_apol2calc(NOsh *thee, int icalc) {
283 VASSERT(thee != VNULL);
284 VASSERT(icalc < thee->ncalc);
285 return thee->apol2calc[icalc];
286 }
287
NOsh_elecname(NOsh * thee,int ielec)288 VPUBLIC char* NOsh_elecname(NOsh *thee, int ielec) {
289 VASSERT(thee != VNULL);
290 VASSERT(ielec < thee->nelec + 1);
291 return thee->elecname[ielec];
292 }
293
NOsh_printOp(NOsh * thee,int iprint,int iarg)294 VPUBLIC int NOsh_printOp(NOsh *thee, int iprint, int iarg) {
295 VASSERT(thee != VNULL);
296 VASSERT(iprint < thee->nprint);
297 VASSERT(iarg < thee->printnarg[iprint]);
298 return thee->printop[iprint][iarg];
299 }
300
NOsh_printCalc(NOsh * thee,int iprint,int iarg)301 VPUBLIC int NOsh_printCalc(NOsh *thee, int iprint, int iarg) {
302 VASSERT(thee != VNULL);
303 VASSERT(iprint < thee->nprint);
304 VASSERT(iarg < thee->printnarg[iprint]);
305 return thee->printcalc[iprint][iarg];
306 }
307
NOsh_ctor(int rank,int size)308 VPUBLIC NOsh* NOsh_ctor(int rank, int size) {
309
310 /* Set up the structure */
311 NOsh *thee = VNULL;
312 thee = (NOsh*)Vmem_malloc(VNULL, 1, sizeof(NOsh) );
313 VASSERT( thee != VNULL);
314 VASSERT( NOsh_ctor2(thee, rank, size) );
315
316 return thee;
317 }
318
NOsh_ctor2(NOsh * thee,int rank,int size)319 VPUBLIC int NOsh_ctor2(NOsh *thee, int rank, int size) {
320
321 int i;
322
323 if (thee == VNULL) return 0;
324
325 thee->proc_rank = rank;
326 thee->proc_size = size;
327
328 thee->ispara = 0;
329 thee->parsed = 0;
330
331 thee->nmol = 0;
332 thee->gotparm = 0;
333 thee->ncharge = 0;
334 thee->ndiel = 0;
335 thee->nkappa = 0;
336 thee->npot = 0;
337 thee->nprint = 0;
338
339 for (i=0; i<NOSH_MAXCALC; i++) {
340 thee->calc[i] = VNULL;
341 thee->elec[i] = VNULL;
342 thee->apol[i] = VNULL;
343 }
344 for (i=0; i<NOSH_MAXMOL; i++) {
345 thee->alist[i] = VNULL;
346 }
347 thee->ncalc = 0;
348 thee->nelec = 0;
349 thee->napol = 0;
350
351 return 1;
352 }
353
NOsh_dtor(NOsh ** thee)354 VPUBLIC void NOsh_dtor(NOsh **thee) {
355 if ((*thee) != VNULL) {
356 NOsh_dtor2(*thee);
357 Vmem_free(VNULL, 1, sizeof(NOsh), (void **)thee);
358 (*thee) = VNULL;
359 }
360 }
361
NOsh_dtor2(NOsh * thee)362 VPUBLIC void NOsh_dtor2(NOsh *thee) {
363
364 int i;
365
366 if (thee != VNULL) {
367 for (i=0; i<(thee->ncalc); i++) NOsh_calc_dtor(&(thee->calc[i]));
368 for (i=0; i<(thee->nelec); i++) NOsh_calc_dtor(&(thee->elec[i]));
369 for (i=0; i<(thee->napol); i++) NOsh_calc_dtor(&(thee->apol[i]));
370 }
371
372 }
373
NOsh_calc_ctor(NOsh_CalcType calctype)374 VPUBLIC NOsh_calc* NOsh_calc_ctor(
375 NOsh_CalcType calctype
376 ) {
377 NOsh_calc *thee;
378 thee = (NOsh_calc *)Vmem_malloc(VNULL, 1, sizeof(NOsh_calc));
379 thee->calctype = calctype;
380
381 thee->mgparm = VNULL;
382 thee->femparm = VNULL;
383 thee->apolparm = VNULL;
384 thee->bemparm = VNULL;
385 thee->geoflowparm = VNULL;
386 thee->pbamparm = VNULL;
387 thee->pbsamparm = VNULL;
388
389 switch (calctype) {
390 case NCT_MG:
391 thee->mgparm = MGparm_ctor(MCT_NONE);
392 break;
393 case NCT_FEM:
394 thee->femparm = FEMparm_ctor(FCT_NONE);
395 break;
396 case NCT_APOL:
397 thee->apolparm = APOLparm_ctor();
398 break;
399 case NCT_BEM:
400 thee->bemparm = BEMparm_ctor(BCT_MANUAL);
401 break;
402 case NCT_GEOFLOW:
403 thee->geoflowparm = GEOFLOWparm_ctor(GFCT_AUTO);
404 thee->apolparm = APOLparm_ctor();
405 break;
406 case NCT_PBAM:
407 thee->pbamparm = PBAMparm_ctor(PBAMCT_AUTO);
408 break;
409 case NCT_PBSAM:
410 thee->pbamparm = PBAMparm_ctor(PBAMCT_AUTO);
411 thee->pbsamparm = PBSAMparm_ctor(PBSAMCT_AUTO);
412 break;
413 default:
414 Vnm_print(2, "NOsh_calc_ctor: unknown calculation type (%d)!\n",
415 calctype);
416 VASSERT(0);
417 }
418 thee->pbeparm = PBEparm_ctor();
419
420 return thee;
421 }
422
NOsh_calc_dtor(NOsh_calc ** thee)423 VPUBLIC void NOsh_calc_dtor(
424 NOsh_calc **thee
425 ) {
426
427 NOsh_calc *calc = VNULL;
428 calc = *thee;
429 if (calc == VNULL) return;
430
431 switch (calc->calctype) {
432 case NCT_MG:
433 MGparm_dtor(&(calc->mgparm));
434 break;
435 case NCT_FEM:
436 FEMparm_dtor(&(calc->femparm));
437 break;
438 case NCT_APOL:
439 APOLparm_dtor(&(calc->apolparm));
440 break;
441 case NCT_BEM:
442 BEMparm_dtor(&(calc->bemparm));
443 break;
444 case NCT_GEOFLOW:
445 GEOFLOWparm_dtor(&(calc->geoflowparm));
446 APOLparm_dtor(&(calc->apolparm));
447 break;
448 case NCT_PBAM:
449 PBAMparm_dtor(&(calc->pbamparm));
450 break;
451 case NCT_PBSAM:
452 PBAMparm_dtor(&(calc->pbamparm));
453 PBSAMparm_dtor(&(calc->pbsamparm));
454 break;
455 default:
456 Vnm_print(2, "NOsh_calc_ctor: unknown calculation type (%d)!\n",
457 calc->calctype);
458 VASSERT(0);
459 }
460 PBEparm_dtor(&(calc->pbeparm));
461
462 Vmem_free(VNULL, 1, sizeof(NOsh_calc), (void **)thee);
463 calc = VNULL;
464
465 }
466
NOsh_calc_copy(NOsh_calc * thee,NOsh_calc * source)467 VPUBLIC int NOsh_calc_copy(
468 NOsh_calc *thee,
469 NOsh_calc *source
470 ) {
471
472 VASSERT(thee != VNULL);
473 VASSERT(source != VNULL);
474 VASSERT(thee->calctype == source->calctype);
475 if (source->mgparm != VNULL)
476 MGparm_copy(thee->mgparm, source->mgparm);
477 if (source->femparm != VNULL)
478 FEMparm_copy(thee->femparm, source->femparm);
479 if (source->bemparm != VNULL)
480 BEMparm_copy(thee->bemparm, source->bemparm);
481 if (source->pbeparm != VNULL)
482 PBEparm_copy(thee->pbeparm, source->pbeparm);
483 if (source->apolparm != VNULL)
484 APOLparm_copy(thee->apolparm, source->apolparm);
485 /*I think here is where the the geoflow changes get lost*/
486 if(source->geoflowparm != VNULL)
487 GEOFLOWparm_copy(thee->geoflowparm, source->geoflowparm);
488 if(source->pbamparm != VNULL)
489 PBAMparm_copy(thee->pbamparm, source->pbamparm);
490 if(source->pbsamparm != VNULL)
491 PBSAMparm_copy(thee->pbsamparm, source->pbsamparm);
492
493
494 return 1;
495
496 }
497
NOsh_parseInputFile(NOsh * thee,char * filename)498 VPUBLIC int NOsh_parseInputFile(
499 NOsh *thee,
500 char *filename
501 ) {
502
503 Vio *sock;
504 int rc;
505
506 sock = Vio_ctor("FILE", "ASC", VNULL, filename, "r");
507 rc = NOsh_parseInput(thee, sock);
508 Vio_dtor(&sock);
509
510 return rc;
511 }
512
NOsh_parseInput(NOsh * thee,Vio * sock)513 VPUBLIC int NOsh_parseInput(
514 NOsh *thee,
515 Vio *sock
516 ) {
517
518 char *MCwhiteChars = " =,;\t\r\n";
519 char *MCcommChars = "#%";
520 char tok[VMAX_BUFSIZE];
521
522 if (thee == VNULL) {
523 Vnm_print(2, "NOsh_parseInput: Got NULL thee!\n");
524 return 0;
525 }
526
527 if (sock == VNULL) {
528 Vnm_print(2, "NOsh_parseInput: Got pointer to NULL socket!\n");
529 Vnm_print(2, "NOsh_parseInput: The specified input file was not found!\n");
530 return 0;
531 }
532
533 if (thee->parsed) {
534 Vnm_print(2, "NOsh_parseInput: Already parsed an input file!\n");
535 return 0;
536 }
537
538 if (Vio_accept(sock, 0) < 0) {
539 Vnm_print(2, "NOsh_parseInput: Problem reading from socket!\n");
540 return 0;
541 }
542
543 /* Set up the whitespace and comment character definitions */
544 Vio_setWhiteChars(sock, MCwhiteChars);
545 Vio_setCommChars(sock, MCcommChars);
546
547 /* We parse the file until we run out of tokens */
548 Vnm_print(0, "NOsh_parseInput: Starting file parsing...\n");
549 while (Vio_scanf(sock, "%s", tok) == 1) {
550 /* At the highest level, we look for keywords that indicate functions like:
551
552 read => Read in a molecule file
553 elec => Do an electrostatics calculation
554 print => Print some results
555 apolar => do a non-polar calculation
556 quit => Quit
557
558 These cause the code to go to a lower-level parser routine which
559 handles keywords specific to the particular function. Each
560 lower-level parser routine then returns when it hits the "end"
561 keyword. Due to this simple layout, no nesting of these "function"
562 sections is allowed.
563 */
564 if (Vstring_strcasecmp(tok, "read") == 0) {
565 // printf("read\n");
566 Vnm_print(0, "NOsh: Parsing READ section\n");
567 if (!NOsh_parseREAD(thee, sock)) return 0;
568 Vnm_print(0, "NOsh: Done parsing READ section \
569 (nmol=%d, ndiel=%d, nkappa=%d, ncharge=%d, npot=%d)\n", thee->nmol, thee->ndiel,
570 thee->nkappa, thee->ncharge,thee->npot);
571 } else if (Vstring_strcasecmp(tok, "print") == 0) {
572 Vnm_print(0, "NOsh: Parsing PRINT section\n");
573 if (!NOsh_parsePRINT(thee, sock)) return 0;
574 Vnm_print(0, "NOsh: Done parsing PRINT section\n");
575 } else if (Vstring_strcasecmp(tok, "elec") == 0) {
576 Vnm_print(0, "NOsh: Parsing ELEC section\n");
577 if (!NOsh_parseELEC(thee, sock)) return 0;
578 Vnm_print(0, "NOsh: Done parsing ELEC section (nelec = %d)\n",
579 thee->nelec);
580 } else if (Vstring_strcasecmp(tok, "apolar") == 0) {
581 Vnm_print(0, "NOsh: Parsing APOLAR section\n");
582 if (!NOsh_parseAPOLAR(thee, sock)) return 0;
583 Vnm_print(0, "NOsh: Done parsing APOLAR section (nelec = %d)\n",
584 thee->nelec);
585 } else if (Vstring_strcasecmp(tok, "quit") == 0) {
586 Vnm_print(0, "NOsh: Done parsing file (got QUIT)\n");
587 break;
588 } else {
589 Vnm_print(2, "NOsh_parseInput: Ignoring undefined keyword %s!\n", tok);
590 }
591 }
592
593 thee->parsed = 1;
594 return 1;
595
596 }
597
NOsh_parseREAD_MOL(NOsh * thee,Vio * sock)598 VPRIVATE int NOsh_parseREAD_MOL(NOsh *thee, Vio *sock) {
599
600 char tok[VMAX_BUFSIZE], str[VMAX_BUFSIZE]="", strnew[VMAX_BUFSIZE]="";
601 NOsh_MolFormat molfmt;
602
603 VJMPERR1(Vio_scanf(sock, "%s", tok) == 1);
604 if (Vstring_strcasecmp(tok, "pqr") == 0) {
605 molfmt = NMF_PQR;
606 VJMPERR1(Vio_scanf(sock, "%s", tok) == 1);
607 if (tok[0]=='"') {
608 strcpy(strnew, "");
609 while (tok[strlen(tok)-1] != '"') {
610 strcat(str, tok);
611 strcat(str, " ");
612 VJMPERR1(Vio_scanf(sock, "%s", tok) == 1);
613 }
614 strcat(str, tok);
615 strncpy(strnew, str+1, strlen(str)-2);
616 strcpy(tok, strnew);
617 }
618 Vnm_print(0, "NOsh: Storing molecule %d path %s\n",
619 thee->nmol, tok);
620 thee->molfmt[thee->nmol] = molfmt;
621 strncpy(thee->molpath[thee->nmol], tok, VMAX_ARGLEN);
622 (thee->nmol)++;
623 } else if (Vstring_strcasecmp(tok, "pdb") == 0) {
624 molfmt = NMF_PDB;
625 VJMPERR1(Vio_scanf(sock, "%s", tok) == 1);
626 if (tok[0]=='"') {
627 strcpy(strnew, "");
628 while (tok[strlen(tok)-1] != '"') {
629 strcat(str, tok);
630 strcat(str, " ");
631 VJMPERR1(Vio_scanf(sock, "%s", tok) == 1);
632 }
633 strcat(str, tok);
634 strncpy(strnew, str+1, strlen(str)-2);
635 strcpy(tok, strnew);
636 }
637 Vnm_print(0, "NOsh: Storing molecule %d path %s\n",
638 thee->nmol, tok);
639 thee->molfmt[thee->nmol] = molfmt;
640 strncpy(thee->molpath[thee->nmol], tok, VMAX_ARGLEN);
641 (thee->nmol)++;
642 } else if (Vstring_strcasecmp(tok, "xml") == 0) {
643 molfmt = NMF_XML;
644 VJMPERR1(Vio_scanf(sock, "%s", tok) == 1);
645 if (tok[0]=='"') {
646 strcpy(strnew, "");
647 while (tok[strlen(tok)-1] != '"') {
648 strcat(str, tok);
649 strcat(str, " ");
650 VJMPERR1(Vio_scanf(sock, "%s", tok) == 1);
651 }
652 strcat(str, tok);
653 strncpy(strnew, str+1, strlen(str)-2);
654 strcpy(tok, strnew);
655 }
656 Vnm_print(0, "NOsh: Storing molecule %d path %s\n",
657 thee->nmol, tok);
658 thee->molfmt[thee->nmol] = molfmt;
659 strncpy(thee->molpath[thee->nmol], tok, VMAX_ARGLEN);
660 (thee->nmol)++;
661 } else {
662 Vnm_print(2, "NOsh_parseREAD: Ignoring undefined mol format \
663 %s!\n", tok);
664 }
665
666 return 1;
667
668
669 VERROR1:
670 Vnm_print(2, "NOsh_parseREAD_MOL: Ran out of tokens while parsing READ section!\n");
671 return 0;
672
673 }
674
NOsh_parseREAD_PARM(NOsh * thee,Vio * sock)675 VPRIVATE int NOsh_parseREAD_PARM(NOsh *thee, Vio *sock) {
676
677 char tok[VMAX_BUFSIZE], str[VMAX_BUFSIZE]="", strnew[VMAX_BUFSIZE]="";
678 NOsh_ParmFormat parmfmt;
679
680 VJMPERR1(Vio_scanf(sock, "%s", tok) == 1);
681 if (Vstring_strcasecmp(tok, "flat") == 0) {
682 parmfmt = NPF_FLAT;
683 VJMPERR1(Vio_scanf(sock, "%s", tok) == 1);
684 if (tok[0]=='"') {
685 strcpy(strnew, "");
686 while (tok[strlen(tok)-1] != '"') {
687 strcat(str, tok);
688 strcat(str, " ");
689 VJMPERR1(Vio_scanf(sock, "%s", tok) == 1);
690 }
691 strcat(str, tok);
692 strncpy(strnew, str+1, strlen(str)-2);
693 strcpy(tok, strnew);
694 }
695 if (thee->gotparm) {
696 Vnm_print(2, "NOsh: Hey! You already specified a parameterfile (%s)!\n", thee->parmpath);
697 Vnm_print(2, "NOsh: I'm going to ignore this one (%s)!\n", tok);
698 } else {
699 thee->parmfmt = parmfmt;
700 thee->gotparm = 1;
701 strncpy(thee->parmpath, tok, VMAX_ARGLEN);
702 }
703 } else if(Vstring_strcasecmp(tok, "xml") == 0) {
704 parmfmt = NPF_XML;
705 VJMPERR1(Vio_scanf(sock, "%s", tok) == 1);
706 if (tok[0]=='"') {
707 strcpy(strnew, "");
708 while (tok[strlen(tok)-1] != '"') {
709 strcat(str, tok);
710 strcat(str, " ");
711 VJMPERR1(Vio_scanf(sock, "%s", tok) == 1);
712 }
713 strcat(str, tok);
714 strncpy(strnew, str+1, strlen(str)-2);
715 strcpy(tok, strnew);
716 }
717 if (thee->gotparm) {
718 Vnm_print(2, "NOsh: Hey! You already specified a parameterfile (%s)!\n", thee->parmpath);
719 Vnm_print(2, "NOsh: I'm going to ignore this one (%s)!\n", tok);
720 } else {
721 thee->parmfmt = parmfmt;
722 thee->gotparm = 1;
723 strncpy(thee->parmpath, tok, VMAX_ARGLEN);
724 }
725
726 } else {
727 Vnm_print(2, "NOsh_parseREAD: Ignoring undefined parm format \
728 %s!\n", tok);
729 }
730
731 return 1;
732
733 VERROR1:
734 Vnm_print(2, "NOsh_parseREAD_PARM: Ran out of tokens while parsing READ section!\n");
735 return 0;
736
737 }
738
NOsh_parseREAD_DIEL(NOsh * thee,Vio * sock)739 VPRIVATE int NOsh_parseREAD_DIEL(NOsh *thee, Vio *sock) {
740
741 char tok[VMAX_BUFSIZE], str[VMAX_BUFSIZE]="", strnew[VMAX_BUFSIZE]="";
742 Vdata_Format dielfmt;
743
744 VJMPERR1(Vio_scanf(sock, "%s", tok) == 1);
745 if (Vstring_strcasecmp(tok, "dx") == 0) {
746 dielfmt = VDF_DX;
747 //added VDF_BIN to take binary files.
748 } else if (Vstring_strcasecmp(tok, "dxbin") == 0){
749 dielfmt = VDF_DXBIN;
750 }else if (Vstring_strcasecmp(tok, "gz") == 0) {
751 dielfmt = VDF_GZ;
752 } else {
753 Vnm_print(2, "NOsh_parseREAD: Ignoring undefined format \
754 %s!\n", tok);
755 return VRC_FAILURE;
756 }
757
758 VJMPERR1(Vio_scanf(sock, "%s", tok) == 1);
759 if (tok[0]=='"') {
760 strcpy(strnew, "");
761 while (tok[strlen(tok)-1] != '"') {
762 strcat(str, tok);
763 strcat(str, " ");
764 VJMPERR1(Vio_scanf(sock, "%s", tok) == 1);
765 }
766 strcat(str, tok);
767 strncpy(strnew, str+1, strlen(str)-2);
768 strcpy(tok, strnew);
769 }
770 Vnm_print(0, "NOsh: Storing x-shifted dielectric map %d path \
771 %s\n", thee->ndiel, tok);
772 strncpy(thee->dielXpath[thee->ndiel], tok, VMAX_ARGLEN);
773 VJMPERR1(Vio_scanf(sock, "%s", tok) == 1);
774 Vnm_print(0, "NOsh: Storing y-shifted dielectric map %d path \
775 %s\n", thee->ndiel, tok);
776 strncpy(thee->dielYpath[thee->ndiel], tok, VMAX_ARGLEN);
777 VJMPERR1(Vio_scanf(sock, "%s", tok) == 1);
778 Vnm_print(0, "NOsh: Storing z-shifted dielectric map %d path \
779 %s\n", thee->ndiel, tok);
780 strncpy(thee->dielZpath[thee->ndiel], tok, VMAX_ARGLEN);
781 thee->dielfmt[thee->ndiel] = dielfmt;
782 (thee->ndiel)++;
783
784 return 1;
785
786 VERROR1:
787 Vnm_print(2, "NOsh_parseREAD_DIEL: Ran out of tokens while parsing READ \
788 section!\n");
789 return 0;
790
791 }
792
NOsh_parseREAD_KAPPA(NOsh * thee,Vio * sock)793 VPRIVATE int NOsh_parseREAD_KAPPA(NOsh *thee, Vio *sock) {
794
795 char tok[VMAX_BUFSIZE], str[VMAX_BUFSIZE]="", strnew[VMAX_BUFSIZE]="";
796 Vdata_Format kappafmt;
797
798 VJMPERR1(Vio_scanf(sock, "%s", tok) == 1);
799 if (Vstring_strcasecmp(tok, "dx") == 0) {
800 kappafmt = VDF_DX;
801 } else if (Vstring_strcasecmp(tok, "gz") == 0) {
802 kappafmt = VDF_GZ;
803 } else if (Vstring_strcasecmp(tok,"dxbin") == 0) {
804 kappafmt = VDF_DXBIN;
805 } else {
806
807 Vnm_print(2, "NOsh_parseREAD: Ignoring undefined format \
808 %s!\n", tok);
809 return VRC_FAILURE;
810 }
811
812 VJMPERR1(Vio_scanf(sock, "%s", tok) == 1);
813 if (tok[0]=='"') {
814 strcpy(strnew, "");
815 while (tok[strlen(tok)-1] != '"') {
816 strcat(str, tok);
817 strcat(str, " ");
818 VJMPERR1(Vio_scanf(sock, "%s", tok) == 1);
819 }
820 strcat(str, tok);
821 strncpy(strnew, str+1, strlen(str)-2);
822 strcpy(tok, strnew);
823 }
824 Vnm_print(0, "NOsh: Storing kappa map %d path %s\n",
825 thee->nkappa, tok);
826 thee->kappafmt[thee->nkappa] = kappafmt;
827 strncpy(thee->kappapath[thee->nkappa], tok, VMAX_ARGLEN);
828 (thee->nkappa)++;
829
830 return 1;
831
832 VERROR1:
833 Vnm_print(2, "NOsh_parseREAD: Ran out of tokens while parsing READ \
834 section!\n");
835 return 0;
836
837 }
838
NOsh_parseREAD_POTENTIAL(NOsh * thee,Vio * sock)839 VPRIVATE int NOsh_parseREAD_POTENTIAL(NOsh *thee, Vio *sock) {
840
841 char tok[VMAX_BUFSIZE], str[VMAX_BUFSIZE]="", strnew[VMAX_BUFSIZE]="";
842 Vdata_Format potfmt;
843
844 VJMPERR1(Vio_scanf(sock, "%s", tok) == 1);
845 if (Vstring_strcasecmp(tok, "dx") == 0) {
846 potfmt = VDF_DX;
847 } else if (Vstring_strcasecmp(tok, "gz") == 0) {
848 potfmt = VDF_GZ;
849 } else if(Vstring_strcasecmp(tok, "dxbin") == 0){
850 potfmt = VDF_DXBIN;
851 } else {
852 Vnm_print(2, "NOsh_parseREAD: Ignoring undefined format \
853 %s!\n", tok);
854 return VRC_FAILURE;
855 }
856
857 VJMPERR1(Vio_scanf(sock, "%s", tok) == 1);
858 if (tok[0]=='"') {
859 strcpy(strnew, "");
860 while (tok[strlen(tok)-1] != '"') {
861 strcat(str, tok);
862 strcat(str, " ");
863 VJMPERR1(Vio_scanf(sock, "%s", tok) == 1);
864 }
865 strcat(str, tok);
866 strncpy(strnew, str+1, strlen(str)-2);
867 strcpy(tok, strnew);
868 }
869 Vnm_print(0, "NOsh: Storing potential map %d path %s\n",
870 thee->npot, tok);
871 thee->potfmt[thee->npot] = potfmt;
872 strncpy(thee->potpath[thee->npot], tok, VMAX_ARGLEN);
873 (thee->npot)++;
874
875 return 1;
876
877 VERROR1:
878 Vnm_print(2, "NOsh_parseREAD: Ran out of tokens while parsing READ \
879 section!\n");
880 return 0;
881
882 }
883
NOsh_parseREAD_CHARGE(NOsh * thee,Vio * sock)884 VPRIVATE int NOsh_parseREAD_CHARGE(NOsh *thee, Vio *sock) {
885
886 char tok[VMAX_BUFSIZE], str[VMAX_BUFSIZE]="", strnew[VMAX_BUFSIZE]="";
887 Vdata_Format chargefmt;
888
889 VJMPERR1(Vio_scanf(sock, "%s", tok) == 1);
890 if (Vstring_strcasecmp(tok, "dx") == 0) {
891 chargefmt = VDF_DX;
892 }
893 else if(Vstring_strcasecmp(tok, "dxbin") == 0){
894 chargefmt = VDF_DXBIN;
895 }else if (Vstring_strcasecmp(tok, "gz") == 0) {
896 chargefmt = VDF_GZ;
897 } else {
898 Vnm_print(2, "NOsh_parseREAD: Ignoring undefined format \
899 %s!\n", tok);
900 return VRC_FAILURE;
901 }
902
903 VJMPERR1(Vio_scanf(sock, "%s", tok) == 1);
904 if (tok[0]=='"') {
905 strcpy(strnew, "");
906 while (tok[strlen(tok)-1] != '"') {
907 strcat(str, tok);
908 strcat(str, " ");
909 VJMPERR1(Vio_scanf(sock, "%s", tok) == 1);
910 }
911 strcat(str, tok);
912 strncpy(strnew, str+1, strlen(str)-2);
913 strcpy(tok, strnew);
914 }
915 Vnm_print(0, "NOsh: Storing charge map %d path %s\n",
916 thee->ncharge, tok);
917 thee->chargefmt[thee->ncharge] = chargefmt;
918 strncpy(thee->chargepath[thee->ncharge], tok, VMAX_ARGLEN);
919 (thee->ncharge)++;
920
921 return 1;
922
923 VERROR1:
924 Vnm_print(2, "NOsh_parseREAD: Ran out of tokens while parsing READ \
925 section!\n");
926 return 0;
927
928 }
929
NOsh_parseREAD_MESH(NOsh * thee,Vio * sock)930 VPRIVATE int NOsh_parseREAD_MESH(NOsh *thee, Vio *sock) {
931
932 char tok[VMAX_BUFSIZE], str[VMAX_BUFSIZE]="", strnew[VMAX_BUFSIZE]="";
933 Vdata_Format meshfmt;
934
935 VJMPERR1(Vio_scanf(sock, "%s", tok) == 1);
936 if (Vstring_strcasecmp(tok, "mcsf") == 0) {
937 meshfmt = VDF_MCSF;
938 VJMPERR1(Vio_scanf(sock, "%s", tok) == 1);
939 if (tok[0]=='"') {
940 strcpy(strnew, "");
941 while (tok[strlen(tok)-1] != '"') {
942 strcat(str, tok);
943 strcat(str, " ");
944 VJMPERR1(Vio_scanf(sock, "%s", tok) == 1);
945 }
946 strcat(str, tok);
947 strncpy(strnew, str+1, strlen(str)-2);
948 strcpy(tok, strnew);
949 }
950 Vnm_print(0, "NOsh: Storing mesh %d path %s\n",
951 thee->nmesh, tok);
952 thee->meshfmt[thee->nmesh] = meshfmt;
953 strncpy(thee->meshpath[thee->nmesh], tok, VMAX_ARGLEN);
954 (thee->nmesh)++;
955 } else {
956 Vnm_print(2, "NOsh_parseREAD: Ignoring undefined mesh format \
957 %s!\n", tok);
958 }
959
960 return 1;
961
962 VERROR1:
963 Vnm_print(2, "NOsh_parseREAD: Ran out of tokens while parsing READ \
964 section!\n");
965 return 0;
966
967 }
968
969
NOsh_parseREAD(NOsh * thee,Vio * sock)970 VPRIVATE int NOsh_parseREAD(NOsh *thee, Vio *sock) {
971
972 char tok[VMAX_BUFSIZE];
973
974 if (thee == VNULL) {
975 Vnm_print(2, "NOsh_parseREAD: Got NULL thee!\n");
976 return 0;
977 }
978
979 if (sock == VNULL) {
980 Vnm_print(2, "NOsh_parseREAD: Got pointer to NULL socket!\n");
981 return 0;
982 }
983
984 if (thee->parsed) {
985 Vnm_print(2, "NOsh_parseREAD: Already parsed an input file!\n");
986 return 0;
987 }
988
989 /* Read until we run out of tokens (bad) or hit the "END" keyword (good) */
990 while (Vio_scanf(sock, "%s", tok) == 1) {
991 if (Vstring_strcasecmp(tok, "end") == 0) {
992 Vnm_print(0, "NOsh: Done parsing READ section\n");
993 return 1;
994 } else if (Vstring_strcasecmp(tok, "mol") == 0) {
995 NOsh_parseREAD_MOL(thee, sock);
996 } else if (Vstring_strcasecmp(tok, "parm") == 0) {
997 NOsh_parseREAD_PARM(thee,sock);
998 } else if (Vstring_strcasecmp(tok, "diel") == 0) {
999 NOsh_parseREAD_DIEL(thee,sock);
1000 } else if (Vstring_strcasecmp(tok, "kappa") == 0) {
1001 NOsh_parseREAD_KAPPA(thee,sock);
1002 } else if (Vstring_strcasecmp(tok, "pot") == 0) {
1003 NOsh_parseREAD_POTENTIAL(thee,sock);
1004 } else if (Vstring_strcasecmp(tok, "charge") == 0) {
1005 NOsh_parseREAD_CHARGE(thee,sock);
1006 } else if (Vstring_strcasecmp(tok, "mesh") == 0) {
1007 NOsh_parseREAD_MESH(thee,sock);
1008 } else {
1009 Vnm_print(2, "NOsh_parseREAD: Ignoring undefined keyword %s!\n",
1010 tok);
1011 }
1012 }
1013
1014 /* We ran out of tokens! */
1015 Vnm_print(2, "NOsh_parseREAD: Ran out of tokens while parsing READ \
1016 section!\n");
1017 return 0;
1018
1019 }
1020
NOsh_parsePRINT(NOsh * thee,Vio * sock)1021 VPRIVATE int NOsh_parsePRINT(NOsh *thee, Vio *sock) {
1022
1023 char tok[VMAX_BUFSIZE];
1024 char name[VMAX_BUFSIZE];
1025 int ti, idx, expect, ielec, iapol;
1026
1027 if (thee == VNULL) {
1028 Vnm_print(2, "NOsh_parsePRINT: Got NULL thee!\n");
1029 return 0;
1030 }
1031
1032 if (sock == VNULL) {
1033 Vnm_print(2, "NOsh_parsePRINT: Got pointer to NULL socket!\n");
1034 return 0;
1035 }
1036
1037 if (thee->parsed) {
1038 Vnm_print(2, "NOsh_parsePRINT: Already parsed an input file!\n");
1039 return 0;
1040 }
1041
1042 idx = thee->nprint;
1043 if (thee->nprint >= NOSH_MAXPRINT) {
1044 Vnm_print(2, "NOsh_parsePRINT: Exceeded max number (%d) of PRINT \
1045 sections\n",
1046 NOSH_MAXPRINT);
1047 return 0;
1048 }
1049
1050
1051 /* The first thing we read is the thing we want to print */
1052 VJMPERR1(Vio_scanf(sock, "%s", tok) == 1);
1053 if (Vstring_strcasecmp(tok, "energy") == 0) {
1054 thee->printwhat[idx] = NPT_ENERGY;
1055 thee->printnarg[idx] = 0;
1056 } else if (Vstring_strcasecmp(tok, "force") == 0) {
1057 thee->printwhat[idx] = NPT_FORCE;
1058 thee->printnarg[idx] = 0;
1059 } else if (Vstring_strcasecmp(tok, "elecEnergy") == 0) {
1060 thee->printwhat[idx] = NPT_ELECENERGY;
1061 thee->printnarg[idx] = 0;
1062 } else if (Vstring_strcasecmp(tok, "elecForce") == 0) {
1063 thee->printwhat[idx] = NPT_ELECFORCE;
1064 thee->printnarg[idx] = 0;
1065 } else if (Vstring_strcasecmp(tok, "apolEnergy") == 0) {
1066 thee->printwhat[idx] = NPT_APOLENERGY;
1067 thee->printnarg[idx] = 0;
1068 } else if (Vstring_strcasecmp(tok, "apolForce") == 0) {
1069 thee->printwhat[idx] = NPT_APOLFORCE;
1070 thee->printnarg[idx] = 0;
1071 } else {
1072 Vnm_print(2, "NOsh_parsePRINT: Undefined keyword %s while parsing \
1073 PRINT section!\n", tok);
1074 return 0;
1075 }
1076
1077 expect = 0; /* We first expect a calculation ID (0) then an op (1) */
1078
1079 /* Read until we run out of tokens (bad) or hit the "END" keyword (good) */
1080 while (Vio_scanf(sock, "%s", tok) == 1) {
1081
1082 /* The next thing we read is either END or an ARG OP ARG statement */
1083 if (Vstring_strcasecmp(tok, "end") == 0) {
1084 if (expect != 0) {
1085 (thee->nprint)++;
1086 (thee->printnarg[idx])++;
1087 Vnm_print(0, "NOsh: Done parsing PRINT section\n");
1088 return 1;
1089 } else {
1090 Vnm_print(2, "NOsh_parsePRINT: Got premature END to PRINT!\n");
1091 return 0;
1092 }
1093 } else {
1094
1095 /* Grab a calculation ID */
1096 if ((sscanf(tok, "%d", &ti) == 1) &&
1097 (Vstring_isdigit(tok) == 1)) {
1098 if (expect == 0) {
1099 thee->printcalc[idx][thee->printnarg[idx]] = ti-1;
1100 expect = 1;
1101 } else {
1102 Vnm_print(2, "NOsh_parsePRINT: Syntax error in PRINT \
1103 section while reading %s!\n", tok);
1104 return 0;
1105 }
1106 /* Grab addition operation */
1107 } else if (Vstring_strcasecmp(tok, "+") == 0) {
1108 if (expect == 1) {
1109 thee->printop[idx][thee->printnarg[idx]] = 0;
1110 (thee->printnarg[idx])++;
1111 expect = 0;
1112 if (thee->printnarg[idx] >= NOSH_MAXPOP) {
1113 Vnm_print(2, "NOsh_parsePRINT: Exceeded max number \
1114 (%d) of arguments for PRINT section!\n",
1115 NOSH_MAXPOP);
1116 return 0;
1117 }
1118 } else {
1119 Vnm_print(2, "NOsh_parsePRINT: Syntax error in PRINT \
1120 section while reading %s!\n", tok);
1121 return 0;
1122 }
1123 /* Grab subtraction operation */
1124 } else if (Vstring_strcasecmp(tok, "-") == 0) {
1125 if (expect == 1) {
1126 thee->printop[idx][thee->printnarg[idx]] = 1;
1127 (thee->printnarg[idx])++;
1128 expect = 0;
1129 if (thee->printnarg[idx] >= NOSH_MAXPOP) {
1130 Vnm_print(2, "NOsh_parseREAD: Exceeded max number \
1131 (%d) of arguments for PRINT section!\n",
1132 NOSH_MAXPOP);
1133 return 0;
1134 }
1135 } else {
1136 Vnm_print(2, "NOsh_parsePRINT: Syntax error in PRINT \
1137 section while reading %s!\n", tok);
1138 return 0;
1139 }
1140 /* Grab a calculation name from elec ID */
1141 } else if (sscanf(tok, "%s", name) == 1) {
1142 if (expect == 0) {
1143 for (ielec=0; ielec<thee->nelec; ielec++) {
1144 if (Vstring_strcasecmp(thee->elecname[ielec], name) == 0) {
1145 thee->printcalc[idx][thee->printnarg[idx]] = ielec;
1146 expect = 1;
1147 break;
1148 }
1149 }
1150 for (iapol=0; iapol<thee->napol; iapol++) {
1151 if (Vstring_strcasecmp(thee->apolname[iapol], name) == 0) {
1152 thee->printcalc[idx][thee->printnarg[idx]] = iapol;
1153 expect = 1;
1154 break;
1155 }
1156 }
1157 if (expect == 0) {
1158 Vnm_print(2, "No ELEC or APOL statement has been named %s!\n",
1159 name);
1160 return 0;
1161 }
1162 } else {
1163 Vnm_print(2, "NOsh_parsePRINT: Syntax error in PRINT \
1164 section while reading %s!\n", tok);
1165 return 0;
1166 }
1167 /* Got bad operation */
1168 } else {
1169 Vnm_print(2, "NOsh_parsePRINT: Undefined keyword %s while \
1170 parsing PRINT section!\n", tok);
1171 return 0;
1172 }
1173 } /* end parse token */
1174
1175 } /* end while */
1176
1177 VJMPERR1(0);
1178
1179 /* We ran out of tokens! */
1180 VERROR1:
1181 Vnm_print(2, "NOsh_parsePRINT: Ran out of tokens while parsing PRINT \
1182 section!\n");
1183 return 0;
1184
1185 }
1186
NOsh_parseELEC(NOsh * thee,Vio * sock)1187 VPRIVATE int NOsh_parseELEC(NOsh *thee, Vio *sock) {
1188
1189 NOsh_calc *calc = VNULL;
1190
1191 char tok[VMAX_BUFSIZE];
1192
1193 if (thee == VNULL) {
1194 Vnm_print(2, "NOsh_parseELEC: Got NULL thee!\n");
1195 return 0;
1196 }
1197
1198 if (sock == VNULL) {
1199 Vnm_print(2, "NOsh_parseELEC: Got pointer to NULL socket!\n");
1200 return 0;
1201 }
1202
1203 if (thee->parsed) {
1204 Vnm_print(2, "NOsh_parseELEC: Already parsed an input file!\n");
1205 return 0;
1206 }
1207
1208 /* Get a pointer to the latest ELEC calc object and update the ELEC
1209 statement number */
1210 if (thee->nelec >= NOSH_MAXCALC) {
1211 Vnm_print(2, "NOsh: Too many electrostatics calculations in this \
1212 run!\n");
1213 Vnm_print(2, "NOsh: Current max is %d; ignoring this calculation\n",
1214 NOSH_MAXCALC);
1215 return 1;
1216 }
1217
1218 /* The next token HAS to be the method OR "name" */
1219 if (Vio_scanf(sock, "%s", tok) == 1) {
1220 if (Vstring_strcasecmp(tok, "name") == 0) {
1221 Vio_scanf(sock, "%s", tok);
1222 strncpy(thee->elecname[thee->nelec], tok, VMAX_ARGLEN);
1223 if (Vio_scanf(sock, "%s", tok) != 1) {
1224 Vnm_print(2, "NOsh_parseELEC: Ran out of tokens while reading \
1225 ELEC section!\n");
1226 return 0;
1227 }
1228 }
1229 if (Vstring_strcasecmp(tok, "mg-manual") == 0) {
1230 thee->elec[thee->nelec] = NOsh_calc_ctor(NCT_MG);
1231 calc = thee->elec[thee->nelec];
1232 (thee->nelec)++;
1233 calc->mgparm->type = MCT_MANUAL;
1234 return NOsh_parseMG(thee, sock, calc);
1235 } else if (Vstring_strcasecmp(tok, "mg-auto") == 0) {
1236 thee->elec[thee->nelec] = NOsh_calc_ctor(NCT_MG);
1237 calc = thee->elec[thee->nelec];
1238 (thee->nelec)++;
1239 calc->mgparm->type = MCT_AUTO;
1240 return NOsh_parseMG(thee, sock, calc);
1241 } else if (Vstring_strcasecmp(tok, "mg-para") == 0) {
1242 thee->elec[thee->nelec] = NOsh_calc_ctor(NCT_MG);
1243 calc = thee->elec[thee->nelec];
1244 (thee->nelec)++;
1245 calc->mgparm->type = MCT_PARALLEL;
1246 return NOsh_parseMG(thee, sock, calc);
1247 } else if (Vstring_strcasecmp(tok, "mg-dummy") == 0) {
1248 thee->elec[thee->nelec] = NOsh_calc_ctor(NCT_MG);
1249 calc = thee->elec[thee->nelec];
1250 (thee->nelec)++;
1251 calc->mgparm->type = MCT_DUMMY;
1252 return NOsh_parseMG(thee, sock, calc);
1253 } else if (Vstring_strcasecmp(tok, "fe-manual") == 0) {
1254 thee->elec[thee->nelec] = NOsh_calc_ctor(NCT_FEM);
1255 calc = thee->elec[thee->nelec];
1256 (thee->nelec)++;
1257 calc->femparm->type = FCT_MANUAL;
1258 return NOsh_parseFEM(thee, sock, calc);
1259 } else if (Vstring_strcasecmp(tok, "tabi") == 0) {
1260 thee->elec[thee->nelec] = NOsh_calc_ctor(NCT_BEM);
1261 calc = thee->elec[thee->nelec];
1262 (thee->nelec)++;
1263 calc->bemparm->type = BCT_MANUAL;
1264 return NOsh_parseBEM(thee, sock, calc);
1265 } else if (Vstring_strcasecmp(tok, "bem") == 0) {
1266 thee->elec[thee->nelec] = NOsh_calc_ctor(NCT_BEM);
1267 calc = thee->elec[thee->nelec];
1268 (thee->nelec)++;
1269 calc->bemparm->type = BCT_MANUAL;
1270 return NOsh_parseBEM(thee, sock, calc);
1271 } else if (Vstring_strcasecmp(tok, "bem-manual") == 0) {
1272 thee->elec[thee->nelec] = NOsh_calc_ctor(NCT_BEM);
1273 calc = thee->elec[thee->nelec];
1274 (thee->nelec)++;
1275 calc->bemparm->type = BCT_MANUAL;
1276 return NOsh_parseBEM(thee, sock, calc);
1277 } else if (Vstring_strcasecmp(tok, "geoflow-manual") == 0) {
1278 Vnm_print(2, "Geoflow currently does not support geoflow-manual please use geoflow instead!\n");
1279 return 0;
1280 } else if(Vstring_strcasecmp(tok, "geoflow-none") == 0) {
1281 Vnm_print(2, "Geoflow currently does not support geoflow-none please use geoflow instead!\n");
1282 return 0;
1283 } else if (Vstring_strcasecmp(tok, "geoflow") == 0) {
1284 thee->elec[thee->nelec] = NOsh_calc_ctor(NCT_GEOFLOW);
1285 calc = thee->elec[thee->nelec];
1286 (thee->nelec)++;
1287 calc->geoflowparm->type = GFCT_AUTO;
1288 return NOsh_parseGEOFLOW(thee, sock, calc);
1289 } else if (Vstring_strcasecmp(tok, "pbam") == 0) {
1290 thee->elec[thee->nelec] = NOsh_calc_ctor(NCT_PBAM);
1291 calc = thee->elec[thee->nelec];
1292 (thee->nelec)++;
1293 calc->pbamparm->type = PBAMCT_AUTO;
1294 return NOsh_parsePBAM(thee, sock, calc);
1295 } else if (Vstring_strcasecmp(tok, "pbsam") == 0) {
1296 thee->elec[thee->nelec] = NOsh_calc_ctor(NCT_PBSAM);
1297 calc = thee->elec[thee->nelec];
1298 (thee->nelec)++;
1299 calc->pbsamparm->type = PBSAMCT_AUTO;
1300 return NOsh_parsePBSAM(thee, sock, calc);
1301 } else {
1302 Vnm_print(2, "NOsh_parseELEC: The method (\"mg\",\"fem\", \"bem\", \"geoflow\" \"pbam\", \"pbsam\") or \
1303 \"name\" must be the first keyword in the ELEC section\n");
1304 return 0;
1305 }
1306 }
1307
1308 Vnm_print(2, "NOsh_parseELEC: Ran out of tokens while reading ELEC section!\n");
1309 return 0;
1310
1311 }
1312
NOsh_parseAPOLAR(NOsh * thee,Vio * sock)1313 VPRIVATE int NOsh_parseAPOLAR(NOsh *thee, Vio *sock) {
1314
1315 NOsh_calc *calc = VNULL;
1316
1317 char tok[VMAX_BUFSIZE];
1318
1319 if (thee == VNULL) {
1320 Vnm_print(2, "NOsh_parseAPOLAR: Got NULL thee!\n");
1321 return 0;
1322 }
1323
1324 if (sock == VNULL) {
1325 Vnm_print(2, "NOsh_parseAPOLAR: Got pointer to NULL socket!\n");
1326 return 0;
1327 }
1328
1329 if (thee->parsed) {
1330 Vnm_print(2, "NOsh_parseAPOLAR: Already parsed an input file!\n");
1331 return 0;
1332 }
1333
1334 /* Get a pointer to the latest ELEC calc object and update the ELEC
1335 statement number */
1336 if (thee->napol >= NOSH_MAXCALC) {
1337 Vnm_print(2, "NOsh: Too many non-polar calculations in this \
1338 run!\n");
1339 Vnm_print(2, "NOsh: Current max is %d; ignoring this calculation\n",
1340 NOSH_MAXCALC);
1341 return 1;
1342 }
1343
1344 /* The next token HAS to be the method OR "name" */
1345 if (Vio_scanf(sock, "%s", tok) == 1) {
1346 if (Vstring_strcasecmp(tok, "name") == 0) {
1347 Vio_scanf(sock, "%s", tok);
1348 strncpy(thee->apolname[thee->napol], tok, VMAX_ARGLEN);
1349
1350 /* Parse the non-polar parameters */
1351 thee->apol[thee->napol] = NOsh_calc_ctor(NCT_APOL);
1352 calc = thee->apol[thee->napol];
1353 (thee->napol)++;
1354 return NOsh_parseAPOL(thee, sock, calc);
1355 // } else if (Vstring_strcasecmp(tok, "geoflow-manual") == 0) {
1356 // thee->elec[thee->nelec] = NOsh_calc_ctor(NCT_GEOFLOW);
1357 // calc = thee->elec[thee->nelec];
1358 // (thee->nelec)++;
1359 // calc->geoflowparm->type = GFCT_MANUAL;
1360 // return NOsh_parseGEOFLOW(thee, sock, calc);
1361 // } else if (Vstring_strcasecmp(tok, "geoflow-auto") == 0) {
1362 // thee->elec[thee->nelec] = NOsh_calc_ctor(NCT_GEOFLOW);
1363 // calc = thee->elec[thee->nelec];
1364 // (thee->nelec)++;
1365 // calc->geoflowparm->type = GFCT_AUTO;
1366 // return NOsh_parseGEOFLOW(thee, sock, calc);
1367 }
1368 }
1369
1370 return 1;
1371
1372 }
1373
NOsh_setupElecCalc(NOsh * thee,Valist * alist[NOSH_MAXMOL])1374 VPUBLIC int NOsh_setupElecCalc(
1375 NOsh *thee,
1376 Valist *alist[NOSH_MAXMOL]
1377 ) {
1378 int ielec, imol, i;
1379 NOsh_calc *elec = VNULL;
1380 MGparm *mgparm = VNULL;
1381 Valist *mymol = VNULL;
1382
1383 VASSERT(thee != VNULL);
1384 for (imol=0; imol<thee->nmol; imol++) {
1385 thee->alist[imol] = alist[imol];
1386 }
1387
1388
1389 for (ielec=0; ielec<(thee->nelec); ielec++) {
1390 /* Unload the calculation object containing the ELEC information */
1391 elec = thee->elec[ielec];
1392
1393 if (((thee->ndiel != 0) || (thee->nkappa != 0) ||
1394 (thee->ncharge != 0) || (thee->npot != 0)) &&
1395 (elec->pbeparm->calcforce != PCF_NO)) {
1396 Vnm_print(2, "NOsh_setupElecCalc: Calculation of forces disabled because surface \
1397 map is used!\n");
1398 elec->pbeparm->calcforce = PCF_NO;
1399 }
1400
1401 /* Setup the calculation */
1402 switch (elec->calctype) {
1403 case NCT_MG:
1404 /* Center on the molecules, if requested */
1405 mgparm = elec->mgparm;
1406 VASSERT(mgparm != VNULL);
1407 if (elec->mgparm->cmeth == MCM_MOLECULE) {
1408 VASSERT(mgparm->centmol >= 0);
1409 VASSERT(mgparm->centmol < thee->nmol);
1410 mymol = thee->alist[mgparm->centmol];
1411 VASSERT(mymol != VNULL);
1412 for (i=0; i<3; i++) {
1413 mgparm->center[i] = mymol->center[i];
1414 }
1415 }
1416 if (elec->mgparm->fcmeth == MCM_MOLECULE) {
1417 VASSERT(mgparm->fcentmol >= 0);
1418 VASSERT(mgparm->fcentmol < thee->nmol);
1419 mymol = thee->alist[mgparm->fcentmol];
1420 VASSERT(mymol != VNULL);
1421 for (i=0; i<3; i++) {
1422 mgparm->fcenter[i] = mymol->center[i];
1423 }
1424 }
1425 if (elec->mgparm->ccmeth == MCM_MOLECULE) {
1426 VASSERT(mgparm->ccentmol >= 0);
1427 VASSERT(mgparm->ccentmol < thee->nmol);
1428 mymol = thee->alist[mgparm->ccentmol];
1429 VASSERT(mymol != VNULL);
1430 for (i=0; i<3; i++) {
1431 mgparm->ccenter[i] = mymol->center[i];
1432 }
1433 }
1434 NOsh_setupCalcMG(thee, elec);
1435 break;
1436 case NCT_FEM:
1437 NOsh_setupCalcFEM(thee, elec);
1438 break;
1439 case NCT_PBAM:
1440 NOsh_setupCalcPBAM(thee, elec);
1441 break;
1442 case NCT_PBSAM:
1443 NOsh_setupCalcPBSAM(thee, elec);
1444 break;
1445 case NCT_BEM:
1446 NOsh_setupCalcBEM(thee, elec);
1447 break;
1448 case NCT_GEOFLOW:
1449 NOsh_setupCalcGEOFLOW(thee, elec);
1450 break;
1451 default:
1452 Vnm_print(2, "NOsh_setupCalc: Invalid calculation type (%d)!\n",
1453 elec->calctype);
1454 return 0;
1455 }
1456
1457 /* At this point, the most recently-created NOsh_calc object should be the
1458 one we use for results for this ELEC statement. Assign it. */
1459 /* Associate ELEC statement with the calculation */
1460 thee->elec2calc[ielec] = thee->ncalc-1;
1461 Vnm_print(0, "NOsh_setupCalc: Mapping ELEC statement %d (%d) to \
1462 calculation %d (%d)\n", ielec, ielec+1, thee->elec2calc[ielec],
1463 thee->elec2calc[ielec]+1);
1464 }
1465
1466 return 1;
1467 }
1468
NOsh_setupApolCalc(NOsh * thee,Valist * alist[NOSH_MAXMOL])1469 VPUBLIC int NOsh_setupApolCalc(
1470 NOsh *thee,
1471 Valist *alist[NOSH_MAXMOL]
1472 ) {
1473 int iapol, imol;
1474 int doCalc = ACD_NO;
1475 NOsh_calc *calc = VNULL;
1476
1477 VASSERT(thee != VNULL);
1478 for (imol=0; imol<thee->nmol; imol++) {
1479 thee->alist[imol] = alist[imol];
1480 }
1481
1482 for (iapol=0; iapol<(thee->napol); iapol++) {
1483 /* Unload the calculation object containing the APOL information */
1484 calc = thee->apol[iapol];
1485
1486 /* Setup the calculation */
1487 switch (calc->calctype) {
1488 case NCT_APOL:
1489 NOsh_setupCalcAPOL(thee, calc);
1490 doCalc = ACD_YES;
1491 break;
1492 default:
1493 Vnm_print(2, "NOsh_setupCalc: Invalid calculation type (%d)!\n", calc->calctype);
1494 return ACD_ERROR;
1495 }
1496 /* At this point, the most recently-created NOsh_calc object should be the
1497 one we use for results for this APOL statement. Assign it. */
1498 /* Associate APOL statement with the calculation */
1499 thee->apol2calc[iapol] = thee->ncalc-1;
1500 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);
1501 }
1502
1503 if(doCalc == ACD_YES){
1504 return ACD_YES;
1505 }else{
1506 return ACD_NO;
1507 }
1508 }
1509
NOsh_parseMG(NOsh * thee,Vio * sock,NOsh_calc * elec)1510 VPUBLIC int NOsh_parseMG(
1511 NOsh *thee,
1512 Vio *sock,
1513 NOsh_calc *elec
1514 ) {
1515
1516 char tok[VMAX_BUFSIZE];
1517 MGparm *mgparm = VNULL;
1518 PBEparm *pbeparm = VNULL;
1519 int rc;
1520
1521 /* Check the arguments */
1522 if (thee == VNULL) {
1523 Vnm_print(2, "NOsh: Got NULL thee!\n");
1524 return 0;
1525 }
1526 if (sock == VNULL) {
1527 Vnm_print(2, "NOsh: Got pointer to NULL socket!\n");
1528 return 0;
1529 }
1530 if (elec == VNULL) {
1531 Vnm_print(2, "NOsh: Got pointer to NULL elec object!\n");
1532 return 0;
1533 }
1534 mgparm = elec->mgparm;
1535 if (mgparm == VNULL) {
1536 Vnm_print(2, "NOsh: Got pointer to NULL mgparm object!\n");
1537 return 0;
1538 }
1539 pbeparm = elec->pbeparm;
1540 if (pbeparm == VNULL) {
1541 Vnm_print(2, "NOsh: Got pointer to NULL pbeparm object!\n");
1542 return 0;
1543 }
1544
1545 Vnm_print(0, "NOsh_parseMG: Parsing parameters for MG calculation\n");
1546
1547 /* Parallel stuff */
1548 if (mgparm->type == MCT_PARALLEL) {
1549 mgparm->proc_rank = thee->proc_rank;
1550 mgparm->proc_size = thee->proc_size;
1551 mgparm->setrank = 1;
1552 mgparm->setsize = 1;
1553 }
1554
1555
1556 /* Start snarfing tokens from the input stream */
1557 rc = 1;
1558 while (Vio_scanf(sock, "%s", tok) == 1) {
1559
1560 Vnm_print(0, "NOsh_parseMG: Parsing %s...\n", tok);
1561
1562 /* See if it's an END token */
1563 if (Vstring_strcasecmp(tok, "end") == 0) {
1564 mgparm->parsed = 1;
1565 pbeparm->parsed = 1;
1566 rc = 1;
1567 break;
1568 }
1569
1570 /* Pass the token through a series of parsers */
1571 rc = PBEparm_parseToken(pbeparm, tok, sock);
1572 if (rc == -1) {
1573 Vnm_print(0, "NOsh_parseMG: parsePBE error!\n");
1574 break;
1575 } else if (rc == 0) {
1576 /* Pass the token to the generic MG parser */
1577 rc = MGparm_parseToken(mgparm, tok, sock);
1578 if (rc == -1) {
1579 Vnm_print(0, "NOsh_parseMG: parseMG error!\n");
1580 break;
1581 } else if (rc == 0) {
1582 /* We ran out of parsers! */
1583 Vnm_print(2, "NOsh: Unrecognized keyword: %s\n", tok);
1584 break;
1585 }
1586 }
1587 }
1588
1589 /* Handle various errors arising in the token-snarfing loop -- these all
1590 just result in simple returns right now */
1591 if (rc == -1) return 0;
1592 if (rc == 0) return 0;
1593
1594 /* Check the status of the parameter objects */
1595 if ((MGparm_check(mgparm) == VRC_FAILURE) || (!PBEparm_check(pbeparm))) {
1596 Vnm_print(2, "NOsh: MG parameters not set correctly!\n");
1597 return 0;
1598 }
1599
1600 return 1;
1601 }
1602
NOsh_setupCalcMG(NOsh * thee,NOsh_calc * calc)1603 VPRIVATE int NOsh_setupCalcMG(
1604 NOsh *thee,
1605 NOsh_calc *calc
1606 ) {
1607
1608 MGparm *mgparm = VNULL;
1609
1610 VASSERT(thee != VNULL);
1611 VASSERT(calc != VNULL);
1612 mgparm = calc->mgparm;
1613 VASSERT(mgparm != VNULL);
1614
1615
1616 /* Now we're ready to whatever sorts of post-processing operations that are
1617 necessary for the various types of calculations */
1618 switch (mgparm->type) {
1619 case MCT_MANUAL:
1620 return NOsh_setupCalcMGMANUAL(thee, calc);
1621 case MCT_DUMMY:
1622 return NOsh_setupCalcMGMANUAL(thee, calc);
1623 case MCT_AUTO:
1624 return NOsh_setupCalcMGAUTO(thee, calc);
1625 case MCT_PARALLEL:
1626 return NOsh_setupCalcMGPARA(thee, calc);
1627 default:
1628 Vnm_print(2, "NOsh_setupCalcMG: undefined MG calculation type (%d)!\n",
1629 mgparm->type);
1630 return 0;
1631 }
1632
1633 /* Shouldn't get here */
1634 return 0;
1635 }
1636
1637
NOsh_setupCalcBEM(NOsh * thee,NOsh_calc * calc)1638 VPRIVATE int NOsh_setupCalcBEM(
1639 NOsh *thee,
1640 NOsh_calc *calc
1641 ) {
1642
1643 BEMparm *bemparm = VNULL;
1644
1645 VASSERT(thee != VNULL);
1646 VASSERT(calc != VNULL);
1647 bemparm = calc->bemparm;
1648 VASSERT(bemparm != VNULL);
1649
1650
1651 /* Now we're ready to whatever sorts of post-processing operations that are
1652 necessary for the various types of calculations */
1653 switch (bemparm->type) {
1654 case BCT_MANUAL:
1655 return NOsh_setupCalcBEMMANUAL(thee, calc);
1656 default:
1657 Vnm_print(2, "NOsh_setupCalcBEM: undefined BEM calculation type (%d)!\n",
1658 bemparm->type);
1659 return 0;
1660 }
1661
1662 /* Shouldn't get here */
1663 return 0;
1664 }
1665
NOsh_setupCalcGEOFLOW(NOsh * thee,NOsh_calc * calc)1666 VPRIVATE int NOsh_setupCalcGEOFLOW(NOsh *thee, NOsh_calc *calc) {
1667
1668 GEOFLOWparm *parm = VNULL;
1669
1670 VASSERT(thee != VNULL);
1671 VASSERT(calc != VNULL);
1672 parm = calc->geoflowparm;
1673 VASSERT(parm != VNULL);
1674
1675
1676 /* Now we're ready to whatever sorts of post-processing operations that are
1677 necessary for the various types of calculations */
1678 if(/*parm->type == GFCT_MANUAL ||*/ parm->type == GFCT_AUTO){
1679 return NOsh_setupCalcGEOFLOWMANUAL(thee, calc);
1680 }else{
1681 Vnm_print(2, "NOsh_setupCalcGEOFLOW: undefined GEOFLOW calculation type (%d)!\n", parm->type);
1682 return 0;
1683 }
1684 }
1685
NOsh_setupCalcPBAM(NOsh * thee,NOsh_calc * calc)1686 VPRIVATE int NOsh_setupCalcPBAM(NOsh *thee, NOsh_calc *calc){
1687
1688 PBAMparm *parm = VNULL;
1689
1690 VASSERT(thee!=VNULL);
1691 VASSERT(calc!=VNULL);
1692 parm = calc->pbamparm;
1693 VASSERT(parm!=VNULL);
1694
1695 if(parm->type == PBAMCT_AUTO){
1696 return NOsh_setupCalcPBAMAUTO(thee, calc);
1697 } else {
1698 Vnm_print(2, "NOsh_setupCalcPBAM: undefined PBAM calculation type (%d)!\n", parm->type);
1699 return 0;
1700 }
1701 }
1702
1703
NOsh_setupCalcPBSAM(NOsh * thee,NOsh_calc * calc)1704 VPRIVATE int NOsh_setupCalcPBSAM(NOsh *thee, NOsh_calc *calc){
1705
1706 PBSAMparm *parm = VNULL;
1707
1708 VASSERT(thee!=VNULL);
1709 VASSERT(calc!=VNULL);
1710 parm = calc->pbsamparm;
1711 VASSERT(parm!=VNULL);
1712
1713 if(parm->type == PBSAMCT_AUTO){
1714 return NOsh_setupCalcPBSAMAUTO(thee, calc);
1715 } else {
1716 Vnm_print(2, "NOsh_setupCalcPBSAM: undefined PBSAM calculation type (%d)!\n", parm->type);
1717 return 0;
1718 }
1719 }
1720
1721
NOsh_setupCalcFEM(NOsh * thee,NOsh_calc * calc)1722 VPRIVATE int NOsh_setupCalcFEM(
1723 NOsh *thee,
1724 NOsh_calc *calc
1725 ) {
1726
1727 VASSERT(thee != VNULL);
1728 VASSERT(calc != VNULL);
1729 VASSERT(calc->femparm != VNULL);
1730
1731 /* Now we're ready to whatever sorts of post-processing operations that are
1732 * necessary for the various types of calculations */
1733 switch (calc->femparm->type) {
1734 case FCT_MANUAL:
1735 return NOsh_setupCalcFEMANUAL(thee, calc);
1736 default:
1737 Vnm_print(2, "NOsh_parseFEM: unknown calculation type (%d)!\n",
1738 calc->femparm->type);
1739 return 0;
1740 }
1741
1742 /* Shouldn't get here */
1743 return 0;
1744 }
1745
1746
NOsh_setupCalcMGMANUAL(NOsh * thee,NOsh_calc * elec)1747 VPRIVATE int NOsh_setupCalcMGMANUAL(
1748 NOsh *thee,
1749 NOsh_calc *elec
1750 ) {
1751
1752 MGparm *mgparm = VNULL;
1753 PBEparm *pbeparm = VNULL;
1754 NOsh_calc *calc = VNULL;
1755
1756 if (thee == VNULL) {
1757 Vnm_print(2, "NOsh_setupCalcMGMANUAL: Got NULL thee!\n");
1758 return 0;
1759 }
1760 if (elec == VNULL) {
1761 Vnm_print(2, "NOsh_setupCalcMGMANUAL: Got NULL calc!\n");
1762 return 0;
1763 }
1764 mgparm = elec->mgparm;
1765 if (mgparm == VNULL) {
1766 Vnm_print(2, "NOsh_setupCalcMGMANUAL: Got NULL mgparm -- was this calculation \
1767 set up?\n");
1768 return 0;
1769 }
1770 pbeparm = elec->pbeparm;
1771 if (pbeparm == VNULL) {
1772 Vnm_print(2, "NOsh_setupCalcMGMANUAL: Got NULL pbeparm -- was this calculation \
1773 set up?\n");
1774 return 0;
1775 }
1776
1777 /* Set up missing MG parameters */
1778 if (mgparm->setgrid == 0) {
1779 VASSERT(mgparm->setglen);
1780 mgparm->grid[0] = mgparm->glen[0]/((double)(mgparm->dime[0]-1));
1781 mgparm->grid[1] = mgparm->glen[1]/((double)(mgparm->dime[1]-1));
1782 mgparm->grid[2] = mgparm->glen[2]/((double)(mgparm->dime[2]-1));
1783 }
1784 if (mgparm->setglen == 0) {
1785 VASSERT(mgparm->setgrid);
1786 mgparm->glen[0] = mgparm->grid[0]*((double)(mgparm->dime[0]-1));
1787 mgparm->glen[1] = mgparm->grid[1]*((double)(mgparm->dime[1]-1));
1788 mgparm->glen[2] = mgparm->grid[2]*((double)(mgparm->dime[2]-1));
1789 }
1790
1791 /* Check to see if he have any room left for this type of calculation, if
1792 so: set the calculation type, update the number of calculations of this type,
1793 and parse the rest of the section */
1794 if (thee->ncalc >= NOSH_MAXCALC) {
1795 Vnm_print(2, "NOsh: Too many calculations in this run!\n");
1796 Vnm_print(2, "NOsh: Current max is %d; ignoring this calculation\n",
1797 NOSH_MAXCALC);
1798 return 0;
1799 }
1800
1801 /* Get the next calculation object and increment the number of calculations */
1802 thee->calc[thee->ncalc] = NOsh_calc_ctor(NCT_MG);
1803 calc = thee->calc[thee->ncalc];
1804 (thee->ncalc)++;
1805
1806
1807
1808 /* Copy over contents of ELEC */
1809 NOsh_calc_copy(calc, elec);
1810
1811
1812 return 1;
1813 }
1814
NOsh_setupCalcMGAUTO(NOsh * thee,NOsh_calc * elec)1815 VPUBLIC int NOsh_setupCalcMGAUTO(
1816 NOsh *thee,
1817 NOsh_calc *elec
1818 ) {
1819
1820 NOsh_calc *calcf = VNULL;
1821 NOsh_calc *calcc = VNULL;
1822 double fgrid[3], cgrid[3];
1823 double d[3], minf[3], maxf[3], minc[3], maxc[3];
1824 double redfrac, redrat[3], td;
1825 int ifocus, nfocus, tnfocus[3];
1826 int j;
1827 int icalc;
1828 int dofix;
1829
1830 /* A comment about the coding style in this function. I use lots and lots
1831 and lots of pointer deferencing. I could (and probably should) save
1832 these in temporary variables. However, since there are so many MGparm,
1833 etc. and NOsh_calc, etc. objects running around in this function, the
1834 current scheme is easiest to debug. */
1835
1836
1837 if (thee == VNULL) {
1838 Vnm_print(2, "NOsh_setupCalcMGAUTO: Got NULL thee!\n");
1839 return 0;
1840 }
1841 if (elec == VNULL) {
1842 Vnm_print(2, "NOsh_setupCalcMGAUTO: Got NULL elec!\n");
1843 return 0;
1844 }
1845 if (elec->mgparm == VNULL) {
1846 Vnm_print(2, "NOsh_setupCalcMGAUTO: Got NULL mgparm!\n");
1847 return 0;
1848 }
1849 if (elec->pbeparm == VNULL) {
1850 Vnm_print(2, "NOsh_setupCalcMGAUTO: Got NULL pbeparm!\n");
1851 return 0;
1852 }
1853
1854 Vnm_print(0, "NOsh_setupCalcMGAUTO(%s, %d): coarse grid center = %g %g %g\n",
1855 __FILE__, __LINE__,
1856 elec->mgparm->ccenter[0],
1857 elec->mgparm->ccenter[1],
1858 elec->mgparm->ccenter[2]);
1859 Vnm_print(0, "NOsh_setupCalcMGAUTO(%s, %d): fine grid center = %g %g %g\n",
1860 __FILE__, __LINE__,
1861 elec->mgparm->fcenter[0],
1862 elec->mgparm->fcenter[1],
1863 elec->mgparm->fcenter[2]);
1864
1865 /* Calculate the grid spacing on the coarse and fine levels */
1866 for (j=0; j<3; j++) {
1867 cgrid[j] = (elec->mgparm->cglen[j])/((double)(elec->mgparm->dime[j]-1));
1868 fgrid[j] = (elec->mgparm->fglen[j])/((double)(elec->mgparm->dime[j]-1));
1869 d[j] = elec->mgparm->fcenter[j] - elec->mgparm->ccenter[j];
1870 }
1871 Vnm_print(0, "NOsh_setupCalcMGAUTO (%s, %d): Coarse grid spacing = %g, %g, %g\n",
1872 __FILE__, __LINE__, cgrid[0], cgrid[1], cgrid[2]);
1873 Vnm_print(0, "NOsh_setupCalcMGAUTO (%s, %d): Fine grid spacing = %g, %g, %g\n",
1874 __FILE__, __LINE__, fgrid[0], fgrid[1], fgrid[2]);
1875 Vnm_print(0, "NOsh_setupCalcMGAUTO (%s, %d): Displacement between fine and \
1876 coarse grids = %g, %g, %g\n", __FILE__, __LINE__, d[0], d[1], d[2]);
1877
1878 /* Now calculate the number of focusing levels, never reducing the grid
1879 spacing by more than redfrac at each level */
1880 for (j=0; j<3; j++) {
1881 if (fgrid[j]/cgrid[j] < VREDFRAC) {
1882 redfrac = fgrid[j]/cgrid[j];
1883 td = log(redfrac)/log(VREDFRAC);
1884 tnfocus[j] = (int)ceil(td) + 1;
1885 } else tnfocus[j] = 2;
1886 }
1887 nfocus = VMAX2(VMAX2(tnfocus[0], tnfocus[1]), tnfocus[2]);
1888
1889 /* Now set redrat to the actual value by which the grid spacing is reduced
1890 at each level of focusing */
1891 for (j=0; j<3; j++) {
1892 redrat[j] = VPOW((fgrid[j]/cgrid[j]), 1.0/((double)nfocus-1.0));
1893 }
1894 Vnm_print(0, "NOsh: %d levels of focusing with %g, %g, %g reductions\n",
1895 nfocus, redrat[0], redrat[1], redrat[2]);
1896
1897 /* Now that we know how many focusing levels to use, we're ready to set up
1898 the parameter objects */
1899 if (nfocus > (NOSH_MAXCALC-(thee->ncalc))) {
1900 Vnm_print(2, "NOsh: Require more calculations than max (%d)!\n",
1901 NOSH_MAXCALC);
1902 return 0;
1903 }
1904
1905 for (ifocus=0; ifocus<nfocus; ifocus++) {
1906
1907 /* Generate the new calc object */
1908 icalc = thee->ncalc;
1909 thee->calc[icalc] = NOsh_calc_ctor(NCT_MG);
1910 (thee->ncalc)++;
1911
1912 /* This is the _current_ NOsh_calc object */
1913 calcf = thee->calc[icalc];
1914 /* This is the _previous_ Nosh_calc object */
1915 if (ifocus != 0) {
1916 calcc = thee->calc[icalc-1];
1917 } else {
1918 calcc = VNULL;
1919 }
1920
1921 /* Copy over most of the parameters from the ELEC object */
1922 NOsh_calc_copy(calcf, elec);
1923
1924 /* Set up the grid lengths and spacings */
1925 if (ifocus == 0) {
1926 for (j=0; j<3; j++) {
1927 calcf->mgparm->grid[j] = cgrid[j];
1928 calcf->mgparm->glen[j] = elec->mgparm->cglen[j];
1929 }
1930 } else {
1931 for (j=0; j<3; j++) {
1932 calcf->mgparm->grid[j] = redrat[j]*(calcc->mgparm->grid[j]);
1933 calcf->mgparm->glen[j] = redrat[j]*(calcc->mgparm->glen[j]);
1934 }
1935 }
1936 calcf->mgparm->setgrid = 1;
1937 calcf->mgparm->setglen = 1;
1938
1939 /* Get centers and centering method from coarse and fine meshes */
1940 if (ifocus == 0) {
1941 calcf->mgparm->cmeth = elec->mgparm->ccmeth;
1942 calcf->mgparm->centmol = elec->mgparm->ccentmol;
1943 for (j=0; j<3; j++) {
1944 calcf->mgparm->center[j] = elec->mgparm->ccenter[j];
1945 }
1946 } else if (ifocus == (nfocus-1)) {
1947 calcf->mgparm->cmeth = elec->mgparm->fcmeth;
1948 calcf->mgparm->centmol = elec->mgparm->fcentmol;
1949 for (j=0; j<3; j++) {
1950 calcf->mgparm->center[j] = elec->mgparm->fcenter[j];
1951 }
1952 } else {
1953 calcf->mgparm->cmeth = MCM_FOCUS;
1954 /* TEMPORARILY move the current grid center
1955 to the fine grid center. In general, this will move portions of
1956 the current mesh off the immediately-coarser mesh. We'll fix that
1957 in the next step. */
1958 for (j=0; j<3; j++) {
1959 calcf->mgparm->center[j] = elec->mgparm->fcenter[j];
1960 }
1961 }
1962
1963
1964 /* As mentioned above, it is highly likely that the previous "jump"
1965 to the fine grid center put portions of the current mesh off the
1966 previous (coarser) mesh. Fix this by displacing the current mesh
1967 back onto the previous coarser mesh. */
1968 if (ifocus != 0) {
1969 Vnm_print(0, "NOsh_setupCalcMGAUTO (%s, %d): starting mesh \
1970 repositioning.\n", __FILE__, __LINE__);
1971 Vnm_print(0, "NOsh_setupCalcMGAUTO (%s, %d): coarse mesh center = \
1972 %g %g %g\n", __FILE__, __LINE__,
1973 calcc->mgparm->center[0],
1974 calcc->mgparm->center[1],
1975 calcc->mgparm->center[2]);
1976 Vnm_print(0, "NOsh_setupCalcMGAUTO (%s, %d): coarse mesh upper corner = \
1977 %g %g %g\n", __FILE__, __LINE__,
1978 calcc->mgparm->center[0]+0.5*(calcc->mgparm->glen[0]),
1979 calcc->mgparm->center[1]+0.5*(calcc->mgparm->glen[1]),
1980 calcc->mgparm->center[2]+0.5*(calcc->mgparm->glen[2]));
1981 Vnm_print(0, "NOsh_setupCalcMGAUTO (%s, %d): coarse mesh lower corner = \
1982 %g %g %g\n", __FILE__, __LINE__,
1983 calcc->mgparm->center[0]-0.5*(calcc->mgparm->glen[0]),
1984 calcc->mgparm->center[1]-0.5*(calcc->mgparm->glen[1]),
1985 calcc->mgparm->center[2]-0.5*(calcc->mgparm->glen[2]));
1986 Vnm_print(0, "NOsh_setupCalcMGAUTO (%s, %d): initial fine mesh upper corner = \
1987 %g %g %g\n", __FILE__, __LINE__,
1988 calcf->mgparm->center[0]+0.5*(calcf->mgparm->glen[0]),
1989 calcf->mgparm->center[1]+0.5*(calcf->mgparm->glen[1]),
1990 calcf->mgparm->center[2]+0.5*(calcf->mgparm->glen[2]));
1991 Vnm_print(0, "NOsh_setupCalcMGAUTO (%s, %d): initial fine mesh lower corner = \
1992 %g %g %g\n", __FILE__, __LINE__,
1993 calcf->mgparm->center[0]-0.5*(calcf->mgparm->glen[0]),
1994 calcf->mgparm->center[1]-0.5*(calcf->mgparm->glen[1]),
1995 calcf->mgparm->center[2]-0.5*(calcf->mgparm->glen[2]));
1996 for (j=0; j<3; j++) {
1997 /* Check if we've fallen off of the lower end of the mesh */
1998 dofix = 0;
1999 minf[j] = calcf->mgparm->center[j]
2000 - 0.5*(calcf->mgparm->glen[j]);
2001 minc[j] = calcc->mgparm->center[j]
2002 - 0.5*(calcc->mgparm->glen[j]);
2003 d[j] = minc[j] - minf[j];
2004 if (d[j] >= VSMALL) {
2005 if (ifocus == (nfocus-1)) {
2006 Vnm_print(2, "NOsh_setupCalcMGAUTO: Error! Finest \
2007 mesh has fallen off the coarser meshes!\n");
2008 Vnm_print(2, "NOsh_setupCalcMGAUTO: difference in min %d-\
2009 direction = %g\n", j, d[j]);
2010 Vnm_print(2, "NOsh_setupCalcMGAUTO: min fine = %g %g %g\n",
2011 minf[0], minf[1], minf[2]);
2012 Vnm_print(2, "NOsh_setupCalcMGAUTO: min coarse = %g %g %g\n",
2013 minc[0], minc[1], minc[2]);
2014 VASSERT(0);
2015 } else {
2016 Vnm_print(0, "NOsh_setupCalcMGAUTO (%s, %d): ifocus = %d, \
2017 fixing mesh min violation (%g in %d-direction).\n", __FILE__, __LINE__, ifocus,
2018 d[j], j);
2019 calcf->mgparm->center[j] += d[j];
2020 dofix = 1;
2021 }
2022 }
2023 /* Check if we've fallen off of the upper end of the mesh */
2024 maxf[j] = calcf->mgparm->center[j] \
2025 + 0.5*(calcf->mgparm->glen[j]);
2026 maxc[j] = calcc->mgparm->center[j] \
2027 + 0.5*(calcc->mgparm->glen[j]);
2028 d[j] = maxf[j] - maxc[j];
2029 if (d[j] >= VSMALL) {
2030 if (ifocus == (nfocus-1)) {
2031 Vnm_print(2, "NOsh_setupCalcMGAUTO: Error! Finest \
2032 mesh has fallen off the coarser meshes!\n");
2033 Vnm_print(2, "NOsh_setupCalcMGAUTO: difference in %d-\
2034 direction = %g\n", j, d[j]);
2035 VASSERT(0);
2036 } else {
2037 /* If we already fixed the lower boundary and we now need
2038 to fix the upper boundary, we have a serious problem. */
2039 if (dofix) {
2040 Vnm_print(2, "NOsh_setupCalcMGAUTO: Error! Both \
2041 ends of the finer mesh do not fit in the bigger mesh!\n");
2042 VASSERT(0);
2043 }
2044 Vnm_print(0, "NOsh_setupCalcMGAUTO(%s, %d): ifocus = %d, \
2045 fixing mesh max violation (%g in %d-direction).\n", __FILE__, __LINE__, ifocus,
2046 d[j], j);
2047 calcf->mgparm->center[j] -= d[j];
2048 dofix = 1;
2049 }
2050 }
2051 }
2052 Vnm_print(0, "NOsh_setupCalcMGAUTO (%s, %d): final fine mesh upper corner = \
2053 %g %g %g\n", __FILE__, __LINE__,
2054 calcf->mgparm->center[0]+0.5*(calcf->mgparm->glen[0]),
2055 calcf->mgparm->center[1]+0.5*(calcf->mgparm->glen[1]),
2056 calcf->mgparm->center[2]+0.5*(calcf->mgparm->glen[2]));
2057 Vnm_print(0, "NOsh_setupCalcMGAUTO (%s, %d): final fine mesh lower corner = \
2058 %g %g %g\n", __FILE__, __LINE__,
2059 calcf->mgparm->center[0]-0.5*(calcf->mgparm->glen[0]),
2060 calcf->mgparm->center[1]-0.5*(calcf->mgparm->glen[1]),
2061 calcf->mgparm->center[2]-0.5*(calcf->mgparm->glen[2]));
2062 }
2063
2064 /* Finer levels have focusing boundary conditions */
2065 if (ifocus != 0) calcf->pbeparm->bcfl = BCFL_FOCUS;
2066
2067 /* Only the finest level handles I/O and needs to worry about disjoint
2068 partitioning */
2069 if (ifocus != (nfocus-1)) calcf->pbeparm->numwrite = 0;
2070
2071 /* Reset boundary flags for everything except parallel focusing */
2072 if (calcf->mgparm->type != MCT_PARALLEL) {
2073 Vnm_print(0, "NOsh_setupMGAUTO: Resetting boundary flags\n");
2074 for (j=0; j<6; j++) calcf->mgparm->partDisjOwnSide[j] = 0;
2075 for (j=0; j<3; j++) {
2076 calcf->mgparm->partDisjCenter[j] = 0;
2077 calcf->mgparm->partDisjLength[j] = calcf->mgparm->glen[j];
2078 }
2079 }
2080
2081
2082 calcf->mgparm->parsed = 1;
2083 }
2084
2085
2086 return 1;
2087 }
2088
2089 /* Author: Nathan Baker and Todd Dolinsky */
NOsh_setupCalcMGPARA(NOsh * thee,NOsh_calc * elec)2090 VPUBLIC int NOsh_setupCalcMGPARA(
2091 NOsh *thee,
2092 NOsh_calc *elec
2093 ) {
2094
2095 /* NEW (25-Jul-2006): This code should produce modify the ELEC statement
2096 and pass it on to MGAUTO for further processing. */
2097
2098 MGparm *mgparm = VNULL;
2099 double ofrac;
2100 double hx, hy, hzed;
2101 double xofrac, yofrac, zofrac;
2102 int rank, size, npx, npy, npz, nproc, ip, jp, kp;
2103 int xeffGlob, yeffGlob, zeffGlob, xDisj, yDisj, zDisj;
2104 int xigminDisj, xigmaxDisj, yigminDisj, yigmaxDisj, zigminDisj, zigmaxDisj;
2105 int xigminOlap, xigmaxOlap, yigminOlap, yigmaxOlap, zigminOlap, zigmaxOlap;
2106 int xOlapReg, yOlapReg, zOlapReg;
2107 double xlenDisj, ylenDisj, zlenDisj;
2108 double xcentDisj, ycentDisj, zcentDisj;
2109 double xcentOlap, ycentOlap, zcentOlap;
2110 double xlenOlap, ylenOlap, zlenOlap;
2111 double xminOlap, xmaxOlap, yminOlap, ymaxOlap, zminOlap, zmaxOlap;
2112 double xminDisj, xmaxDisj, yminDisj, ymaxDisj, zminDisj, zmaxDisj;
2113 double xcent, ycent, zcent;
2114
2115 /* Grab some useful variables */
2116 VASSERT(thee != VNULL);
2117 VASSERT(elec != VNULL);
2118 mgparm = elec->mgparm;
2119 VASSERT(mgparm != VNULL);
2120
2121 /* Grab some useful variables */
2122 ofrac = mgparm->ofrac;
2123 npx = mgparm->pdime[0];
2124 npy = mgparm->pdime[1];
2125 npz = mgparm->pdime[2];
2126 nproc = npx*npy*npz;
2127
2128 /* If this is not an asynchronous calculation, then we need to make sure we
2129 have all the necessary MPI information */
2130 if (mgparm->setasync == 0) {
2131
2132 #ifndef HAVE_MPI_H
2133
2134 Vnm_tprint(2, "NOsh_setupCalcMGPARA: Oops! You're trying to perform \
2135 an 'mg-para' (parallel) calculation\n");
2136 Vnm_tprint(2, "NOsh_setupCalcMGPARA: with a version of APBS that wasn't \
2137 compiled with MPI!\n");
2138 Vnm_tprint(2, "NOsh_setupCalcMGPARA: Perhaps you meant to use the \
2139 'async' flag?\n");
2140 Vnm_tprint(2, "NOsh_setupCalcMGPARA: Bailing out!\n");
2141
2142 return 0;
2143
2144 #endif
2145
2146 rank = thee->proc_rank;
2147 size = thee->proc_size;
2148 Vnm_print(0, "NOsh_setupCalcMGPARA: Hello from processor %d of %d\n", rank,
2149 size);
2150
2151 /* Check to see if we have too many processors. If so, then simply set
2152 this processor to duplicating the work of processor 0. */
2153 if (rank > (nproc-1)) {
2154 Vnm_print(2, "NOsh_setupMGPARA: There are more processors available than\
2155 the %d you requested.\n", nproc);
2156 Vnm_print(2, "NOsh_setupMGPARA: Eliminating processor %d\n", rank);
2157 thee->bogus = 1;
2158 rank = 0;
2159 }
2160
2161 /* Check to see if we have too few processors. If so, this is a fatal
2162 error. */
2163 if (size < nproc) {
2164 Vnm_print(2, "NOsh_setupMGPARA: There are too few processors (%d) to \
2165 satisfy requirements (%d)\n", size, nproc);
2166 return 0;
2167 }
2168
2169 Vnm_print(0, "NOsh_setupMGPARA: Hello (again) from processor %d of %d\n",
2170 rank, size);
2171
2172 } else { /* Setting up for an asynchronous calculation. */
2173
2174 rank = mgparm->async;
2175
2176 thee->ispara = 1;
2177 thee->proc_rank = rank;
2178
2179 /* Check to see if the async id is greater than the number of
2180 * processors. If so, this is a fatal error. */
2181 if (rank > (nproc-1)) {
2182 Vnm_print(2, "NOsh_setupMGPARA: The processor id you requested (%d) \
2183 is not within the range of processors available (0-%d)\n", rank, (nproc-1));
2184 return 0;
2185 }
2186 }
2187
2188 /* Calculate the processor's coordinates in the processor grid */
2189 kp = (int)floor(rank/(npx*npy));
2190 jp = (int)floor((rank-kp*npx*npy)/npx);
2191 ip = rank - kp*npx*npy - jp*npx;
2192 Vnm_print(0, "NOsh_setupMGPARA: Hello world from PE (%d, %d, %d)\n",
2193 ip, jp, kp);
2194
2195 /* Calculate effective overlap fractions for uneven processor distributions */
2196 if (npx == 1) xofrac = 0.0;
2197 else xofrac = ofrac;
2198 if (npy == 1) yofrac = 0.0;
2199 else yofrac = ofrac;
2200 if (npz == 1) zofrac = 0.0;
2201 else zofrac = ofrac;
2202
2203 /* Calculate the global grid size and spacing */
2204 xDisj = (int)VFLOOR(mgparm->dime[0]/(1 + 2*xofrac) + 0.5);
2205 xeffGlob = npx*xDisj;
2206 hx = mgparm->fglen[0]/(double)(xeffGlob-1);
2207 yDisj = (int)VFLOOR(mgparm->dime[1]/(1 + 2*yofrac) + 0.5);
2208 yeffGlob = npy*yDisj;
2209 hy = mgparm->fglen[1]/(double)(yeffGlob-1);
2210 zDisj = (int)VFLOOR(mgparm->dime[2]/(1 + 2*zofrac) + 0.5);
2211 zeffGlob = npz*zDisj;
2212 hzed = mgparm->fglen[2]/(double)(zeffGlob-1);
2213 Vnm_print(0, "NOsh_setupMGPARA: Global Grid size = (%d, %d, %d)\n",
2214 xeffGlob, yeffGlob, zeffGlob);
2215 Vnm_print(0, "NOsh_setupMGPARA: Global Grid Spacing = (%.3f, %.3f, %.3f)\n",
2216 hx, hy, hzed);
2217 Vnm_print(0, "NOsh_setupMGPARA: Processor Grid Size = (%d, %d, %d)\n",
2218 xDisj, yDisj, zDisj);
2219
2220 /* Calculate the maximum and minimum processor grid points */
2221 xigminDisj = ip*xDisj;
2222 xigmaxDisj = xigminDisj + xDisj - 1;
2223 yigminDisj = jp*yDisj;
2224 yigmaxDisj = yigminDisj + yDisj - 1;
2225 zigminDisj = kp*zDisj;
2226 zigmaxDisj = zigminDisj + zDisj - 1;
2227 Vnm_print(0, "NOsh_setupMGPARA: Min Grid Points for this proc. (%d, %d, %d)\n",
2228 xigminDisj, yigminDisj, zigminDisj);
2229 Vnm_print(0, "NOsh_setupMGPARA: Max Grid Points for this proc. (%d, %d, %d)\n",
2230 xigmaxDisj, yigmaxDisj, zigmaxDisj);
2231
2232
2233 /* Calculate the disjoint partition length and center displacement */
2234 xminDisj = VMAX2(hx*(xigminDisj-0.5), 0.0);
2235 xmaxDisj = VMIN2(hx*(xigmaxDisj+0.5), mgparm->fglen[0]);
2236 xlenDisj = xmaxDisj - xminDisj;
2237 yminDisj = VMAX2(hy*(yigminDisj-0.5), 0.0);
2238 ymaxDisj = VMIN2(hy*(yigmaxDisj+0.5), mgparm->fglen[1]);
2239 ylenDisj = ymaxDisj - yminDisj;
2240 zminDisj = VMAX2(hzed*(zigminDisj-0.5), 0.0);
2241 zmaxDisj = VMIN2(hzed*(zigmaxDisj+0.5), mgparm->fglen[2]);
2242 zlenDisj = zmaxDisj - zminDisj;
2243
2244 xcent = 0.5*mgparm->fglen[0];
2245 ycent = 0.5*mgparm->fglen[1];
2246 zcent = 0.5*mgparm->fglen[2];
2247
2248 xcentDisj = xminDisj + 0.5*xlenDisj - xcent;
2249 ycentDisj = yminDisj + 0.5*ylenDisj - ycent;
2250 zcentDisj = zminDisj + 0.5*zlenDisj - zcent;
2251 if (VABS(xcentDisj) < VSMALL) xcentDisj = 0.0;
2252 if (VABS(ycentDisj) < VSMALL) ycentDisj = 0.0;
2253 if (VABS(zcentDisj) < VSMALL) zcentDisj = 0.0;
2254
2255 Vnm_print(0, "NOsh_setupMGPARA: Disj part length = (%g, %g, %g)\n",
2256 xlenDisj, ylenDisj, zlenDisj);
2257 Vnm_print(0, "NOsh_setupMGPARA: Disj part center displacement = (%g, %g, %g)\n",
2258 xcentDisj, ycentDisj, zcentDisj);
2259
2260 /* Calculate the overlapping partition length and center displacement */
2261 xOlapReg = 0;
2262 yOlapReg = 0;
2263 zOlapReg = 0;
2264 if (npx != 1) xOlapReg = (int)VFLOOR(xofrac*mgparm->fglen[0]/npx/hx + 0.5) + 1;
2265 if (npy != 1) yOlapReg = (int)VFLOOR(yofrac*mgparm->fglen[1]/npy/hy + 0.5) + 1;
2266 if (npz != 1) zOlapReg = (int)VFLOOR(zofrac*mgparm->fglen[2]/npz/hzed + 0.5) + 1;
2267
2268 Vnm_print(0, "NOsh_setupMGPARA: No. of Grid Points in Overlap (%d, %d, %d)\n",
2269 xOlapReg, yOlapReg, zOlapReg);
2270
2271 if (ip == 0) xigminOlap = 0;
2272 else if (ip == (npx - 1)) xigminOlap = xeffGlob - mgparm->dime[0];
2273 else xigminOlap = xigminDisj - xOlapReg;
2274 xigmaxOlap = xigminOlap + mgparm->dime[0] - 1;
2275
2276 if (jp == 0) yigminOlap = 0;
2277 else if (jp == (npy - 1)) yigminOlap = yeffGlob - mgparm->dime[1];
2278 else yigminOlap = yigminDisj - yOlapReg;
2279 yigmaxOlap = yigminOlap + mgparm->dime[1] - 1;
2280
2281 if (kp == 0) zigminOlap = 0;
2282 else if (kp == (npz - 1)) zigminOlap = zeffGlob - mgparm->dime[2];
2283 else zigminOlap = zigminDisj - zOlapReg;
2284 zigmaxOlap = zigminOlap + mgparm->dime[2] - 1;
2285
2286 Vnm_print(0, "NOsh_setupMGPARA: Min Grid Points with Overlap (%d, %d, %d)\n",
2287 xigminOlap, yigminOlap, zigminOlap);
2288 Vnm_print(0, "NOsh_setupMGPARA: Max Grid Points with Overlap (%d, %d, %d)\n",
2289 xigmaxOlap, yigmaxOlap, zigmaxOlap);
2290
2291 xminOlap = hx * xigminOlap;
2292 xmaxOlap = hx * xigmaxOlap;
2293 yminOlap = hy * yigminOlap;
2294 ymaxOlap = hy * yigmaxOlap;
2295 zminOlap = hzed * zigminOlap;
2296 zmaxOlap = hzed * zigmaxOlap;
2297
2298 xlenOlap = xmaxOlap - xminOlap;
2299 ylenOlap = ymaxOlap - yminOlap;
2300 zlenOlap = zmaxOlap - zminOlap;
2301
2302 xcentOlap = (xminOlap + 0.5*xlenOlap) - xcent;
2303 ycentOlap = (yminOlap + 0.5*ylenOlap) - ycent;
2304 zcentOlap = (zminOlap + 0.5*zlenOlap) - zcent;
2305 if (VABS(xcentOlap) < VSMALL) xcentOlap = 0.0;
2306 if (VABS(ycentOlap) < VSMALL) ycentOlap = 0.0;
2307 if (VABS(zcentOlap) < VSMALL) zcentOlap = 0.0;
2308
2309 Vnm_print(0, "NOsh_setupMGPARA: Olap part length = (%g, %g, %g)\n",
2310 xlenOlap, ylenOlap, zlenOlap);
2311 Vnm_print(0, "NOsh_setupMGPARA: Olap part center displacement = (%g, %g, %g)\n",
2312 xcentOlap, ycentOlap, zcentOlap);
2313
2314
2315 /* Calculate the boundary flags:
2316 Flags are set to 1 when another processor is present along the boundary
2317 Flags are otherwise set to 0. */
2318
2319 if (ip == 0) mgparm->partDisjOwnSide[VAPBS_LEFT] = 0;
2320 else mgparm->partDisjOwnSide[VAPBS_LEFT] = 1;
2321 if (ip == (npx-1)) mgparm->partDisjOwnSide[VAPBS_RIGHT] = 0;
2322 else mgparm->partDisjOwnSide[VAPBS_RIGHT] = 1;
2323 if (jp == 0) mgparm->partDisjOwnSide[VAPBS_BACK] = 0;
2324 else mgparm->partDisjOwnSide[VAPBS_BACK] = 1;
2325 if (jp == (npy-1)) mgparm->partDisjOwnSide[VAPBS_FRONT] = 0;
2326 else mgparm->partDisjOwnSide[VAPBS_FRONT] = 1;
2327 if (kp == 0) mgparm->partDisjOwnSide[VAPBS_DOWN] = 0;
2328 else mgparm->partDisjOwnSide[VAPBS_DOWN] = 1;
2329 if (kp == (npz-1)) mgparm->partDisjOwnSide[VAPBS_UP] = 0;
2330 else mgparm->partDisjOwnSide[VAPBS_UP] = 1;
2331
2332 Vnm_print(0, "NOsh_setupMGPARA: partDisjOwnSide[LEFT] = %d\n",
2333 mgparm->partDisjOwnSide[VAPBS_LEFT]);
2334 Vnm_print(0, "NOsh_setupMGPARA: partDisjOwnSide[RIGHT] = %d\n",
2335 mgparm->partDisjOwnSide[VAPBS_RIGHT]);
2336 Vnm_print(0, "NOsh_setupMGPARA: partDisjOwnSide[FRONT] = %d\n",
2337 mgparm->partDisjOwnSide[VAPBS_FRONT]);
2338 Vnm_print(0, "NOsh_setupMGPARA: partDisjOwnSide[BACK] = %d\n",
2339 mgparm->partDisjOwnSide[VAPBS_BACK]);
2340 Vnm_print(0, "NOsh_setupMGPARA: partDisjOwnSide[UP] = %d\n",
2341 mgparm->partDisjOwnSide[VAPBS_UP]);
2342 Vnm_print(0, "NOsh_setupMGPARA: partDisjOwnSide[DOWN] = %d\n",
2343 mgparm->partDisjOwnSide[VAPBS_DOWN]);
2344
2345 /* Set the mesh parameters */
2346 mgparm->fglen[0] = xlenOlap;
2347 mgparm->fglen[1] = ylenOlap;
2348 mgparm->fglen[2] = zlenOlap;
2349 mgparm->partDisjLength[0] = xlenDisj;
2350 mgparm->partDisjLength[1] = ylenDisj;
2351 mgparm->partDisjLength[2] = zlenDisj;
2352 mgparm->partDisjCenter[0] = mgparm->fcenter[0] + xcentDisj;
2353 mgparm->partDisjCenter[1] = mgparm->fcenter[1] + ycentDisj;
2354 mgparm->partDisjCenter[2] = mgparm->fcenter[2] + zcentDisj;
2355 mgparm->fcenter[0] += xcentOlap;
2356 mgparm->fcenter[1] += ycentOlap;
2357 mgparm->fcenter[2] += zcentOlap;
2358
2359 Vnm_print(0, "NOsh_setupCalcMGPARA (%s, %d): Set up *relative* partition \
2360 centers...\n", __FILE__, __LINE__);
2361 Vnm_print(0, "NOsh_setupCalcMGPARA (%s, %d): Absolute centers will be set \
2362 in NOsh_setupMGAUTO\n", __FILE__, __LINE__);
2363 Vnm_print(0, "NOsh_setupCalcMGPARA (%s, %d): partDisjCenter = %g %g %g\n",
2364 __FILE__, __LINE__,
2365 mgparm->partDisjCenter[0],
2366 mgparm->partDisjCenter[1],
2367 mgparm->partDisjCenter[2]);
2368 Vnm_print(0, "NOsh_setupCalcMGPARA (%s, %d): ccenter = %g %g %g\n",
2369 __FILE__, __LINE__,
2370 mgparm->ccenter[0],
2371 mgparm->ccenter[1],
2372 mgparm->ccenter[2]);
2373 Vnm_print(0, "NOsh_setupCalcMGPARA (%s, %d): fcenter = %g %g %g\n",
2374 __FILE__, __LINE__,
2375 mgparm->fcenter[0],
2376 mgparm->fcenter[1],
2377 mgparm->fcenter[2]);
2378
2379
2380 /* Setup the automatic focusing calculations associated with this processor */
2381 return NOsh_setupCalcMGAUTO(thee, elec);
2382
2383 }
2384
NOsh_parseFEM(NOsh * thee,Vio * sock,NOsh_calc * elec)2385 VPUBLIC int NOsh_parseFEM(
2386 NOsh *thee,
2387 Vio *sock,
2388 NOsh_calc *elec
2389 ) {
2390
2391 char tok[VMAX_BUFSIZE];
2392 FEMparm *feparm = VNULL;
2393 PBEparm *pbeparm = VNULL;
2394 int rc;
2395 Vrc_Codes vrc;
2396
2397 /* Check the arguments */
2398 if (thee == VNULL) {
2399 Vnm_print(2, "NOsh_parseFEM: Got NULL thee!\n");
2400 return 0;
2401 }
2402 if (sock == VNULL) {
2403 Vnm_print(2, "NOsh_parseFEM: Got pointer to NULL socket!\n");
2404 return 0;
2405 }
2406 if (elec == VNULL) {
2407 Vnm_print(2, "NOsh_parseFEM: Got pointer to NULL elec object!\n");
2408 return 0;
2409 }
2410 feparm = elec->femparm;
2411 if (feparm == VNULL) {
2412 Vnm_print(2, "NOsh_parseFEM: Got pointer to NULL feparm object!\n");
2413 return 0;
2414 }
2415 pbeparm = elec->pbeparm;
2416 if (feparm == VNULL) {
2417 Vnm_print(2, "NOsh_parseFEM: Got pointer to NULL pbeparm object!\n");
2418 return 0;
2419 }
2420
2421 Vnm_print(0, "NOsh_parseFEM: Parsing parameters for FEM calculation\n");
2422
2423 /* Start snarfing tokens from the input stream */
2424 rc = 1;
2425 while (Vio_scanf(sock, "%s", tok) == 1) {
2426
2427 Vnm_print(0, "NOsh_parseFEM: Parsing %s...\n", tok);
2428
2429 /* See if it's an END token */
2430 if (Vstring_strcasecmp(tok, "end") == 0) {
2431 feparm->parsed = 1;
2432 pbeparm->parsed = 1;
2433 rc = 1;
2434 break;
2435 }
2436
2437 /* Pass the token through a series of parsers */
2438 rc = PBEparm_parseToken(pbeparm, tok, sock);
2439 if (rc == -1) {
2440 Vnm_print(0, "NOsh_parseFEM: parsePBE error!\n");
2441 break;
2442 } else if (rc == 0) {
2443 /* Pass the token to the generic MG parser */
2444 vrc = FEMparm_parseToken(feparm, tok, sock);
2445 if (vrc == VRC_FAILURE) {
2446 Vnm_print(0, "NOsh_parseFEM: parseMG error!\n");
2447 break;
2448 } else if (vrc == VRC_WARNING) {
2449 /* We ran out of parsers! */
2450 Vnm_print(2, "NOsh: Unrecognized keyword: %s\n", tok);
2451 break;
2452 }
2453 }
2454 }
2455
2456 /* Handle various errors arising in the token-snarfing loop -- these all
2457 * just result in simple returns right now */
2458 if (rc == -1) return 0;
2459 if (rc == 0) return 0;
2460
2461 /* Check the status of the parameter objects */
2462 if ((!FEMparm_check(feparm)) || (!PBEparm_check(pbeparm))) {
2463 Vnm_print(2, "NOsh: FEM parameters not set correctly!\n");
2464 return 0;
2465 }
2466
2467 return 1;
2468
2469 }
2470
NOsh_setupCalcFEMANUAL(NOsh * thee,NOsh_calc * elec)2471 VPRIVATE int NOsh_setupCalcFEMANUAL(
2472 NOsh *thee,
2473 NOsh_calc *elec
2474 ) {
2475
2476 FEMparm *feparm = VNULL;
2477 PBEparm *pbeparm = VNULL;
2478 NOsh_calc *calc = VNULL;
2479
2480 VASSERT(thee != VNULL);
2481 VASSERT(elec != VNULL);
2482 feparm = elec->femparm;
2483 VASSERT(feparm != VNULL);
2484 pbeparm = elec->pbeparm;
2485 VASSERT(pbeparm);
2486
2487 /* Check to see if he have any room left for this type of
2488 * calculation, if so: set the calculation type, update the number
2489 * of calculations of this type, and parse the rest of the section
2490 */
2491 if (thee->ncalc >= NOSH_MAXCALC) {
2492 Vnm_print(2, "NOsh: Too many calculations in this run!\n");
2493 Vnm_print(2, "NOsh: Current max is %d; ignoring this calculation\n",
2494 NOSH_MAXCALC);
2495 return 0;
2496 }
2497 thee->calc[thee->ncalc] = NOsh_calc_ctor(NCT_FEM);
2498 calc = thee->calc[thee->ncalc];
2499 (thee->ncalc)++;
2500
2501 /* Copy over contents of ELEC */
2502 NOsh_calc_copy(calc, elec);
2503
2504
2505 return 1;
2506 }
2507
NOsh_parseAPOL(NOsh * thee,Vio * sock,NOsh_calc * elec)2508 VPUBLIC int NOsh_parseAPOL(
2509 NOsh *thee,
2510 Vio *sock,
2511 NOsh_calc *elec
2512 ) {
2513
2514 char tok[VMAX_BUFSIZE];
2515 APOLparm *apolparm = VNULL;
2516 int rc;
2517
2518 /* Check the arguments */
2519 if (thee == VNULL) {
2520 Vnm_print(2, "NOsh_parseAPOL: Got NULL thee!\n");
2521 return 0;
2522 }
2523 if (sock == VNULL) {
2524 Vnm_print(2, "NOsh_parseAPOL: Got pointer to NULL socket!\n");
2525 return 0;
2526 }
2527 if (elec == VNULL) {
2528 Vnm_print(2, "NOsh_parseAPOL: Got pointer to NULL elec object!\n");
2529 return 0;
2530 }
2531 apolparm = elec->apolparm;
2532 if (apolparm == VNULL) {
2533 Vnm_print(2, "NOsh_parseAPOL: Got pointer to NULL apolparm object!\n");
2534 return 0;
2535 }
2536
2537 Vnm_print(0, "NOsh_parseAPOL: Parsing parameters for APOL calculation\n");
2538
2539 /* Start snarfing tokens from the input stream */
2540 rc = 1;
2541 while (Vio_scanf(sock, "%s", tok) == 1) {
2542
2543 Vnm_print(0, "NOsh_parseAPOL: Parsing %s...\n", tok);
2544 /* See if it's an END token */
2545 if (Vstring_strcasecmp(tok, "end") == 0) {
2546 apolparm->parsed = 1;
2547 rc = 1;
2548 break;
2549 }
2550
2551 /* Pass the token through a series of parsers */
2552 /* Pass the token to the generic non-polar parser */
2553 rc = APOLparm_parseToken(apolparm, tok, sock);
2554 if (rc == -1) {
2555 Vnm_print(0, "NOsh_parseFEM: parseMG error!\n");
2556 break;
2557 } else if (rc == 0) {
2558 /* We ran out of parsers! */
2559 Vnm_print(2, "NOsh: Unrecognized keyword: %s\n", tok);
2560 break;
2561 }
2562
2563 }
2564
2565 /* Handle various errors arising in the token-snarfing loop -- these all
2566 * just result in simple returns right now */
2567 if (rc == -1) return 0;
2568 if (rc == 0) return 0;
2569
2570 /* Check the status of the parameter objects */
2571 if (!APOLparm_check(apolparm)) {
2572 Vnm_print(2, "NOsh: APOL parameters not set correctly!\n");
2573 return 0;
2574 }
2575
2576 return 1;
2577
2578 }
2579
2580
NOsh_setupCalcAPOL(NOsh * thee,NOsh_calc * apol)2581 VPRIVATE int NOsh_setupCalcAPOL(
2582 NOsh *thee,
2583 NOsh_calc *apol
2584 ) {
2585
2586 NOsh_calc *calc = VNULL;
2587
2588 VASSERT(thee != VNULL);
2589 VASSERT(apol != VNULL);
2590
2591 /* Check to see if he have any room left for this type of
2592 * calculation, if so: set the calculation type, update the number
2593 * of calculations of this type, and parse the rest of the section
2594 */
2595 if (thee->ncalc >= NOSH_MAXCALC) {
2596 Vnm_print(2, "NOsh: Too many calculations in this run!\n");
2597 Vnm_print(2, "NOsh: Current max is %d; ignoring this calculation\n",
2598 NOSH_MAXCALC);
2599 return 0;
2600 }
2601 thee->calc[thee->ncalc] = NOsh_calc_ctor(NCT_APOL);
2602 calc = thee->calc[thee->ncalc];
2603 (thee->ncalc)++;
2604
2605 /* Copy over contents of APOL */
2606 NOsh_calc_copy(calc, apol);
2607
2608 return 1;
2609 }
2610
2611
NOsh_setupCalcBEMMANUAL(NOsh * thee,NOsh_calc * elec)2612 VPRIVATE int NOsh_setupCalcBEMMANUAL(
2613 NOsh *thee,
2614 NOsh_calc *elec
2615 ) {
2616
2617 BEMparm *bemparm = VNULL;
2618 PBEparm *pbeparm = VNULL;
2619 NOsh_calc *calc = VNULL;
2620
2621 if (thee == VNULL) {
2622 Vnm_print(2, "NOsh_setupCalcBEMMANUAL: Got NULL thee!\n");
2623 return 0;
2624 }
2625 if (elec == VNULL) {
2626 Vnm_print(2, "NOsh_setupCalcBEMMANUAL: Got NULL calc!\n");
2627 return 0;
2628 }
2629 bemparm = elec->bemparm;
2630 if (bemparm == VNULL) {
2631 Vnm_print(2, "NOsh_setupCalcBEMMANUAL: Got NULL bemparm -- was this calculation \
2632 set up?\n");
2633 return 0;
2634 }
2635 pbeparm = elec->pbeparm;
2636 if (pbeparm == VNULL) {
2637 Vnm_print(2, "NOsh_setupCalcBEMMANUAL: Got NULL pbeparm -- was this calculation \
2638 set up?\n");
2639 return 0;
2640 }
2641
2642 /* Set up missing BEM parameters */
2643 if (bemparm->settree_order == 0) {
2644 bemparm->tree_order=1;
2645 }
2646
2647 if (bemparm->settree_n0 == 0) {
2648 bemparm->tree_n0=500;
2649 }
2650
2651 if (bemparm->setmac == 0) {
2652 bemparm->mac=0.8;
2653 }
2654
2655 /* Check to see if he have any room left for this type of calculation, if
2656 so: set the calculation type, update the number of calculations of this type,
2657 and parse the rest of the section */
2658 if (thee->ncalc >= NOSH_MAXCALC) {
2659 Vnm_print(2, "NOsh: Too many calculations in this run!\n");
2660 Vnm_print(2, "NOsh: Current max is %d; ignoring this calculation\n",
2661 NOSH_MAXCALC);
2662 return 0;
2663 }
2664
2665 /* Get the next calculation object and increment the number of calculations */
2666 thee->calc[thee->ncalc] = NOsh_calc_ctor(NCT_BEM);
2667 calc = thee->calc[thee->ncalc];
2668 (thee->ncalc)++;
2669
2670 /* Copy over contents of ELEC */
2671 NOsh_calc_copy(calc, elec);
2672
2673
2674 return 1;
2675 }
2676
NOsh_setupCalcGEOFLOWMANUAL(NOsh * thee,NOsh_calc * elec)2677 VPRIVATE int NOsh_setupCalcGEOFLOWMANUAL(
2678 NOsh *thee,
2679 NOsh_calc *elec
2680 ) {
2681
2682 GEOFLOWparm *parm = VNULL;
2683 APOLparm *apolparm = VNULL;
2684 PBEparm *pbeparm = VNULL;
2685 NOsh_calc *calc = VNULL;
2686
2687 if (thee == VNULL) {
2688 Vnm_print(2, "NOsh_setupCalcGEOFLOWMANUAL: Got NULL thee!\n");
2689 return 0;
2690 }
2691 if (elec == VNULL) {
2692 Vnm_print(2, "NOsh_setupCalcGEOFLOWMANUAL: Got NULL calc!\n");
2693 return 0;
2694 }
2695 parm = elec->geoflowparm;
2696 if (parm == VNULL) {
2697 Vnm_print(2, "NOsh_setupCalcGEOFLOWMANUAL: Got NULL geoflowparm -- was this calculation \
2698 set up?\n");
2699 return 0;
2700 }
2701 apolparm = elec->apolparm;
2702 if (parm == VNULL) {
2703 Vnm_print(2, "NOsh_setupCalcGEOFLOWMANUAL: Got NULL apolparm -- was this calculation \
2704 set up?\n");
2705 return 0;
2706 }
2707 pbeparm = elec->pbeparm;
2708 if (pbeparm == VNULL) {
2709 Vnm_print(2, "NOsh_setupCalcGEOFLOWMANUAL: Got NULL pbeparm -- was this calculation \
2710 set up?\n");
2711 return 0;
2712 }
2713
2714 /* Check to see if he have any room left for this type of calculation, if
2715 so: set the calculation type, update the number of calculations of this type,
2716 and parse the rest of the section */
2717 if (thee->ncalc >= NOSH_MAXCALC) {
2718 Vnm_print(2, "NOsh: Too many calculations in this run!\n");
2719 Vnm_print(2, "NOsh: Current max is %d; ignoring this calculation\n",
2720 NOSH_MAXCALC);
2721 return 0;
2722 }
2723
2724 /* Get the next calculation object and increment the number of calculations */
2725 thee->calc[thee->ncalc] = NOsh_calc_ctor(NCT_GEOFLOW);
2726 calc = thee->calc[thee->ncalc];
2727 (thee->ncalc)++;
2728
2729 /* Copy over contents of ELEC */
2730 NOsh_calc_copy(calc, elec);
2731
2732 return 1;
2733 }
2734
NOsh_setupCalcPBAMAUTO(NOsh * thee,NOsh_calc * elec)2735 VPRIVATE int NOsh_setupCalcPBAMAUTO(
2736 NOsh *thee,
2737 NOsh_calc *elec
2738 ) {
2739
2740 PBAMparm *parm = VNULL;
2741 PBEparm *pbeparm = VNULL;
2742 NOsh_calc *calc = VNULL;
2743
2744 if (thee == VNULL) {
2745 Vnm_print(2, "NOsh_setupCalcPBAMAUTO: Got NULL thee!\n");
2746 return 0;
2747 }
2748 if (elec == VNULL) {
2749 Vnm_print(2, "NOsh_setupCalcPBAMAUTO: Got NULL calc!\n");
2750 return 0;
2751 }
2752 parm = elec->pbamparm;
2753 if (parm == VNULL) {
2754 Vnm_print(2, "NOsh_setupCalcPBAMAUTO: Got NULL pbamparm -- was this calculation \
2755 set up?\n");
2756 return 0;
2757 }
2758 pbeparm = elec->pbeparm;
2759 if (pbeparm == VNULL) {
2760 Vnm_print(2, "NOsh_setupCalcPBAMAUTO: Got NULL pbeparm -- was this calculation \
2761 set up?\n");
2762 return 0;
2763 }
2764
2765 /* Check to see if he have any room left for this type of calculation, if
2766 so: set the calculation type, update the number of calculations of this type,
2767 and parse the rest of the section */
2768 if (thee->ncalc >= NOSH_MAXCALC) {
2769 Vnm_print(2, "NOsh: Too many calculations in this run!\n");
2770 Vnm_print(2, "NOsh: Current max is %d; ignoring this calculation\n",
2771 NOSH_MAXCALC);
2772 return 0;
2773 }
2774
2775 /* Get the next calculation object and increment the number of calculations */
2776 thee->calc[thee->ncalc] = NOsh_calc_ctor(NCT_PBAM);
2777 calc = thee->calc[thee->ncalc];
2778 (thee->ncalc)++;
2779
2780 /* Copy over contents of ELEC */
2781 NOsh_calc_copy(calc, elec);
2782
2783 return 1;
2784 }
2785
NOsh_setupCalcPBSAMAUTO(NOsh * thee,NOsh_calc * elec)2786 VPRIVATE int NOsh_setupCalcPBSAMAUTO(
2787 NOsh *thee,
2788 NOsh_calc *elec
2789 ) {
2790
2791 PBAMparm *parm = VNULL;
2792 PBSAMparm *samparm = VNULL;
2793 PBEparm *pbeparm = VNULL;
2794 NOsh_calc *calc = VNULL;
2795
2796 if (thee == VNULL) {
2797 Vnm_print(2, "NOsh_setupCalcPBSAMAUTO: Got NULL thee!\n");
2798 return 0;
2799 }
2800 if (elec == VNULL) {
2801 Vnm_print(2, "NOsh_setupCalcPBSAMAUTO: Got NULL calc!\n");
2802 return 0;
2803 }
2804 parm = elec->pbamparm;
2805 if (parm == VNULL) {
2806 Vnm_print(2, "NOsh_setupCalcPBSAMAUTO: Got NULL pbamparm -- was this calculation \
2807 set up?\n");
2808 return 0;
2809 }
2810 samparm = elec->pbsamparm;
2811 if (samparm == VNULL) {
2812 Vnm_print(2, "NOsh_setupCalcPBSAMAUTO: Got NULL pbsamparm -- was this calculation \
2813 set up?\n");
2814 return 0;
2815 }
2816 pbeparm = elec->pbeparm;
2817 if (pbeparm == VNULL) {
2818 Vnm_print(2, "NOsh_setupCalcPBAMAUTO: Got NULL pbeparm -- was this calculation \
2819 set up?\n");
2820 return 0;
2821 }
2822
2823 /* Check to see if he have any room left for this type of calculation, if
2824 so: set the calculation type, update the number of calculations of this type,
2825 and parse the rest of the section */
2826 if (thee->ncalc >= NOSH_MAXCALC) {
2827 Vnm_print(2, "NOsh: Too many calculations in this run!\n");
2828 Vnm_print(2, "NOsh: Current max is %d; ignoring this calculation\n",
2829 NOSH_MAXCALC);
2830 return 0;
2831 }
2832
2833 /* Get the next calculation object and increment the number of calculations */
2834 thee->calc[thee->ncalc] = NOsh_calc_ctor(NCT_PBSAM);
2835 calc = thee->calc[thee->ncalc];
2836 (thee->ncalc)++;
2837
2838 /* Copy over contents of ELEC */
2839 NOsh_calc_copy(calc, elec);
2840
2841 return 1;
2842 }
2843
2844
NOsh_parseBEM(NOsh * thee,Vio * sock,NOsh_calc * elec)2845 VPUBLIC int NOsh_parseBEM(
2846 NOsh *thee,
2847 Vio *sock,
2848 NOsh_calc *elec
2849 ) {
2850
2851 char tok[VMAX_BUFSIZE];
2852 BEMparm *bemparm = VNULL;
2853 PBEparm *pbeparm = VNULL;
2854 int rc;
2855
2856 /* Check the arguments */
2857 if (thee == VNULL) {
2858 Vnm_print(2, "NOsh: Got NULL thee!\n");
2859 return 0;
2860 }
2861 if (sock == VNULL) {
2862 Vnm_print(2, "NOsh: Got pointer to NULL socket!\n");
2863 return 0;
2864 }
2865 if (elec == VNULL) {
2866 Vnm_print(2, "NOsh: Got pointer to NULL elec object!\n");
2867 return 0;
2868 }
2869 bemparm = elec->bemparm;
2870 if (bemparm == VNULL) {
2871 Vnm_print(2, "NOsh: Got pointer to NULL bemparm object!\n");
2872 return 0;
2873 }
2874 pbeparm = elec->pbeparm;
2875 if (pbeparm == VNULL) {
2876 Vnm_print(2, "NOsh: Got pointer to NULL pbeparm object!\n");
2877 return 0;
2878 }
2879
2880 Vnm_print(0, "NOsh_parseBEM: Parsing parameters for BEM calculation\n");
2881
2882
2883 /* Start snarfing tokens from the input stream */
2884 rc = 1;
2885 while (Vio_scanf(sock, "%s", tok) == 1) {
2886
2887 Vnm_print(0, "NOsh_parseBEM: Parsing %s...\n", tok);
2888
2889 /* See if it's an END token */
2890 if (Vstring_strcasecmp(tok, "end") == 0) {
2891 bemparm->parsed = 1;
2892 pbeparm->parsed = 1;
2893 rc = 1;
2894 break;
2895 }
2896
2897 /* Pass the token through a series of parsers */
2898 rc = PBEparm_parseToken(pbeparm, tok, sock);
2899 if (rc == -1) {
2900 Vnm_print(0, "NOsh_parseBEM: parsePBE error!\n");
2901 break;
2902 } else if (rc == 0) {
2903 /* Pass the token to the generic BEM parser */
2904 rc = BEMparm_parseToken(bemparm, tok, sock);
2905 if (rc == -1) {
2906 Vnm_print(0, "NOsh_parseBEM: parseBEM error!\n");
2907 break;
2908 } else if (rc == 0) {
2909 /* We ran out of parsers! */
2910 Vnm_print(2, "NOsh: Unrecognized keyword: %s\n", tok);
2911 break;
2912 }
2913 }
2914 }
2915
2916 pbeparm->setsrfm=1; // unneeded srfm
2917 pbeparm->setpbetype=1; // unneeded pbe type
2918 pbeparm->setbcfl=1; // unneeded bcfl
2919
2920 /* Handle various errors arising in the token-snarfing loop -- these all
2921 just result in simple returns right now */
2922 if (rc == -1) return 0;
2923 if (rc == 0) return 0;
2924
2925 /* Check the status of the parameter objects */
2926 if ((BEMparm_check(bemparm) == VRC_FAILURE) || (!PBEparm_check(pbeparm))) {
2927 Vnm_print(2, "NOsh: BEM parameters not set correctly!\n");
2928 return 0;
2929 }
2930
2931 return 1;
2932 }
2933
NOsh_parseGEOFLOW(NOsh * thee,Vio * sock,NOsh_calc * elec)2934 VPUBLIC int NOsh_parseGEOFLOW(
2935 NOsh *thee,
2936 Vio *sock,
2937 NOsh_calc *elec
2938 ) {
2939
2940 char tok[VMAX_BUFSIZE];
2941 GEOFLOWparm *parm = VNULL;
2942 APOLparm *apolparm = VNULL;
2943 PBEparm *pbeparm = VNULL;
2944 int rc;
2945
2946 /* Check the arguments */
2947 if (thee == VNULL) {
2948 Vnm_print(2, "NOsh: Got NULL thee!\n");
2949 return 0;
2950 }
2951 if (sock == VNULL) {
2952 Vnm_print(2, "NOsh: Got pointer to NULL socket!\n");
2953 return 0;
2954 }
2955 if (elec == VNULL) {
2956 Vnm_print(2, "NOsh: Got pointer to NULL elec object!\n");
2957 return 0;
2958 }
2959 parm = elec->geoflowparm;
2960 if (parm == VNULL) {
2961 Vnm_print(2, "NOsh: Got pointer to NULL geoflowparm object!\n");
2962 return 0;
2963 }
2964 apolparm = elec->apolparm;
2965 if (parm == VNULL) {
2966 Vnm_print(2, "NOsh: Got pointer to NULL apolparm object!\n");
2967 return 0;
2968 }
2969 pbeparm = elec->pbeparm;
2970 if (pbeparm == VNULL) {
2971 Vnm_print(2, "NOsh: Got pointer to NULL pbeparm object!\n");
2972 return 0;
2973 }
2974
2975 Vnm_print(0, "NOsh_parseGEOFLOW: Parsing parameters for GEOFLOW calculation\n");
2976
2977
2978 /* Start snarfing tokens from the input stream */
2979 rc = 1;
2980 while (Vio_scanf(sock, "%s", tok) == 1) {
2981
2982 Vnm_print(0, "NOsh_parseGEOFLOW: Parsing %s...\n", tok);
2983
2984 /* See if it's an END token */
2985 if (Vstring_strcasecmp(tok, "end") == 0) {
2986 parm->parsed = 1;
2987 pbeparm->parsed = 1;
2988 apolparm->parsed = 1;
2989 rc = 1;
2990 break;
2991 }
2992
2993 if (Vstring_strcasecmp(tok, "ion") == 0) {
2994 Vnm_print(2, "parseGEOFLOW: WARNING! ion not implemented for geometric flow!\n");
2995 }
2996
2997 /* Pass the token through a series of parsers */
2998 rc = PBEparm_parseToken(pbeparm, tok, sock);
2999 if (rc == -1) {
3000 Vnm_print(0, "NOsh_parseGEOFLOW: parsePBE error!\n");
3001 break;
3002 } else if (rc == 0) {
3003 /* Pass the token to the generic GEOFLOW parser */
3004 rc = APOLparm_parseToken(apolparm, tok, sock);
3005 if (rc == -1) {
3006 Vnm_print(0, "NOsh_parseAPOL: parseAPOL error!\n");
3007 break;
3008 } else if (rc == 0) {
3009 rc = GEOFLOWparm_parseToken(parm, tok, sock);
3010 if (rc == -1) {
3011 Vnm_print(0, "NOsh_parseGEOFLOW: parseGEOFLOW error!\n");
3012 break;
3013 } else if (rc == 0) {
3014 /* We ran out of parsers! */
3015 Vnm_print(2, "NOsh: Unrecognized keyword: %s\n", tok);
3016 break;
3017 }
3018 }
3019 }
3020 }
3021
3022 pbeparm->setsrfm=1;
3023 pbeparm->srad=0.0;
3024 pbeparm->setsrad=1;
3025 pbeparm->settemp=1;
3026
3027 /* Handle various errors arising in the token-snarfing loop -- these all
3028 just result in simple returns right now */
3029 if (rc == -1) return 0;
3030 if (rc == 0) return 0;
3031
3032 /* Check the status of the parameter objects */
3033 if ((GEOFLOWparm_check(parm) == VRC_FAILURE) || (!PBEparm_check(pbeparm))) {
3034 Vnm_print(2, "NOsh: GEOFLOW parameters not set correctly!\n");
3035 return 0;
3036 }
3037 /*currently the only bc handle by geoflow is mdh so we check here if mdh was read*/
3038 if(pbeparm->bcfl != BCFL_MDH){
3039 Vnm_print(2, "NOsh_parseGEOFLOW: Geoflow currently only supports mdh boundary conditions!\n");
3040 Vnm_print(2, "NOsh_parseGEOFLOW: please change bcfl keyword.\n");
3041 return 0;
3042 }
3043
3044 return 1;
3045 }
3046
3047
NOsh_parsePBAM(NOsh * thee,Vio * sock,NOsh_calc * elec)3048 VPUBLIC int NOsh_parsePBAM(
3049 NOsh *thee,
3050 Vio *sock,
3051 NOsh_calc *elec
3052 ) {
3053
3054 char tok[VMAX_BUFSIZE];
3055 PBAMparm *parm = VNULL;
3056 PBEparm *pbeparm = VNULL;
3057 int rc;
3058
3059 /* Check the arguments */
3060 if (thee == VNULL) {
3061 Vnm_print(2, "NOsh: Got NULL thee!\n");
3062 return 0;
3063 }
3064 if (sock == VNULL) {
3065 Vnm_print(2, "NOsh: Got pointer to NULL socket!\n");
3066 return 0;
3067 }
3068 if (elec == VNULL) {
3069 Vnm_print(2, "NOsh: Got pointer to NULL elec object!\n");
3070 return 0;
3071 }
3072 parm = elec->pbamparm;
3073 if (parm == VNULL) {
3074 Vnm_print(2, "NOsh: Got pointer to NULL pbam object!\n");
3075 return 0;
3076 }
3077 pbeparm = elec->pbeparm;
3078 if (pbeparm == VNULL) {
3079 Vnm_print(2, "NOsh: Got pointer to NULL pbeparm object!\n");
3080 return 0;
3081 }
3082 Vnm_print(0, "NOsh_parsePBAM: Parsing parameters for PBAM calculation\n");
3083
3084 /* Start snarfing tokens from the input stream */
3085 rc = 1;
3086 while (Vio_scanf(sock, "%s", tok) == 1) {
3087
3088 Vnm_print(0, "NOsh_parsePBAM: Parsing %s...\n", tok);
3089
3090 /* See if it's an END token */
3091 if (Vstring_strcasecmp(tok, "end") == 0) {
3092 parm->parsed = 1;
3093 pbeparm->parsed = 1;
3094 rc = 1;
3095 break;
3096 }
3097
3098 if (Vstring_strcasecmp(tok, "ion") == 0) {
3099 Vnm_print(2, "parsePBAM: WARNING! PBAM only uses the conc parameter of ion!\n");
3100 }
3101
3102 /* Pass the token through a series of parsers */
3103 rc = PBEparm_parseToken(pbeparm, tok, sock);
3104 if (rc == -1) {
3105 Vnm_print(0, "NOsh_parsePBAM: parsePBE error!\n");
3106 break;
3107 } else if (rc == 0) {
3108 rc = PBAMparm_parseToken(parm, tok, sock);
3109 if (rc == -1) {
3110 Vnm_print(0, "NOsh_parsePBAM: parsePBAM error!\n");
3111 break;
3112 } else if (rc == 0) {
3113 /* We ran out of parsers! */
3114 Vnm_print(2, "NOsh: Unrecognized keyword: %s\n", tok);
3115 break;
3116 }
3117 }
3118 }
3119
3120 pbeparm->setsrfm=1;
3121 pbeparm->setsrad=1;
3122 pbeparm->settemp=1; // do need temp, but have default, incase
3123 pbeparm->setmolid=1; // for unneeded mol flag
3124 pbeparm->setpbetype=1; // unneeded pbe type
3125 pbeparm->setbcfl=1; // unneeded bcfl
3126 pbeparm->setsdens=1;
3127
3128 //This is a hacky fix at best for issue 501. This is so we don't need to change PBAM's
3129 //external code.
3130 if(pbeparm->setnion){
3131 parm->salt = pbeparm->ionc[pbeparm->nion-1];
3132 parm->setsalt = 1;
3133 }
3134
3135 /* Handle various errors arising in the token-snarfing loop -- these all
3136 just result in simple returns right now */
3137 if (rc == -1) return 0;
3138 if (rc == 0) return 0;
3139
3140 /* Check the status of the parameter objects */
3141 if ((PBAMparm_check(parm) == VRC_FAILURE) || (!PBEparm_check(pbeparm))) {
3142 Vnm_print(2, "NOsh: PBAM parameters not set correctly!\n");
3143 return 0;
3144 }
3145 return 1;
3146 }
3147
NOsh_parsePBSAM(NOsh * thee,Vio * sock,NOsh_calc * elec)3148 VPUBLIC int NOsh_parsePBSAM(
3149 NOsh *thee,
3150 Vio *sock,
3151 NOsh_calc *elec
3152 ) {
3153
3154 char tok[VMAX_BUFSIZE];
3155 PBAMparm *parm = VNULL;
3156 PBSAMparm *samparm = VNULL;
3157 PBEparm *pbeparm = VNULL;
3158 int rc;
3159
3160 /* Check the arguments */
3161 if (thee == VNULL) {
3162 Vnm_print(2, "NOsh: Got NULL thee!\n");
3163 return 0;
3164 }
3165 if (sock == VNULL) {
3166 Vnm_print(2, "NOsh: Got pointer to NULL socket!\n");
3167 return 0;
3168 }
3169 if (elec == VNULL) {
3170 Vnm_print(2, "NOsh: Got pointer to NULL elec object!\n");
3171 return 0;
3172 }
3173 parm = elec->pbamparm;
3174 if (parm == VNULL) {
3175 Vnm_print(2, "NOsh: Got pointer to NULL pbam object!\n");
3176 return 0;
3177 }
3178 samparm = elec->pbsamparm;
3179 if (samparm == VNULL) {
3180 Vnm_print(2, "NOsh: Got pointer to NULL pbsam object!\n");
3181 return 0;
3182 }
3183 pbeparm = elec->pbeparm;
3184 if (pbeparm == VNULL) {
3185 Vnm_print(2, "NOsh: Got pointer to NULL pbeparm object!\n");
3186 return 0;
3187 }
3188 Vnm_print(0, "NOsh_parsePBSAM: Parsing parameters for PBSAM calculation\n");
3189
3190 /* Start snarfing tokens from the input stream */
3191 rc = 1;
3192 while (Vio_scanf(sock, "%s", tok) == 1) {
3193
3194 Vnm_print(0, "NOsh_parsePBSAM: Parsing %s...\n", tok);
3195
3196 /* See if it's an END token */
3197 if (Vstring_strcasecmp(tok, "end") == 0) {
3198 parm->parsed = 1;
3199 samparm->parsed = 1;
3200 pbeparm->parsed = 1;
3201 rc = 1;
3202 break;
3203 }
3204
3205 if (Vstring_strcasecmp(tok, "ion") == 0) {
3206 Vnm_print(2, "parsePBSAM: WARNING! PBAM only uses the conc parameter of ion!\n");
3207 }
3208
3209 /* Pass the token through a series of parsers */
3210 rc = PBEparm_parseToken(pbeparm, tok, sock);
3211 if (rc == -1) {
3212 Vnm_print(0, "NOsh_parsePBSAM: parsePBE error!\n");
3213 break;
3214 } else if (rc == 0) {
3215 rc = PBAMparm_parseToken(parm, tok, sock);
3216 if (rc == -1) {
3217 Vnm_print(0, "NOsh_parsePBSAM: parsePBAM error!\n");
3218 break;
3219 } else if ( rc == 0 ) {
3220 rc = PBSAMparm_parseToken(samparm, tok, sock);
3221 if (rc == -1) {
3222 Vnm_print(0, "NOsh_parsePBSAM: parsePBSAM error!\n");
3223 break;
3224 } else if (rc == 0) {
3225 /* We ran out of parsers! */
3226 Vnm_print(2, "NOsh: Unrecognized keyword: %s\n", tok);
3227 break;
3228 }
3229 }
3230 }
3231 }
3232
3233 pbeparm->setsrfm=1;
3234 pbeparm->setsrad=1;
3235 pbeparm->settemp=1; // do need temp, but have default, incase
3236 pbeparm->setmolid=1; // for unneeded mol flag
3237 pbeparm->setpbetype=1; // unneeded pbe type
3238 pbeparm->setbcfl=1; // unneeded bcfl
3239 pbeparm->setsdens=1;
3240
3241 //This is a hacky fix at best for issue 501. This is so we don't need to change PBAM's
3242 //external code.
3243 if(pbeparm->setnion){
3244 parm->salt = pbeparm->ionc[pbeparm->nion-1];
3245 parm->setsalt = 1;
3246 }
3247
3248 /* Handle various errors arising in the token-snarfing loop -- these all
3249 just result in simple returns right now */
3250 if (rc == -1) return 0;
3251 if (rc == 0) return 0;
3252
3253 /* Check the status of the parameter objects */
3254 if ((PBSAMparm_check(samparm)==VRC_FAILURE) ||
3255 (PBAMparm_check(parm) == VRC_FAILURE) ||
3256 (!PBEparm_check(pbeparm))) {
3257 Vnm_print(2, "NOsh: PBSAM parameters not set correctly!\n");
3258 return 0;
3259 }
3260 return 1;
3261 }
3262