00001
00050 #include "apbscfg.h"
00051 #include "apbs/nosh.h"
00052 #include "apbs/vstring.h"
00053 #include "apbs/mgparm.h"
00054 #include "apbs/femparm.h"
00055
00056 VEMBED(rcsid="$Id: nosh.c 1585 2010-05-13 16:21:17Z sdg0919 $")
00057
00058
00059 VPRIVATE int NOsh_parseREAD(
00060 NOsh *thee,
00061 Vio *sock);
00062
00063 VPRIVATE int NOsh_parsePRINT(
00064 NOsh *thee,
00065 Vio *sock);
00066
00067 VPRIVATE int NOsh_parseELEC(
00068 NOsh *thee,
00069 Vio *sock
00070 );
00071
00072 VPRIVATE int NOsh_parseAPOLAR(
00073 NOsh *thee,
00074 Vio *sock
00075 );
00076
00077 VEXTERNC int NOsh_parseFEM(
00078 NOsh *thee,
00079 Vio *sock,
00080 NOsh_calc *elec
00081 );
00082
00083 VEXTERNC int NOsh_parseMG(
00084 NOsh *thee,
00085 Vio *sock,
00086 NOsh_calc *elec
00087 );
00088
00089 VEXTERNC int NOsh_parseAPOL(
00090 NOsh *thee,
00091 Vio *sock,
00092 NOsh_calc *elec
00093 );
00094
00095 VPRIVATE int NOsh_setupCalcMG(
00096 NOsh *thee,
00097 NOsh_calc *elec
00098 );
00099
00100 VPRIVATE int NOsh_setupCalcMGAUTO(
00101 NOsh *thee,
00102 NOsh_calc *elec
00103 );
00104
00105 VPRIVATE int NOsh_setupCalcMGMANUAL(
00106 NOsh *thee,
00107 NOsh_calc *elec
00108 );
00109
00110 VPRIVATE int NOsh_setupCalcMGPARA(
00111 NOsh *thee,
00112 NOsh_calc *elec
00113 );
00114
00115 VPRIVATE int NOsh_setupCalcFEM(
00116 NOsh *thee,
00117 NOsh_calc *elec
00118 );
00119
00120 VPRIVATE int NOsh_setupCalcFEMANUAL(
00121 NOsh *thee,
00122 NOsh_calc *elec
00123 );
00124
00125 VPRIVATE int NOsh_setupCalcAPOL(
00126 NOsh *thee,
00127 NOsh_calc *elec
00128 );
00129
00130 #if !defined(VINLINE_NOSH)
00131
00132 VPUBLIC char* NOsh_getMolpath(NOsh *thee, int imol) {
00133 VASSERT(thee != VNULL);
00134 VASSERT(imol < thee->nmol);
00135 return thee->molpath[imol];
00136 }
00137 VPUBLIC char* NOsh_getDielXpath(NOsh *thee, int imol) {
00138 VASSERT(thee != VNULL);
00139 VASSERT(imol < thee->nmol);
00140 return thee->dielXpath[imol];
00141 }
00142 VPUBLIC char* NOsh_getDielYpath(NOsh *thee, int imol) {
00143 VASSERT(thee != VNULL);
00144 VASSERT(imol < thee->nmol);
00145 return thee->dielYpath[imol];
00146 }
00147 VPUBLIC char* NOsh_getDielZpath(NOsh *thee, int imol) {
00148 VASSERT(thee != VNULL);
00149 VASSERT(imol < thee->nmol);
00150 return thee->dielZpath[imol];
00151 }
00152 VPUBLIC char* NOsh_getKappapath(NOsh *thee, int imol) {
00153 VASSERT(thee != VNULL);
00154 VASSERT(imol < thee->nmol);
00155 return thee->kappapath[imol];
00156 }
00157 VPUBLIC char* NOsh_getPotpath(NOsh *thee, int imol) {
00158 VASSERT(thee != VNULL);
00159 VASSERT(imol < thee->nmol);
00160 return thee->potpath[imol];
00161 }
00162 VPUBLIC char* NOsh_getChargepath(NOsh *thee, int imol) {
00163 VASSERT(thee != VNULL);
00164 VASSERT(imol < thee->nmol);
00165 return thee->chargepath[imol];
00166 }
00167 VPUBLIC NOsh_calc* NOsh_getCalc(NOsh *thee, int icalc) {
00168 VASSERT(thee != VNULL);
00169 VASSERT(icalc < thee->ncalc);
00170 return thee->calc[icalc];
00171 }
00172 VPUBLIC int NOsh_getDielfmt(NOsh *thee, int i) {
00173 VASSERT(thee != VNULL);
00174 VASSERT(i < thee->ndiel);
00175 return (thee->dielfmt[i]);
00176 }
00177 VPUBLIC int NOsh_getKappafmt(NOsh *thee, int i) {
00178 VASSERT(thee != VNULL);
00179 VASSERT(i < thee->nkappa);
00180 return (thee->kappafmt[i]);
00181 }
00182 VPUBLIC int NOsh_getPotfmt(NOsh *thee, int i) {
00183 VASSERT(thee != VNULL);
00184 VASSERT(i < thee->npot);
00185 return (thee->potfmt[i]);
00186 }
00187 VPUBLIC int NOsh_getChargefmt(NOsh *thee, int i) {
00188 VASSERT(thee != VNULL);
00189 VASSERT(i < thee->ncharge);
00190 return (thee->chargefmt[i]);
00191 }
00192
00193
00194 #endif
00195
00196 VPUBLIC NOsh_PrintType NOsh_printWhat(NOsh *thee, int iprint) {
00197 VASSERT(thee != VNULL);
00198 VASSERT(iprint < thee->nprint);
00199 return thee->printwhat[iprint];
00200 }
00201
00202 VPUBLIC int NOsh_printNarg(NOsh *thee, int iprint) {
00203 VASSERT(thee != VNULL);
00204 VASSERT(iprint < thee->nprint);
00205 return thee->printnarg[iprint];
00206 }
00207
00208 VPUBLIC int NOsh_elec2calc(NOsh *thee, int icalc) {
00209 VASSERT(thee != VNULL);
00210 VASSERT(icalc < thee->ncalc);
00211 return thee->elec2calc[icalc];
00212 }
00213
00214 VPUBLIC int NOsh_apol2calc(NOsh *thee, int icalc) {
00215 VASSERT(thee != VNULL);
00216 VASSERT(icalc < thee->ncalc);
00217 return thee->apol2calc[icalc];
00218 }
00219
00220 VPUBLIC char* NOsh_elecname(NOsh *thee, int ielec) {
00221 VASSERT(thee != VNULL);
00222 VASSERT(ielec < thee->nelec + 1);
00223 return thee->elecname[ielec];
00224 }
00225
00226 VPUBLIC int NOsh_printOp(NOsh *thee, int iprint, int iarg) {
00227 VASSERT(thee != VNULL);
00228 VASSERT(iprint < thee->nprint);
00229 VASSERT(iarg < thee->printnarg[iprint]);
00230 return thee->printop[iprint][iarg];
00231 }
00232
00233 VPUBLIC int NOsh_printCalc(NOsh *thee, int iprint, int iarg) {
00234 VASSERT(thee != VNULL);
00235 VASSERT(iprint < thee->nprint);
00236 VASSERT(iarg < thee->printnarg[iprint]);
00237 return thee->printcalc[iprint][iarg];
00238 }
00239
00240 VPUBLIC NOsh* NOsh_ctor(int rank, int size) {
00241
00242
00243 NOsh *thee = VNULL;
00244 thee = Vmem_malloc(VNULL, 1, sizeof(NOsh) );
00245 VASSERT( thee != VNULL);
00246 VASSERT( NOsh_ctor2(thee, rank, size) );
00247
00248 return thee;
00249 }
00250
00251 VPUBLIC int NOsh_ctor2(NOsh *thee, int rank, int size) {
00252
00253 int i;
00254
00255 if (thee == VNULL) return 0;
00256
00257 thee->proc_rank = rank;
00258 thee->proc_size = size;
00259
00260 thee->ispara = 0;
00261 thee->parsed = 0;
00262
00263 thee->nmol = 0;
00264 thee->gotparm = 0;
00265 thee->ncharge = 0;
00266 thee->ndiel = 0;
00267 thee->nkappa = 0;
00268 thee->npot = 0;
00269 thee->nprint = 0;
00270
00271 for (i=0; i<NOSH_MAXCALC; i++) {
00272 thee->calc[i] = VNULL;
00273 thee->elec[i] = VNULL;
00274 thee->apol[i] = VNULL;
00275 }
00276 for (i=0; i<NOSH_MAXMOL; i++) {
00277 thee->alist[i] = VNULL;
00278 }
00279 thee->ncalc = 0;
00280 thee->nelec = 0;
00281 thee->napol = 0;
00282
00283 return 1;
00284 }
00285
00286 VPUBLIC void NOsh_dtor(NOsh **thee) {
00287 if ((*thee) != VNULL) {
00288 NOsh_dtor2(*thee);
00289 Vmem_free(VNULL, 1, sizeof(NOsh), (void **)thee);
00290 (*thee) = VNULL;
00291 }
00292 }
00293
00294 VPUBLIC void NOsh_dtor2(NOsh *thee) {
00295
00296 int i;
00297
00298 if (thee != VNULL) {
00299 for (i=0; i<(thee->ncalc); i++) NOsh_calc_dtor(&(thee->calc[i]));
00300 for (i=0; i<(thee->nelec); i++) NOsh_calc_dtor(&(thee->elec[i]));
00301 for (i=0; i<(thee->napol); i++) NOsh_calc_dtor(&(thee->apol[i]));
00302 }
00303
00304 }
00305
00306 VPUBLIC NOsh_calc* NOsh_calc_ctor(
00307 NOsh_CalcType calctype
00308 ) {
00309 NOsh_calc *thee;
00310 thee = (NOsh_calc *)Vmem_malloc(VNULL, 1, sizeof(NOsh_calc));
00311 thee->calctype = calctype;
00312 switch (calctype) {
00313 case NCT_MG:
00314 thee->mgparm = MGparm_ctor(MCT_NONE);
00315 thee->femparm = VNULL;
00316 thee->apolparm = VNULL;
00317 break;
00318 case NCT_FEM:
00319 thee->mgparm = VNULL;
00320 thee->femparm = FEMparm_ctor(FCT_NONE);
00321 thee->apolparm = VNULL;
00322 break;
00323 case NCT_APOL:
00324 thee->mgparm = VNULL;
00325 thee->femparm = VNULL;
00326 thee->apolparm = APOLparm_ctor();
00327 break;
00328 default:
00329 Vnm_print(2, "NOsh_calc_ctor: unknown calculation type (%d)!\n",
00330 calctype);
00331 VASSERT(0);
00332 }
00333 thee->pbeparm = PBEparm_ctor();
00334
00335 return thee;
00336 }
00337
00338 VPUBLIC void NOsh_calc_dtor(
00339 NOsh_calc **thee
00340 ) {
00341
00342 NOsh_calc *calc = VNULL;
00343 calc = *thee;
00344 if (calc == VNULL) return;
00345
00346 switch (calc->calctype) {
00347 case NCT_MG:
00348 MGparm_dtor(&(calc->mgparm));
00349 break;
00350 case NCT_FEM:
00351 FEMparm_dtor(&(calc->femparm));
00352 break;
00353 case NCT_APOL:
00354 APOLparm_dtor(&(calc->apolparm));
00355 break;
00356 default:
00357 Vnm_print(2, "NOsh_calc_ctor: unknown calculation type (%d)!\n",
00358 calc->calctype);
00359 VASSERT(0);
00360 }
00361 PBEparm_dtor(&(calc->pbeparm));
00362
00363 Vmem_free(VNULL, 1, sizeof(NOsh_calc), (void **)thee);
00364 calc = VNULL;
00365
00366 }
00367
00368 VPUBLIC int NOsh_calc_copy(
00369 NOsh_calc *thee,
00370 NOsh_calc *source
00371 ) {
00372
00373 VASSERT(thee != VNULL);
00374 VASSERT(source != VNULL);
00375 VASSERT(thee->calctype == source->calctype);
00376 if (source->mgparm != VNULL)
00377 MGparm_copy(thee->mgparm, source->mgparm);
00378 if (source->femparm != VNULL)
00379 FEMparm_copy(thee->femparm, source->femparm);
00380 if (source->pbeparm != VNULL)
00381 PBEparm_copy(thee->pbeparm, source->pbeparm);
00382 if (source->apolparm != VNULL)
00383 APOLparm_copy(thee->apolparm, source->apolparm);
00384
00385 return 1;
00386
00387 }
00388
00389 VPUBLIC int NOsh_parseInputFile(
00390 NOsh *thee,
00391 char *filename
00392 ) {
00393
00394 Vio *sock;
00395 int rc;
00396
00397 sock = Vio_ctor("FILE", "ASC", VNULL, filename, "r");
00398 rc = NOsh_parseInput(thee, sock);
00399 Vio_dtor(&sock);
00400
00401 return rc;
00402 }
00403
00404 VPUBLIC int NOsh_parseInput(
00405 NOsh *thee,
00406 Vio *sock
00407 ) {
00408
00409 char *MCwhiteChars = " =,;\t\r\n";
00410 char *MCcommChars = "#%";
00411 char tok[VMAX_BUFSIZE];
00412
00413 if (thee == VNULL) {
00414 Vnm_print(2, "NOsh_parseInput: Got NULL thee!\n");
00415 return 0;
00416 }
00417
00418 if (sock == VNULL) {
00419 Vnm_print(2, "NOsh_parseInput: Got pointer to NULL socket!\n");
00420 Vnm_print(2, "NOsh_parseInput: The specified input file was not found!\n");
00421 return 0;
00422 }
00423
00424 if (thee->parsed) {
00425 Vnm_print(2, "NOsh_parseInput: Already parsed an input file!\n");
00426 return 0;
00427 }
00428
00429 if (Vio_accept(sock, 0) < 0) {
00430 Vnm_print(2, "NOsh_parseInput: Problem reading from socket!\n");
00431 return 0;
00432 }
00433
00434
00435 Vio_setWhiteChars(sock, MCwhiteChars);
00436 Vio_setCommChars(sock, MCcommChars);
00437
00438
00439 Vnm_print(0, "NOsh_parseInput: Starting file parsing...\n");
00440 while (Vio_scanf(sock, "%s", tok) == 1) {
00441
00442
00443
00444
00445
00446
00447
00448
00449
00450
00451
00452
00453
00454
00455 if (Vstring_strcasecmp(tok, "read") == 0) {
00456 Vnm_print(0, "NOsh: Parsing READ section\n");
00457 if (!NOsh_parseREAD(thee, sock)) return 0;
00458 Vnm_print(0, "NOsh: Done parsing READ section \
00459 (nmol=%d, ndiel=%d, nkappa=%d, ncharge=%d, npot=%d)\n", thee->nmol, thee->ndiel,
00460 thee->nkappa, thee->ncharge,thee->npot);
00461 } else if (Vstring_strcasecmp(tok, "print") == 0) {
00462 Vnm_print(0, "NOsh: Parsing PRINT section\n");
00463 if (!NOsh_parsePRINT(thee, sock)) return 0;
00464 Vnm_print(0, "NOsh: Done parsing PRINT section\n");
00465 } else if (Vstring_strcasecmp(tok, "elec") == 0) {
00466 Vnm_print(0, "NOsh: Parsing ELEC section\n");
00467 if (!NOsh_parseELEC(thee, sock)) return 0;
00468 Vnm_print(0, "NOsh: Done parsing ELEC section (nelec = %d)\n",
00469 thee->nelec);
00470 } else if (Vstring_strcasecmp(tok, "apolar") == 0) {
00471 Vnm_print(0, "NOsh: Parsing APOLAR section\n");
00472 if (!NOsh_parseAPOLAR(thee, sock)) return 0;
00473 Vnm_print(0, "NOsh: Done parsing APOLAR section (nelec = %d)\n",
00474 thee->nelec);
00475 } else if (Vstring_strcasecmp(tok, "quit") == 0) {
00476 Vnm_print(0, "NOsh: Done parsing file (got QUIT)\n");
00477 break;
00478 } else {
00479 Vnm_print(2, "NOsh_parseInput: Ignoring undefined keyword %s!\n", tok);
00480 }
00481 }
00482
00483 thee->parsed = 1;
00484 return 1;
00485
00486 }
00487
00488 VPRIVATE int NOsh_parseREAD_MOL(NOsh *thee, Vio *sock) {
00489
00490 char tok[VMAX_BUFSIZE], str[VMAX_BUFSIZE]="", strnew[VMAX_BUFSIZE]="";
00491 NOsh_MolFormat molfmt;
00492
00493 VJMPERR1(Vio_scanf(sock, "%s", tok) == 1);
00494 if (Vstring_strcasecmp(tok, "pqr") == 0) {
00495 molfmt = NMF_PQR;
00496 VJMPERR1(Vio_scanf(sock, "%s", tok) == 1);
00497 if (tok[0]=='"') {
00498 strcpy(strnew, "");
00499 while (tok[strlen(tok)-1] != '"') {
00500 strcat(str, tok);
00501 strcat(str, " ");
00502 VJMPERR1(Vio_scanf(sock, "%s", tok) == 1);
00503 }
00504 strcat(str, tok);
00505 strncpy(strnew, str+1, strlen(str)-2);
00506 strcpy(tok, strnew);
00507 }
00508 Vnm_print(0, "NOsh: Storing molecule %d path %s\n",
00509 thee->nmol, tok);
00510 thee->molfmt[thee->nmol] = molfmt;
00511 strncpy(thee->molpath[thee->nmol], tok, VMAX_ARGLEN);
00512 (thee->nmol)++;
00513 } else if (Vstring_strcasecmp(tok, "pdb") == 0) {
00514 molfmt = NMF_PDB;
00515 VJMPERR1(Vio_scanf(sock, "%s", tok) == 1);
00516 if (tok[0]=='"') {
00517 strcpy(strnew, "");
00518 while (tok[strlen(tok)-1] != '"') {
00519 strcat(str, tok);
00520 strcat(str, " ");
00521 VJMPERR1(Vio_scanf(sock, "%s", tok) == 1);
00522 }
00523 strcat(str, tok);
00524 strncpy(strnew, str+1, strlen(str)-2);
00525 strcpy(tok, strnew);
00526 }
00527 Vnm_print(0, "NOsh: Storing molecule %d path %s\n",
00528 thee->nmol, tok);
00529 thee->molfmt[thee->nmol] = molfmt;
00530 strncpy(thee->molpath[thee->nmol], tok, VMAX_ARGLEN);
00531 (thee->nmol)++;
00532 } else if (Vstring_strcasecmp(tok, "xml") == 0) {
00533 molfmt = NMF_XML;
00534 VJMPERR1(Vio_scanf(sock, "%s", tok) == 1);
00535 if (tok[0]=='"') {
00536 strcpy(strnew, "");
00537 while (tok[strlen(tok)-1] != '"') {
00538 strcat(str, tok);
00539 strcat(str, " ");
00540 VJMPERR1(Vio_scanf(sock, "%s", tok) == 1);
00541 }
00542 strcat(str, tok);
00543 strncpy(strnew, str+1, strlen(str)-2);
00544 strcpy(tok, strnew);
00545 }
00546 Vnm_print(0, "NOsh: Storing molecule %d path %s\n",
00547 thee->nmol, tok);
00548 thee->molfmt[thee->nmol] = molfmt;
00549 strncpy(thee->molpath[thee->nmol], tok, VMAX_ARGLEN);
00550 (thee->nmol)++;
00551 } else {
00552 Vnm_print(2, "NOsh_parseREAD: Ignoring undefined mol format \
00553 %s!\n", tok);
00554 }
00555
00556 return 1;
00557
00558
00559 VERROR1:
00560 Vnm_print(2, "NOsh_parseREAD_MOL: Ran out of tokens while parsing READ section!\n");
00561 return 0;
00562
00563 }
00564
00565 VPRIVATE int NOsh_parseREAD_PARM(NOsh *thee, Vio *sock) {
00566
00567 char tok[VMAX_BUFSIZE], str[VMAX_BUFSIZE]="", strnew[VMAX_BUFSIZE]="";
00568 NOsh_ParmFormat parmfmt;
00569
00570 VJMPERR1(Vio_scanf(sock, "%s", tok) == 1);
00571 if (Vstring_strcasecmp(tok, "flat") == 0) {
00572 parmfmt = NPF_FLAT;
00573 VJMPERR1(Vio_scanf(sock, "%s", tok) == 1);
00574 if (tok[0]=='"') {
00575 strcpy(strnew, "");
00576 while (tok[strlen(tok)-1] != '"') {
00577 strcat(str, tok);
00578 strcat(str, " ");
00579 VJMPERR1(Vio_scanf(sock, "%s", tok) == 1);
00580 }
00581 strcat(str, tok);
00582 strncpy(strnew, str+1, strlen(str)-2);
00583 strcpy(tok, strnew);
00584 }
00585 if (thee->gotparm) {
00586 Vnm_print(2, "NOsh: Hey! You already specified a parameterfile (%s)!\n", thee->parmpath);
00587 Vnm_print(2, "NOsh: I'm going to ignore this one (%s)!\n", tok);
00588 } else {
00589 thee->parmfmt = parmfmt;
00590 thee->gotparm = 1;
00591 strncpy(thee->parmpath, tok, VMAX_ARGLEN);
00592 }
00593 } else if(Vstring_strcasecmp(tok, "xml") == 0) {
00594 parmfmt = NPF_XML;
00595 VJMPERR1(Vio_scanf(sock, "%s", tok) == 1);
00596 if (tok[0]=='"') {
00597 strcpy(strnew, "");
00598 while (tok[strlen(tok)-1] != '"') {
00599 strcat(str, tok);
00600 strcat(str, " ");
00601 VJMPERR1(Vio_scanf(sock, "%s", tok) == 1);
00602 }
00603 strcat(str, tok);
00604 strncpy(strnew, str+1, strlen(str)-2);
00605 strcpy(tok, strnew);
00606 }
00607 if (thee->gotparm) {
00608 Vnm_print(2, "NOsh: Hey! You already specified a parameterfile (%s)!\n", thee->parmpath);
00609 Vnm_print(2, "NOsh: I'm going to ignore this one (%s)!\n", tok);
00610 } else {
00611 thee->parmfmt = parmfmt;
00612 thee->gotparm = 1;
00613 strncpy(thee->parmpath, tok, VMAX_ARGLEN);
00614 }
00615
00616 } else {
00617 Vnm_print(2, "NOsh_parseREAD: Ignoring undefined parm format \
00618 %s!\n", tok);
00619 }
00620
00621 return 1;
00622
00623 VERROR1:
00624 Vnm_print(2, "NOsh_parseREAD_PARM: Ran out of tokens while parsing READ section!\n");
00625 return 0;
00626
00627 }
00628
00629 VPRIVATE int NOsh_parseREAD_DIEL(NOsh *thee, Vio *sock) {
00630
00631 char tok[VMAX_BUFSIZE], str[VMAX_BUFSIZE]="", strnew[VMAX_BUFSIZE]="";
00632 Vdata_Format dielfmt;
00633
00634 VJMPERR1(Vio_scanf(sock, "%s", tok) == 1);
00635 if (Vstring_strcasecmp(tok, "dx") == 0) {
00636 dielfmt = VDF_DX;
00637 } else if (Vstring_strcasecmp(tok, "gz") == 0) {
00638 dielfmt = VDF_GZ;
00639 } else {
00640 Vnm_print(2, "NOsh_parseREAD: Ignoring undefined format \
00641 %s!\n", tok);
00642 return VRC_FAILURE;
00643 }
00644
00645 VJMPERR1(Vio_scanf(sock, "%s", tok) == 1);
00646 if (tok[0]=='"') {
00647 strcpy(strnew, "");
00648 while (tok[strlen(tok)-1] != '"') {
00649 strcat(str, tok);
00650 strcat(str, " ");
00651 VJMPERR1(Vio_scanf(sock, "%s", tok) == 1);
00652 }
00653 strcat(str, tok);
00654 strncpy(strnew, str+1, strlen(str)-2);
00655 strcpy(tok, strnew);
00656 }
00657 Vnm_print(0, "NOsh: Storing x-shifted dielectric map %d path \
00658 %s\n", thee->ndiel, tok);
00659 strncpy(thee->dielXpath[thee->ndiel], tok, VMAX_ARGLEN);
00660 VJMPERR1(Vio_scanf(sock, "%s", tok) == 1);
00661 Vnm_print(0, "NOsh: Storing y-shifted dielectric map %d path \
00662 %s\n", thee->ndiel, tok);
00663 strncpy(thee->dielYpath[thee->ndiel], tok, VMAX_ARGLEN);
00664 VJMPERR1(Vio_scanf(sock, "%s", tok) == 1);
00665 Vnm_print(0, "NOsh: Storing z-shifted dielectric map %d path \
00666 %s\n", thee->ndiel, tok);
00667 strncpy(thee->dielZpath[thee->ndiel], tok, VMAX_ARGLEN);
00668 thee->dielfmt[thee->ndiel] = dielfmt;
00669 (thee->ndiel)++;
00670
00671 return 1;
00672
00673 VERROR1:
00674 Vnm_print(2, "NOsh_parseREAD_DIEL: Ran out of tokens while parsing READ \
00675 section!\n");
00676 return 0;
00677
00678 }
00679
00680 VPRIVATE int NOsh_parseREAD_KAPPA(NOsh *thee, Vio *sock) {
00681
00682 char tok[VMAX_BUFSIZE], str[VMAX_BUFSIZE]="", strnew[VMAX_BUFSIZE]="";
00683 Vdata_Format kappafmt;
00684
00685 VJMPERR1(Vio_scanf(sock, "%s", tok) == 1);
00686 if (Vstring_strcasecmp(tok, "dx") == 0) {
00687 kappafmt = VDF_DX;
00688 } else if (Vstring_strcasecmp(tok, "gz") == 0) {
00689 kappafmt = VDF_GZ;
00690 } else {
00691 Vnm_print(2, "NOsh_parseREAD: Ignoring undefined format \
00692 %s!\n", tok);
00693 return VRC_FAILURE;
00694 }
00695
00696 VJMPERR1(Vio_scanf(sock, "%s", tok) == 1);
00697 if (tok[0]=='"') {
00698 strcpy(strnew, "");
00699 while (tok[strlen(tok)-1] != '"') {
00700 strcat(str, tok);
00701 strcat(str, " ");
00702 VJMPERR1(Vio_scanf(sock, "%s", tok) == 1);
00703 }
00704 strcat(str, tok);
00705 strncpy(strnew, str+1, strlen(str)-2);
00706 strcpy(tok, strnew);
00707 }
00708 Vnm_print(0, "NOsh: Storing kappa map %d path %s\n",
00709 thee->nkappa, tok);
00710 thee->kappafmt[thee->nkappa] = kappafmt;
00711 strncpy(thee->kappapath[thee->nkappa], tok, VMAX_ARGLEN);
00712 (thee->nkappa)++;
00713
00714 return 1;
00715
00716 VERROR1:
00717 Vnm_print(2, "NOsh_parseREAD: Ran out of tokens while parsing READ \
00718 section!\n");
00719 return 0;
00720
00721 }
00722
00723 VPRIVATE int NOsh_parseREAD_POTENTIAL(NOsh *thee, Vio *sock) {
00724
00725 char tok[VMAX_BUFSIZE], str[VMAX_BUFSIZE]="", strnew[VMAX_BUFSIZE]="";
00726 Vdata_Format potfmt;
00727
00728 VJMPERR1(Vio_scanf(sock, "%s", tok) == 1);
00729 if (Vstring_strcasecmp(tok, "dx") == 0) {
00730 potfmt = VDF_DX;
00731 } else if (Vstring_strcasecmp(tok, "gz") == 0) {
00732 potfmt = VDF_GZ;
00733 } else {
00734 Vnm_print(2, "NOsh_parseREAD: Ignoring undefined format \
00735 %s!\n", tok);
00736 return VRC_FAILURE;
00737 }
00738
00739 VJMPERR1(Vio_scanf(sock, "%s", tok) == 1);
00740 if (tok[0]=='"') {
00741 strcpy(strnew, "");
00742 while (tok[strlen(tok)-1] != '"') {
00743 strcat(str, tok);
00744 strcat(str, " ");
00745 VJMPERR1(Vio_scanf(sock, "%s", tok) == 1);
00746 }
00747 strcat(str, tok);
00748 strncpy(strnew, str+1, strlen(str)-2);
00749 strcpy(tok, strnew);
00750 }
00751 Vnm_print(0, "NOsh: Storing potential map %d path %s\n",
00752 thee->npot, tok);
00753 thee->potfmt[thee->npot] = potfmt;
00754 strncpy(thee->potpath[thee->npot], tok, VMAX_ARGLEN);
00755 (thee->npot)++;
00756
00757 return 1;
00758
00759 VERROR1:
00760 Vnm_print(2, "NOsh_parseREAD: Ran out of tokens while parsing READ \
00761 section!\n");
00762 return 0;
00763
00764 }
00765
00766 VPRIVATE int NOsh_parseREAD_CHARGE(NOsh *thee, Vio *sock) {
00767
00768 char tok[VMAX_BUFSIZE], str[VMAX_BUFSIZE]="", strnew[VMAX_BUFSIZE]="";
00769 Vdata_Format chargefmt;
00770
00771 VJMPERR1(Vio_scanf(sock, "%s", tok) == 1);
00772 if (Vstring_strcasecmp(tok, "dx") == 0) {
00773 chargefmt = VDF_DX;
00774 } else if (Vstring_strcasecmp(tok, "gz") == 0) {
00775 chargefmt = VDF_GZ;
00776 } else {
00777 Vnm_print(2, "NOsh_parseREAD: Ignoring undefined format \
00778 %s!\n", tok);
00779 return VRC_FAILURE;
00780 }
00781
00782 VJMPERR1(Vio_scanf(sock, "%s", tok) == 1);
00783 if (tok[0]=='"') {
00784 strcpy(strnew, "");
00785 while (tok[strlen(tok)-1] != '"') {
00786 strcat(str, tok);
00787 strcat(str, " ");
00788 VJMPERR1(Vio_scanf(sock, "%s", tok) == 1);
00789 }
00790 strcat(str, tok);
00791 strncpy(strnew, str+1, strlen(str)-2);
00792 strcpy(tok, strnew);
00793 }
00794 Vnm_print(0, "NOsh: Storing charge map %d path %s\n",
00795 thee->ncharge, tok);
00796 thee->chargefmt[thee->ncharge] = chargefmt;
00797 strncpy(thee->chargepath[thee->ncharge], tok, VMAX_ARGLEN);
00798 (thee->ncharge)++;
00799
00800 return 1;
00801
00802 VERROR1:
00803 Vnm_print(2, "NOsh_parseREAD: Ran out of tokens while parsing READ \
00804 section!\n");
00805 return 0;
00806
00807 }
00808
00809 VPRIVATE int NOsh_parseREAD_MESH(NOsh *thee, Vio *sock) {
00810
00811 char tok[VMAX_BUFSIZE], str[VMAX_BUFSIZE]="", strnew[VMAX_BUFSIZE]="";
00812 Vdata_Format meshfmt;
00813
00814 VJMPERR1(Vio_scanf(sock, "%s", tok) == 1);
00815 if (Vstring_strcasecmp(tok, "mcsf") == 0) {
00816 meshfmt = VDF_MCSF;
00817 VJMPERR1(Vio_scanf(sock, "%s", tok) == 1);
00818 if (tok[0]=='"') {
00819 strcpy(strnew, "");
00820 while (tok[strlen(tok)-1] != '"') {
00821 strcat(str, tok);
00822 strcat(str, " ");
00823 VJMPERR1(Vio_scanf(sock, "%s", tok) == 1);
00824 }
00825 strcat(str, tok);
00826 strncpy(strnew, str+1, strlen(str)-2);
00827 strcpy(tok, strnew);
00828 }
00829 Vnm_print(0, "NOsh: Storing mesh %d path %s\n",
00830 thee->nmesh, tok);
00831 thee->meshfmt[thee->nmesh] = meshfmt;
00832 strncpy(thee->meshpath[thee->nmesh], tok, VMAX_ARGLEN);
00833 (thee->nmesh)++;
00834 } else {
00835 Vnm_print(2, "NOsh_parseREAD: Ignoring undefined mesh format \
00836 %s!\n", tok);
00837 }
00838
00839 return 1;
00840
00841 VERROR1:
00842 Vnm_print(2, "NOsh_parseREAD: Ran out of tokens while parsing READ \
00843 section!\n");
00844 return 0;
00845
00846 }
00847
00848
00849 VPRIVATE int NOsh_parseREAD(NOsh *thee, Vio *sock) {
00850
00851 char tok[VMAX_BUFSIZE];
00852
00853 if (thee == VNULL) {
00854 Vnm_print(2, "NOsh_parseREAD: Got NULL thee!\n");
00855 return 0;
00856 }
00857
00858 if (sock == VNULL) {
00859 Vnm_print(2, "NOsh_parseREAD: Got pointer to NULL socket!\n");
00860 return 0;
00861 }
00862
00863 if (thee->parsed) {
00864 Vnm_print(2, "NOsh_parseREAD: Already parsed an input file!\n");
00865 return 0;
00866 }
00867
00868
00869 while (Vio_scanf(sock, "%s", tok) == 1) {
00870 if (Vstring_strcasecmp(tok, "end") == 0) {
00871 Vnm_print(0, "NOsh: Done parsing READ section\n");
00872 return 1;
00873 } else if (Vstring_strcasecmp(tok, "mol") == 0) {
00874 NOsh_parseREAD_MOL(thee, sock);
00875 } else if (Vstring_strcasecmp(tok, "parm") == 0) {
00876 NOsh_parseREAD_PARM(thee,sock);
00877 } else if (Vstring_strcasecmp(tok, "diel") == 0) {
00878 NOsh_parseREAD_DIEL(thee,sock);
00879 } else if (Vstring_strcasecmp(tok, "kappa") == 0) {
00880 NOsh_parseREAD_KAPPA(thee,sock);
00881 } else if (Vstring_strcasecmp(tok, "pot") == 0) {
00882 NOsh_parseREAD_POTENTIAL(thee,sock);
00883 } else if (Vstring_strcasecmp(tok, "charge") == 0) {
00884 NOsh_parseREAD_CHARGE(thee,sock);
00885 } else if (Vstring_strcasecmp(tok, "mesh") == 0) {
00886 NOsh_parseREAD_MESH(thee,sock);
00887 } else {
00888 Vnm_print(2, "NOsh_parseREAD: Ignoring undefined keyword %s!\n",
00889 tok);
00890 }
00891 }
00892
00893
00894 Vnm_print(2, "NOsh_parseREAD: Ran out of tokens while parsing READ \
00895 section!\n");
00896 return 0;
00897
00898 }
00899
00900 VPRIVATE int NOsh_parsePRINT(NOsh *thee, Vio *sock) {
00901
00902 char tok[VMAX_BUFSIZE];
00903 char name[VMAX_BUFSIZE];
00904 int ti, idx, expect, ielec, iapol;
00905
00906 if (thee == VNULL) {
00907 Vnm_print(2, "NOsh_parsePRINT: Got NULL thee!\n");
00908 return 0;
00909 }
00910
00911 if (sock == VNULL) {
00912 Vnm_print(2, "NOsh_parsePRINT: Got pointer to NULL socket!\n");
00913 return 0;
00914 }
00915
00916 if (thee->parsed) {
00917 Vnm_print(2, "NOsh_parsePRINT: Already parsed an input file!\n");
00918 return 0;
00919 }
00920
00921 idx = thee->nprint;
00922 if (thee->nprint >= NOSH_MAXPRINT) {
00923 Vnm_print(2, "NOsh_parsePRINT: Exceeded max number (%d) of PRINT \
00924 sections\n",
00925 NOSH_MAXPRINT);
00926 return 0;
00927 }
00928
00929
00930
00931 VJMPERR1(Vio_scanf(sock, "%s", tok) == 1);
00932 if (Vstring_strcasecmp(tok, "energy") == 0) {
00933 thee->printwhat[idx] = NPT_ENERGY;
00934 thee->printnarg[idx] = 0;
00935 } else if (Vstring_strcasecmp(tok, "force") == 0) {
00936 thee->printwhat[idx] = NPT_FORCE;
00937 thee->printnarg[idx] = 0;
00938 } else if (Vstring_strcasecmp(tok, "elecEnergy") == 0) {
00939 thee->printwhat[idx] = NPT_ELECENERGY;
00940 thee->printnarg[idx] = 0;
00941 } else if (Vstring_strcasecmp(tok, "elecForce") == 0) {
00942 thee->printwhat[idx] = NPT_ELECFORCE;
00943 thee->printnarg[idx] = 0;
00944 } else if (Vstring_strcasecmp(tok, "apolEnergy") == 0) {
00945 thee->printwhat[idx] = NPT_APOLENERGY;
00946 thee->printnarg[idx] = 0;
00947 } else if (Vstring_strcasecmp(tok, "apolForce") == 0) {
00948 thee->printwhat[idx] = NPT_APOLFORCE;
00949 thee->printnarg[idx] = 0;
00950 } else {
00951 Vnm_print(2, "NOsh_parsePRINT: Undefined keyword %s while parsing \
00952 PRINT section!\n", tok);
00953 return 0;
00954 }
00955
00956 expect = 0;
00957
00958
00959 while (Vio_scanf(sock, "%s", tok) == 1) {
00960
00961
00962 if (Vstring_strcasecmp(tok, "end") == 0) {
00963 if (expect != 0) {
00964 (thee->nprint)++;
00965 (thee->printnarg[idx])++;
00966 Vnm_print(0, "NOsh: Done parsing PRINT section\n");
00967 return 1;
00968 } else {
00969 Vnm_print(2, "NOsh_parsePRINT: Got premature END to PRINT!\n");
00970 return 0;
00971 }
00972 } else {
00973
00974
00975 if ((sscanf(tok, "%d", &ti) == 1) &&
00976 (Vstring_isdigit(tok) == 1)) {
00977 if (expect == 0) {
00978 thee->printcalc[idx][thee->printnarg[idx]] = ti-1;
00979 expect = 1;
00980 } else {
00981 Vnm_print(2, "NOsh_parsePRINT: Syntax error in PRINT \
00982 section while reading %s!\n", tok);
00983 return 0;
00984 }
00985
00986 } else if (Vstring_strcasecmp(tok, "+") == 0) {
00987 if (expect == 1) {
00988 thee->printop[idx][thee->printnarg[idx]] = 0;
00989 (thee->printnarg[idx])++;
00990 expect = 0;
00991 if (thee->printnarg[idx] >= NOSH_MAXPOP) {
00992 Vnm_print(2, "NOsh_parsePRINT: Exceeded max number \
00993 (%d) of arguments for PRINT section!\n",
00994 NOSH_MAXPOP);
00995 return 0;
00996 }
00997 } else {
00998 Vnm_print(2, "NOsh_parsePRINT: Syntax error in PRINT \
00999 section while reading %s!\n", tok);
01000 return 0;
01001 }
01002
01003 } else if (Vstring_strcasecmp(tok, "-") == 0) {
01004 if (expect == 1) {
01005 thee->printop[idx][thee->printnarg[idx]] = 1;
01006 (thee->printnarg[idx])++;
01007 expect = 0;
01008 if (thee->printnarg[idx] >= NOSH_MAXPOP) {
01009 Vnm_print(2, "NOsh_parseREAD: Exceeded max number \
01010 (%d) of arguments for PRINT section!\n",
01011 NOSH_MAXPOP);
01012 return 0;
01013 }
01014 } else {
01015 Vnm_print(2, "NOsh_parsePRINT: Syntax error in PRINT \
01016 section while reading %s!\n", tok);
01017 return 0;
01018 }
01019
01020 } else if (sscanf(tok, "%s", name) == 1) {
01021 if (expect == 0) {
01022 for (ielec=0; ielec<thee->nelec; ielec++) {
01023 if (Vstring_strcasecmp(thee->elecname[ielec], name) == 0) {
01024 thee->printcalc[idx][thee->printnarg[idx]] = ielec;
01025 expect = 1;
01026 break;
01027 }
01028 }
01029 for (iapol=0; iapol<thee->napol; iapol++) {
01030 if (Vstring_strcasecmp(thee->apolname[iapol], name) == 0) {
01031 thee->printcalc[idx][thee->printnarg[idx]] = iapol;
01032 expect = 1;
01033 break;
01034 }
01035 }
01036 if (expect == 0) {
01037 Vnm_print(2, "No ELEC or APOL statement has been named %s!\n",
01038 name);
01039 return 0;
01040 }
01041 } else {
01042 Vnm_print(2, "NOsh_parsePRINT: Syntax error in PRINT \
01043 section while reading %s!\n", tok);
01044 return 0;
01045 }
01046
01047 } else {
01048 Vnm_print(2, "NOsh_parsePRINT: Undefined keyword %s while \
01049 parsing PRINT section!\n", tok);
01050 return 0;
01051 }
01052 }
01053
01054 }
01055
01056 VJMPERR1(0);
01057
01058
01059 VERROR1:
01060 Vnm_print(2, "NOsh_parsePRINT: Ran out of tokens while parsing PRINT \
01061 section!\n");
01062 return 0;
01063
01064 }
01065
01066 VPRIVATE int NOsh_parseELEC(NOsh *thee, Vio *sock) {
01067
01068 NOsh_calc *calc = VNULL;
01069
01070 char tok[VMAX_BUFSIZE];
01071
01072 if (thee == VNULL) {
01073 Vnm_print(2, "NOsh_parseELEC: Got NULL thee!\n");
01074 return 0;
01075 }
01076
01077 if (sock == VNULL) {
01078 Vnm_print(2, "NOsh_parseELEC: Got pointer to NULL socket!\n");
01079 return 0;
01080 }
01081
01082 if (thee->parsed) {
01083 Vnm_print(2, "NOsh_parseELEC: Already parsed an input file!\n");
01084 return 0;
01085 }
01086
01087
01088
01089 if (thee->nelec >= NOSH_MAXCALC) {
01090 Vnm_print(2, "NOsh: Too many electrostatics calculations in this \
01091 run!\n");
01092 Vnm_print(2, "NOsh: Current max is %d; ignoring this calculation\n",
01093 NOSH_MAXCALC);
01094 return 1;
01095 }
01096
01097
01098 if (Vio_scanf(sock, "%s", tok) == 1) {
01099 if (Vstring_strcasecmp(tok, "name") == 0) {
01100 Vio_scanf(sock, "%s", tok);
01101 strncpy(thee->elecname[thee->nelec], tok, VMAX_ARGLEN);
01102 if (Vio_scanf(sock, "%s", tok) != 1) {
01103 Vnm_print(2, "NOsh_parseELEC: Ran out of tokens while reading \
01104 ELEC section!\n");
01105 return 0;
01106 }
01107 }
01108 if (Vstring_strcasecmp(tok, "mg-manual") == 0) {
01109 thee->elec[thee->nelec] = NOsh_calc_ctor(NCT_MG);
01110 calc = thee->elec[thee->nelec];
01111 (thee->nelec)++;
01112 calc->mgparm->type = MCT_MANUAL;
01113 return NOsh_parseMG(thee, sock, calc);
01114 } else if (Vstring_strcasecmp(tok, "mg-auto") == 0) {
01115 thee->elec[thee->nelec] = NOsh_calc_ctor(NCT_MG);
01116 calc = thee->elec[thee->nelec];
01117 (thee->nelec)++;
01118 calc->mgparm->type = MCT_AUTO;
01119 return NOsh_parseMG(thee, sock, calc);
01120 } else if (Vstring_strcasecmp(tok, "mg-para") == 0) {
01121 thee->elec[thee->nelec] = NOsh_calc_ctor(NCT_MG);
01122 calc = thee->elec[thee->nelec];
01123 (thee->nelec)++;
01124 calc->mgparm->type = MCT_PARALLEL;
01125 return NOsh_parseMG(thee, sock, calc);
01126 } else if (Vstring_strcasecmp(tok, "mg-dummy") == 0) {
01127 thee->elec[thee->nelec] = NOsh_calc_ctor(NCT_MG);
01128 calc = thee->elec[thee->nelec];
01129 (thee->nelec)++;
01130 calc->mgparm->type = MCT_DUMMY;
01131 return NOsh_parseMG(thee, sock, calc);
01132 } else if (Vstring_strcasecmp(tok, "fe-manual") == 0) {
01133 thee->elec[thee->nelec] = NOsh_calc_ctor(NCT_FEM);
01134 calc = thee->elec[thee->nelec];
01135 (thee->nelec)++;
01136 calc->femparm->type = FCT_MANUAL;
01137 return NOsh_parseFEM(thee, sock, calc);
01138 } else {
01139 Vnm_print(2, "NOsh_parseELEC: The method (\"mg\" or \"fem\") or \
01140 \"name\" must be the first keyword in the ELEC section\n");
01141 return 0;
01142 }
01143 }
01144
01145 Vnm_print(2, "NOsh_parseELEC: Ran out of tokens while reading ELEC section!\n");
01146 return 0;
01147
01148 }
01149
01150 VPRIVATE int NOsh_parseAPOLAR(NOsh *thee, Vio *sock) {
01151
01152 NOsh_calc *calc = VNULL;
01153
01154 char tok[VMAX_BUFSIZE];
01155
01156 if (thee == VNULL) {
01157 Vnm_print(2, "NOsh_parseAPOLAR: Got NULL thee!\n");
01158 return 0;
01159 }
01160
01161 if (sock == VNULL) {
01162 Vnm_print(2, "NOsh_parseAPOLAR: Got pointer to NULL socket!\n");
01163 return 0;
01164 }
01165
01166 if (thee->parsed) {
01167 Vnm_print(2, "NOsh_parseAPOLAR: Already parsed an input file!\n");
01168 return 0;
01169 }
01170
01171
01172
01173 if (thee->napol >= NOSH_MAXCALC) {
01174 Vnm_print(2, "NOsh: Too many non-polar calculations in this \
01175 run!\n");
01176 Vnm_print(2, "NOsh: Current max is %d; ignoring this calculation\n",
01177 NOSH_MAXCALC);
01178 return 1;
01179 }
01180
01181
01182 if (Vio_scanf(sock, "%s", tok) == 1) {
01183 if (Vstring_strcasecmp(tok, "name") == 0) {
01184 Vio_scanf(sock, "%s", tok);
01185 strncpy(thee->apolname[thee->napol], tok, VMAX_ARGLEN);
01186
01187
01188 thee->apol[thee->napol] = NOsh_calc_ctor(NCT_APOL);
01189 calc = thee->apol[thee->napol];
01190 (thee->napol)++;
01191 return NOsh_parseAPOL(thee, sock, calc);
01192
01193 if (Vio_scanf(sock, "%s", tok) != 1) {
01194 Vnm_print(2, "NOsh_parseAPOLAR: Ran out of tokens while reading \
01195 APOLAR section!\n");
01196 return 0;
01197 }
01198 }
01199 }
01200
01201 return 1;
01202
01203 }
01204
01205 VPUBLIC int NOsh_setupElecCalc(
01206 NOsh *thee,
01207 Valist *alist[NOSH_MAXMOL]
01208 ) {
01209 int ielec, imol, i;
01210 NOsh_calc *elec = VNULL;
01211 MGparm *mgparm = VNULL;
01212 Valist *mymol = VNULL;
01213
01214 VASSERT(thee != VNULL);
01215 for (imol=0; imol<thee->nmol; imol++) {
01216 thee->alist[imol] = alist[imol];
01217 }
01218
01219
01220 for (ielec=0; ielec<(thee->nelec); ielec++) {
01221
01222 elec = thee->elec[ielec];
01223
01224 if (((thee->ndiel != 0) || (thee->nkappa != 0) ||
01225 (thee->ncharge != 0) || (thee->npot != 0)) &&
01226 (elec->pbeparm->calcforce != PCF_NO)) {
01227 Vnm_print(2, "NOsh_setupElecCalc: Calculation of forces disabled because surface \
01228 map is used!\n");
01229 elec->pbeparm->calcforce = PCF_NO;
01230 }
01231
01232
01233 switch (elec->calctype) {
01234 case NCT_MG:
01235
01236 mgparm = elec->mgparm;
01237 VASSERT(mgparm != VNULL);
01238 if (elec->mgparm->cmeth == MCM_MOLECULE) {
01239 VASSERT(mgparm->centmol >= 0);
01240 VASSERT(mgparm->centmol < thee->nmol);
01241 mymol = thee->alist[mgparm->centmol];
01242 VASSERT(mymol != VNULL);
01243 for (i=0; i<3; i++) {
01244 mgparm->center[i] = mymol->center[i];
01245 }
01246 }
01247 if (elec->mgparm->fcmeth == MCM_MOLECULE) {
01248 VASSERT(mgparm->fcentmol >= 0);
01249 VASSERT(mgparm->fcentmol < thee->nmol);
01250 mymol = thee->alist[mgparm->fcentmol];
01251 VASSERT(mymol != VNULL);
01252 for (i=0; i<3; i++) {
01253 mgparm->fcenter[i] = mymol->center[i];
01254 }
01255 }
01256 if (elec->mgparm->ccmeth == MCM_MOLECULE) {
01257 VASSERT(mgparm->ccentmol >= 0);
01258 VASSERT(mgparm->ccentmol < thee->nmol);
01259 mymol = thee->alist[mgparm->ccentmol];
01260 VASSERT(mymol != VNULL);
01261 for (i=0; i<3; i++) {
01262 mgparm->ccenter[i] = mymol->center[i];
01263 }
01264 }
01265 NOsh_setupCalcMG(thee, elec);
01266 break;
01267 case NCT_FEM:
01268 NOsh_setupCalcFEM(thee, elec);
01269 break;
01270 default:
01271 Vnm_print(2, "NOsh_setupCalc: Invalid calculation type (%d)!\n",
01272 elec->calctype);
01273 return 0;
01274 }
01275
01276
01277
01278
01279 thee->elec2calc[ielec] = thee->ncalc-1;
01280 Vnm_print(0, "NOsh_setupCalc: Mapping ELEC statement %d (%d) to \
01281 calculation %d (%d)\n", ielec, ielec+1, thee->elec2calc[ielec],
01282 thee->elec2calc[ielec]+1);
01283 }
01284
01285 return 1;
01286 }
01287
01288 VPUBLIC int NOsh_setupApolCalc(
01289 NOsh *thee,
01290 Valist *alist[NOSH_MAXMOL]
01291 ) {
01292 int iapol, imol;
01293 int doCalc = ACD_NO;
01294 NOsh_calc *calc = VNULL;
01295
01296 VASSERT(thee != VNULL);
01297 for (imol=0; imol<thee->nmol; imol++) {
01298 thee->alist[imol] = alist[imol];
01299 }
01300
01301 for (iapol=0; iapol<(thee->napol); iapol++) {
01302
01303 calc = thee->apol[iapol];
01304
01305
01306 switch (calc->calctype) {
01307 case NCT_APOL:
01308 NOsh_setupCalcAPOL(thee, calc);
01309 doCalc = ACD_YES;
01310 break;
01311 default:
01312 Vnm_print(2, "NOsh_setupCalc: Invalid calculation type (%d)!\n", calc->calctype);
01313 return ACD_ERROR;
01314 }
01315
01316
01317
01318 thee->apol2calc[iapol] = thee->ncalc-1;
01319 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);
01320 }
01321
01322 if(doCalc == ACD_YES){
01323 return ACD_YES;
01324 }else{
01325 return ACD_NO;
01326 }
01327 }
01328
01329 VPUBLIC int NOsh_parseMG(
01330 NOsh *thee,
01331 Vio *sock,
01332 NOsh_calc *elec
01333 ) {
01334
01335 char tok[VMAX_BUFSIZE];
01336 MGparm *mgparm = VNULL;
01337 PBEparm *pbeparm = VNULL;
01338 int rc;
01339
01340
01341 if (thee == VNULL) {
01342 Vnm_print(2, "NOsh: Got NULL thee!\n");
01343 return 0;
01344 }
01345 if (sock == VNULL) {
01346 Vnm_print(2, "NOsh: Got pointer to NULL socket!\n");
01347 return 0;
01348 }
01349 if (elec == VNULL) {
01350 Vnm_print(2, "NOsh: Got pointer to NULL elec object!\n");
01351 return 0;
01352 }
01353 mgparm = elec->mgparm;
01354 if (mgparm == VNULL) {
01355 Vnm_print(2, "NOsh: Got pointer to NULL mgparm object!\n");
01356 return 0;
01357 }
01358 pbeparm = elec->pbeparm;
01359 if (pbeparm == VNULL) {
01360 Vnm_print(2, "NOsh: Got pointer to NULL pbeparm object!\n");
01361 return 0;
01362 }
01363
01364 Vnm_print(0, "NOsh_parseMG: Parsing parameters for MG calculation\n");
01365
01366
01367 if (mgparm->type == MCT_PARALLEL) {
01368 mgparm->proc_rank = thee->proc_rank;
01369 mgparm->proc_size = thee->proc_size;
01370 mgparm->setrank = 1;
01371 mgparm->setsize = 1;
01372 }
01373
01374
01375
01376 rc = 1;
01377 while (Vio_scanf(sock, "%s", tok) == 1) {
01378
01379 Vnm_print(0, "NOsh_parseMG: Parsing %s...\n", tok);
01380
01381
01382 if (Vstring_strcasecmp(tok, "end") == 0) {
01383 mgparm->parsed = 1;
01384 pbeparm->parsed = 1;
01385 rc = 1;
01386 break;
01387 }
01388
01389
01390 rc = PBEparm_parseToken(pbeparm, tok, sock);
01391 if (rc == -1) {
01392 Vnm_print(0, "NOsh_parseMG: parsePBE error!\n");
01393 break;
01394 } else if (rc == 0) {
01395
01396 rc = MGparm_parseToken(mgparm, tok, sock);
01397 if (rc == -1) {
01398 Vnm_print(0, "NOsh_parseMG: parseMG error!\n");
01399 break;
01400 } else if (rc == 0) {
01401
01402 Vnm_print(2, "NOsh: Unrecognized keyword: %s\n", tok);
01403 break;
01404 }
01405 }
01406 }
01407
01408
01409
01410 if (rc == -1) return 0;
01411 if (rc == 0) return 0;
01412
01413
01414 if ((MGparm_check(mgparm) == VRC_FAILURE) || (!PBEparm_check(pbeparm))) {
01415 Vnm_print(2, "NOsh: MG parameters not set correctly!\n");
01416 return 0;
01417 }
01418
01419 return 1;
01420 }
01421
01422 VPRIVATE int NOsh_setupCalcMG(
01423 NOsh *thee,
01424 NOsh_calc *calc
01425 ) {
01426
01427 MGparm *mgparm = VNULL;
01428
01429 VASSERT(thee != VNULL);
01430 VASSERT(calc != VNULL);
01431 mgparm = calc->mgparm;
01432 VASSERT(mgparm != VNULL);
01433
01434
01435
01436
01437 switch (mgparm->type) {
01438 case MCT_MANUAL:
01439 return NOsh_setupCalcMGMANUAL(thee, calc);
01440 case MCT_DUMMY:
01441 return NOsh_setupCalcMGMANUAL(thee, calc);
01442 case MCT_AUTO:
01443 return NOsh_setupCalcMGAUTO(thee, calc);
01444 case MCT_PARALLEL:
01445 return NOsh_setupCalcMGPARA(thee, calc);
01446 default:
01447 Vnm_print(2, "NOsh_setupCalcMG: undefined MG calculation type (%d)!\n",
01448 mgparm->type);
01449 return 0;
01450 }
01451
01452
01453 return 0;
01454 }
01455
01456 VPRIVATE int NOsh_setupCalcFEM(
01457 NOsh *thee,
01458 NOsh_calc *calc
01459 ) {
01460
01461 VASSERT(thee != VNULL);
01462 VASSERT(calc != VNULL);
01463 VASSERT(calc->femparm != VNULL);
01464
01465
01466
01467 switch (calc->femparm->type) {
01468 case FCT_MANUAL:
01469 return NOsh_setupCalcFEMANUAL(thee, calc);
01470 default:
01471 Vnm_print(2, "NOsh_parseFEM: unknown calculation type (%d)!\n",
01472 calc->femparm->type);
01473 return 0;
01474 }
01475
01476
01477 return 0;
01478 }
01479
01480
01481 VPRIVATE int NOsh_setupCalcMGMANUAL(
01482 NOsh *thee,
01483 NOsh_calc *elec
01484 ) {
01485
01486 MGparm *mgparm = VNULL;
01487 PBEparm *pbeparm = VNULL;
01488 NOsh_calc *calc = VNULL;
01489
01490 if (thee == VNULL) {
01491 Vnm_print(2, "NOsh_setupCalcMGMANUAL: Got NULL thee!\n");
01492 return 0;
01493 }
01494 if (elec == VNULL) {
01495 Vnm_print(2, "NOsh_setupCalcMGMANUAL: Got NULL calc!\n");
01496 return 0;
01497 }
01498 mgparm = elec->mgparm;
01499 if (mgparm == VNULL) {
01500 Vnm_print(2, "NOsh_setupCalcMGMANUAL: Got NULL mgparm -- was this calculation \
01501 set up?\n");
01502 return 0;
01503 }
01504 pbeparm = elec->pbeparm;
01505 if (pbeparm == VNULL) {
01506 Vnm_print(2, "NOsh_setupCalcMGMANUAL: Got NULL pbeparm -- was this calculation \
01507 set up?\n");
01508 return 0;
01509 }
01510
01511
01512 if (mgparm->setgrid == 0) {
01513 VASSERT(mgparm->setglen);
01514 mgparm->grid[0] = mgparm->glen[0]/((double)(mgparm->dime[0]-1));
01515 mgparm->grid[1] = mgparm->glen[1]/((double)(mgparm->dime[1]-1));
01516 mgparm->grid[2] = mgparm->glen[2]/((double)(mgparm->dime[2]-1));
01517 }
01518 if (mgparm->setglen == 0) {
01519 VASSERT(mgparm->setgrid);
01520 mgparm->glen[0] = mgparm->grid[0]*((double)(mgparm->dime[0]-1));
01521 mgparm->glen[1] = mgparm->grid[1]*((double)(mgparm->dime[1]-1));
01522 mgparm->glen[2] = mgparm->grid[2]*((double)(mgparm->dime[2]-1));
01523 }
01524
01525
01526
01527
01528 if (thee->ncalc >= NOSH_MAXCALC) {
01529 Vnm_print(2, "NOsh: Too many calculations in this run!\n");
01530 Vnm_print(2, "NOsh: Current max is %d; ignoring this calculation\n",
01531 NOSH_MAXCALC);
01532 return 0;
01533 }
01534
01535
01536 thee->calc[thee->ncalc] = NOsh_calc_ctor(NCT_MG);
01537 calc = thee->calc[thee->ncalc];
01538 (thee->ncalc)++;
01539
01540
01541
01542
01543 NOsh_calc_copy(calc, elec);
01544
01545
01546 return 1;
01547 }
01548
01549 VPUBLIC int NOsh_setupCalcMGAUTO(
01550 NOsh *thee,
01551 NOsh_calc *elec
01552 ) {
01553
01554 NOsh_calc *calcf = VNULL;
01555 NOsh_calc *calcc = VNULL;
01556 double fgrid[3], cgrid[3];
01557 double d[3], minf[3], maxf[3], minc[3], maxc[3];
01558 double redfrac, redrat[3], td;
01559 int ifocus, nfocus, tnfocus[3];
01560 int j;
01561 int icalc;
01562 int dofix;
01563
01564
01565
01566
01567
01568
01569
01570
01571 if (thee == VNULL) {
01572 Vnm_print(2, "NOsh_setupCalcMGAUTO: Got NULL thee!\n");
01573 return 0;
01574 }
01575 if (elec == VNULL) {
01576 Vnm_print(2, "NOsh_setupCalcMGAUTO: Got NULL elec!\n");
01577 return 0;
01578 }
01579 if (elec->mgparm == VNULL) {
01580 Vnm_print(2, "NOsh_setupCalcMGAUTO: Got NULL mgparm!\n");
01581 return 0;
01582 }
01583 if (elec->pbeparm == VNULL) {
01584 Vnm_print(2, "NOsh_setupCalcMGAUTO: Got NULL pbeparm!\n");
01585 return 0;
01586 }
01587
01588 Vnm_print(0, "NOsh_setupCalcMGAUTO(%s, %d): coarse grid center = %g %g %g\n",
01589 __FILE__, __LINE__,
01590 elec->mgparm->ccenter[0],
01591 elec->mgparm->ccenter[1],
01592 elec->mgparm->ccenter[2]);
01593 Vnm_print(0, "NOsh_setupCalcMGAUTO(%s, %d): fine grid center = %g %g %g\n",
01594 __FILE__, __LINE__,
01595 elec->mgparm->fcenter[0],
01596 elec->mgparm->fcenter[1],
01597 elec->mgparm->fcenter[2]);
01598
01599
01600 for (j=0; j<3; j++) {
01601 cgrid[j] = (elec->mgparm->cglen[j])/((double)(elec->mgparm->dime[j]-1));
01602 fgrid[j] = (elec->mgparm->fglen[j])/((double)(elec->mgparm->dime[j]-1));
01603 d[j] = elec->mgparm->fcenter[j] - elec->mgparm->ccenter[j];
01604 }
01605 Vnm_print(0, "NOsh_setupCalcMGAUTO (%s, %d): Coarse grid spacing = %g, %g, %g\n",
01606 __FILE__, __LINE__, cgrid[0], cgrid[1], cgrid[2]);
01607 Vnm_print(0, "NOsh_setupCalcMGAUTO (%s, %d): Fine grid spacing = %g, %g, %g\n",
01608 __FILE__, __LINE__, fgrid[0], fgrid[1], fgrid[2]);
01609 Vnm_print(0, "NOsh_setupCalcMGAUTO (%s, %d): Displacement between fine and \
01610 coarse grids = %g, %g, %g\n", __FILE__, __LINE__, d[0], d[1], d[2]);
01611
01612
01613
01614 for (j=0; j<3; j++) {
01615 if (fgrid[j]/cgrid[j] < VREDFRAC) {
01616 redfrac = fgrid[j]/cgrid[j];
01617 td = log(redfrac)/log(VREDFRAC);
01618 tnfocus[j] = (int)ceil(td) + 1;
01619 } else tnfocus[j] = 2;
01620 }
01621 nfocus = VMAX2(VMAX2(tnfocus[0], tnfocus[1]), tnfocus[2]);
01622
01623
01624
01625 for (j=0; j<3; j++) {
01626 redrat[j] = VPOW((fgrid[j]/cgrid[j]), 1.0/((double)nfocus-1.0));
01627 }
01628 Vnm_print(0, "NOsh: %d levels of focusing with %g, %g, %g reductions\n",
01629 nfocus, redrat[0], redrat[1], redrat[2]);
01630
01631
01632
01633 if (nfocus > (NOSH_MAXCALC-(thee->ncalc))) {
01634 Vnm_print(2, "NOsh: Require more calculations than max (%d)!\n",
01635 NOSH_MAXCALC);
01636 return 0;
01637 }
01638
01639 for (ifocus=0; ifocus<nfocus; ifocus++) {
01640
01641
01642 icalc = thee->ncalc;
01643 thee->calc[icalc] = NOsh_calc_ctor(NCT_MG);
01644 (thee->ncalc)++;
01645
01646
01647 calcf = thee->calc[icalc];
01648
01649 if (ifocus != 0) {
01650 calcc = thee->calc[icalc-1];
01651 } else {
01652 calcc = VNULL;
01653 }
01654
01655
01656 NOsh_calc_copy(calcf, elec);
01657
01658
01659 if (ifocus == 0) {
01660 for (j=0; j<3; j++) {
01661 calcf->mgparm->grid[j] = cgrid[j];
01662 calcf->mgparm->glen[j] = elec->mgparm->cglen[j];
01663 }
01664 } else {
01665 for (j=0; j<3; j++) {
01666 calcf->mgparm->grid[j] = redrat[j]*(calcc->mgparm->grid[j]);
01667 calcf->mgparm->glen[j] = redrat[j]*(calcc->mgparm->glen[j]);
01668 }
01669 }
01670 calcf->mgparm->setgrid = 1;
01671 calcf->mgparm->setglen = 1;
01672
01673
01674 if (ifocus == 0) {
01675 calcf->mgparm->cmeth = elec->mgparm->ccmeth;
01676 calcf->mgparm->centmol = elec->mgparm->ccentmol;
01677 for (j=0; j<3; j++) {
01678 calcf->mgparm->center[j] = elec->mgparm->ccenter[j];
01679 }
01680 } else if (ifocus == (nfocus-1)) {
01681 calcf->mgparm->cmeth = elec->mgparm->fcmeth;
01682 calcf->mgparm->centmol = elec->mgparm->fcentmol;
01683 for (j=0; j<3; j++) {
01684 calcf->mgparm->center[j] = elec->mgparm->fcenter[j];
01685 }
01686 } else {
01687 calcf->mgparm->cmeth = MCM_FOCUS;
01688
01689
01690
01691
01692 for (j=0; j<3; j++) {
01693 calcf->mgparm->center[j] = elec->mgparm->fcenter[j];
01694 }
01695 }
01696
01697
01698
01699
01700
01701
01702 if (ifocus != 0) {
01703 Vnm_print(0, "NOsh_setupCalcMGAUTO (%s, %d): starting mesh \
01704 repositioning.\n", __FILE__, __LINE__);
01705 Vnm_print(0, "NOsh_setupCalcMGAUTO (%s, %d): coarse mesh center = \
01706 %g %g %g\n", __FILE__, __LINE__,
01707 calcc->mgparm->center[0],
01708 calcc->mgparm->center[1],
01709 calcc->mgparm->center[2]);
01710 Vnm_print(0, "NOsh_setupCalcMGAUTO (%s, %d): coarse mesh upper corner = \
01711 %g %g %g\n", __FILE__, __LINE__,
01712 calcc->mgparm->center[0]+0.5*(calcc->mgparm->glen[0]),
01713 calcc->mgparm->center[1]+0.5*(calcc->mgparm->glen[1]),
01714 calcc->mgparm->center[2]+0.5*(calcc->mgparm->glen[2]));
01715 Vnm_print(0, "NOsh_setupCalcMGAUTO (%s, %d): coarse mesh lower corner = \
01716 %g %g %g\n", __FILE__, __LINE__,
01717 calcc->mgparm->center[0]-0.5*(calcc->mgparm->glen[0]),
01718 calcc->mgparm->center[1]-0.5*(calcc->mgparm->glen[1]),
01719 calcc->mgparm->center[2]-0.5*(calcc->mgparm->glen[2]));
01720 Vnm_print(0, "NOsh_setupCalcMGAUTO (%s, %d): initial fine mesh upper corner = \
01721 %g %g %g\n", __FILE__, __LINE__,
01722 calcf->mgparm->center[0]+0.5*(calcf->mgparm->glen[0]),
01723 calcf->mgparm->center[1]+0.5*(calcf->mgparm->glen[1]),
01724 calcf->mgparm->center[2]+0.5*(calcf->mgparm->glen[2]));
01725 Vnm_print(0, "NOsh_setupCalcMGAUTO (%s, %d): initial fine mesh lower corner = \
01726 %g %g %g\n", __FILE__, __LINE__,
01727 calcf->mgparm->center[0]-0.5*(calcf->mgparm->glen[0]),
01728 calcf->mgparm->center[1]-0.5*(calcf->mgparm->glen[1]),
01729 calcf->mgparm->center[2]-0.5*(calcf->mgparm->glen[2]));
01730 for (j=0; j<3; j++) {
01731
01732 dofix = 0;
01733 minf[j] = calcf->mgparm->center[j]
01734 - 0.5*(calcf->mgparm->glen[j]);
01735 minc[j] = calcc->mgparm->center[j]
01736 - 0.5*(calcc->mgparm->glen[j]);
01737 d[j] = minc[j] - minf[j];
01738 if (d[j] >= VSMALL) {
01739 if (ifocus == (nfocus-1)) {
01740 Vnm_print(2, "NOsh_setupCalcMGAUTO: Error! Finest \
01741 mesh has fallen off the coarser meshes!\n");
01742 Vnm_print(2, "NOsh_setupCalcMGAUTO: difference in min %d-\
01743 direction = %g\n", j, d[j]);
01744 Vnm_print(2, "NOsh_setupCalcMGAUTO: min fine = %g %g %g\n",
01745 minf[0], minf[1], minf[2]);
01746 Vnm_print(2, "NOsh_setupCalcMGAUTO: min coarse = %g %g %g\n",
01747 minc[0], minc[1], minc[2]);
01748 VASSERT(0);
01749 } else {
01750 Vnm_print(0, "NOsh_setupCalcMGAUTO (%s, %d): ifocus = %d, \
01751 fixing mesh min violation (%g in %d-direction).\n", __FILE__, __LINE__, ifocus,
01752 d[j], j);
01753 calcf->mgparm->center[j] += d[j];
01754 dofix = 1;
01755 }
01756 }
01757
01758 maxf[j] = calcf->mgparm->center[j] \
01759 + 0.5*(calcf->mgparm->glen[j]);
01760 maxc[j] = calcc->mgparm->center[j] \
01761 + 0.5*(calcc->mgparm->glen[j]);
01762 d[j] = maxf[j] - maxc[j];
01763 if (d[j] >= VSMALL) {
01764 if (ifocus == (nfocus-1)) {
01765 Vnm_print(2, "NOsh_setupCalcMGAUTO: Error! Finest \
01766 mesh has fallen off the coarser meshes!\n");
01767 Vnm_print(2, "NOsh_setupCalcMGAUTO: difference in %d-\
01768 direction = %g\n", j, d[j]);
01769 VASSERT(0);
01770 } else {
01771
01772
01773 if (dofix) {
01774 Vnm_print(2, "NOsh_setupCalcMGAUTO: Error! Both \
01775 ends of the finer mesh do not fit in the bigger mesh!\n");
01776 VASSERT(0);
01777 }
01778 Vnm_print(0, "NOsh_setupCalcMGAUTO(%s, %d): ifocus = %d, \
01779 fixing mesh max violation (%g in %d-direction).\n", __FILE__, __LINE__, ifocus,
01780 d[j], j);
01781 calcf->mgparm->center[j] -= d[j];
01782 dofix = 1;
01783 }
01784 }
01785 }
01786 Vnm_print(0, "NOsh_setupCalcMGAUTO (%s, %d): final fine mesh upper corner = \
01787 %g %g %g\n", __FILE__, __LINE__,
01788 calcf->mgparm->center[0]+0.5*(calcf->mgparm->glen[0]),
01789 calcf->mgparm->center[1]+0.5*(calcf->mgparm->glen[1]),
01790 calcf->mgparm->center[2]+0.5*(calcf->mgparm->glen[2]));
01791 Vnm_print(0, "NOsh_setupCalcMGAUTO (%s, %d): final fine mesh lower corner = \
01792 %g %g %g\n", __FILE__, __LINE__,
01793 calcf->mgparm->center[0]-0.5*(calcf->mgparm->glen[0]),
01794 calcf->mgparm->center[1]-0.5*(calcf->mgparm->glen[1]),
01795 calcf->mgparm->center[2]-0.5*(calcf->mgparm->glen[2]));
01796 }
01797
01798
01799 if (ifocus != 0) calcf->pbeparm->bcfl = BCFL_FOCUS;
01800
01801
01802
01803 if (ifocus != (nfocus-1)) calcf->pbeparm->numwrite = 0;
01804
01805
01806 if (calcf->mgparm->type != MCT_PARALLEL) {
01807 Vnm_print(0, "NOsh_setupMGAUTO: Resetting boundary flags\n");
01808 for (j=0; j<6; j++) calcf->mgparm->partDisjOwnSide[j] = 0;
01809 for (j=0; j<3; j++) {
01810 calcf->mgparm->partDisjCenter[j] = 0;
01811 calcf->mgparm->partDisjLength[j] = calcf->mgparm->glen[j];
01812 }
01813 }
01814
01815
01816 calcf->mgparm->parsed = 1;
01817 }
01818
01819
01820 return 1;
01821 }
01822
01823
01824 VPUBLIC int NOsh_setupCalcMGPARA(
01825 NOsh *thee,
01826 NOsh_calc *elec
01827 ) {
01828
01829
01830
01831
01832 MGparm *mgparm = VNULL;
01833 double ofrac;
01834 double hx, hy, hzed;
01835 double xofrac, yofrac, zofrac;
01836 int rank, size, npx, npy, npz, nproc, ip, jp, kp;
01837 int xeffGlob, yeffGlob, zeffGlob, xDisj, yDisj, zDisj;
01838 int xigminDisj, xigmaxDisj, yigminDisj, yigmaxDisj, zigminDisj, zigmaxDisj;
01839 int xigminOlap, xigmaxOlap, yigminOlap, yigmaxOlap, zigminOlap, zigmaxOlap;
01840 int xOlapReg, yOlapReg, zOlapReg;
01841 double xlenDisj, ylenDisj, zlenDisj;
01842 double xcentDisj, ycentDisj, zcentDisj;
01843 double xcentOlap, ycentOlap, zcentOlap;
01844 double xlenOlap, ylenOlap, zlenOlap;
01845 double xminOlap, xmaxOlap, yminOlap, ymaxOlap, zminOlap, zmaxOlap;
01846 double xminDisj, xmaxDisj, yminDisj, ymaxDisj, zminDisj, zmaxDisj;
01847 double xcent, ycent, zcent;
01848
01849
01850 VASSERT(thee != VNULL);
01851 VASSERT(elec != VNULL);
01852 mgparm = elec->mgparm;
01853 VASSERT(mgparm != VNULL);
01854
01855
01856 ofrac = mgparm->ofrac;
01857 npx = mgparm->pdime[0];
01858 npy = mgparm->pdime[1];
01859 npz = mgparm->pdime[2];
01860 nproc = npx*npy*npz;
01861
01862
01863
01864 if (mgparm->setasync == 0) {
01865
01866 #ifndef HAVE_MPI_H
01867
01868 Vnm_tprint(2, "NOsh_setupCalcMGPARA: Oops! You're trying to perform \
01869 an 'mg-para' (parallel) calculation\n");
01870 Vnm_tprint(2, "NOsh_setupCalcMGPARA: with a version of APBS that wasn't \
01871 compiled with MPI!\n");
01872 Vnm_tprint(2, "NOsh_setupCalcMGPARA: Perhaps you meant to use the \
01873 'async' flag?\n");
01874 Vnm_tprint(2, "NOsh_setupCalcMGPARA: Bailing out!\n");
01875
01876 return 0;
01877
01878 #endif
01879
01880 rank = thee->proc_rank;
01881 size = thee->proc_size;
01882 Vnm_print(0, "NOsh_setupCalcMGPARA: Hello from processor %d of %d\n", rank,
01883 size);
01884
01885
01886
01887 if (rank > (nproc-1)) {
01888 Vnm_print(2, "NOsh_setupMGPARA: There are more processors available than\
01889 the %d you requested.\n", nproc);
01890 Vnm_print(2, "NOsh_setupMGPARA: Eliminating processor %d\n", rank);
01891 thee->bogus = 1;
01892 rank = 0;
01893 }
01894
01895
01896
01897 if (size < nproc) {
01898 Vnm_print(2, "NOsh_setupMGPARA: There are too few processors (%d) to \
01899 satisfy requirements (%d)\n", size, nproc);
01900 return 0;
01901 }
01902
01903 Vnm_print(0, "NOsh_setupMGPARA: Hello (again) from processor %d of %d\n",
01904 rank, size);
01905
01906 } else {
01907
01908 rank = mgparm->async;
01909
01910 thee->ispara = 1;
01911 thee->proc_rank = rank;
01912
01913
01914
01915 if (rank > (nproc-1)) {
01916 Vnm_print(2, "NOsh_setupMGPARA: The processor id you requested (%d) \
01917 is not within the range of processors available (0-%d)\n", rank, (nproc-1));
01918 return 0;
01919 }
01920 }
01921
01922
01923 kp = (int)floor(rank/(npx*npy));
01924 jp = (int)floor((rank-kp*npx*npy)/npx);
01925 ip = rank - kp*npx*npy - jp*npx;
01926 Vnm_print(0, "NOsh_setupMGPARA: Hello world from PE (%d, %d, %d)\n",
01927 ip, jp, kp);
01928
01929
01930 if (npx == 1) xofrac = 0.0;
01931 else xofrac = ofrac;
01932 if (npy == 1) yofrac = 0.0;
01933 else yofrac = ofrac;
01934 if (npz == 1) zofrac = 0.0;
01935 else zofrac = ofrac;
01936
01937
01938 xDisj = (int)VFLOOR(mgparm->dime[0]/(1 + 2*xofrac) + 0.5);
01939 xeffGlob = npx*xDisj;
01940 hx = mgparm->fglen[0]/(double)(xeffGlob-1);
01941 yDisj = (int)VFLOOR(mgparm->dime[1]/(1 + 2*yofrac) + 0.5);
01942 yeffGlob = npy*yDisj;
01943 hy = mgparm->fglen[1]/(double)(yeffGlob-1);
01944 zDisj = (int)VFLOOR(mgparm->dime[2]/(1 + 2*zofrac) + 0.5);
01945 zeffGlob = npz*zDisj;
01946 hzed = mgparm->fglen[2]/(double)(zeffGlob-1);
01947 Vnm_print(0, "NOsh_setupMGPARA: Global Grid size = (%d, %d, %d)\n",
01948 xeffGlob, yeffGlob, zeffGlob);
01949 Vnm_print(0, "NOsh_setupMGPARA: Global Grid Spacing = (%.3f, %.3f, %.3f)\n",
01950 hx, hy, hzed);
01951 Vnm_print(0, "NOsh_setupMGPARA: Processor Grid Size = (%d, %d, %d)\n",
01952 xDisj, yDisj, zDisj);
01953
01954
01955 xigminDisj = ip*xDisj;
01956 xigmaxDisj = xigminDisj + xDisj - 1;
01957 yigminDisj = jp*yDisj;
01958 yigmaxDisj = yigminDisj + yDisj - 1;
01959 zigminDisj = kp*zDisj;
01960 zigmaxDisj = zigminDisj + zDisj - 1;
01961 Vnm_print(0, "NOsh_setupMGPARA: Min Grid Points for this proc. (%d, %d, %d)\n",
01962 xigminDisj, yigminDisj, zigminDisj);
01963 Vnm_print(0, "NOsh_setupMGPARA: Max Grid Points for this proc. (%d, %d, %d)\n",
01964 xigmaxDisj, yigmaxDisj, zigmaxDisj);
01965
01966
01967
01968 xminDisj = VMAX2(hx*(xigminDisj-0.5), 0.0);
01969 xmaxDisj = VMIN2(hx*(xigmaxDisj+0.5), mgparm->fglen[0]);
01970 xlenDisj = xmaxDisj - xminDisj;
01971 yminDisj = VMAX2(hy*(yigminDisj-0.5), 0.0);
01972 ymaxDisj = VMIN2(hy*(yigmaxDisj+0.5), mgparm->fglen[1]);
01973 ylenDisj = ymaxDisj - yminDisj;
01974 zminDisj = VMAX2(hzed*(zigminDisj-0.5), 0.0);
01975 zmaxDisj = VMIN2(hzed*(zigmaxDisj+0.5), mgparm->fglen[2]);
01976 zlenDisj = zmaxDisj - zminDisj;
01977
01978 xcent = 0.5*mgparm->fglen[0];
01979 ycent = 0.5*mgparm->fglen[1];
01980 zcent = 0.5*mgparm->fglen[2];
01981
01982 xcentDisj = xminDisj + 0.5*xlenDisj - xcent;
01983 ycentDisj = yminDisj + 0.5*ylenDisj - ycent;
01984 zcentDisj = zminDisj + 0.5*zlenDisj - zcent;
01985 if (VABS(xcentDisj) < VSMALL) xcentDisj = 0.0;
01986 if (VABS(ycentDisj) < VSMALL) ycentDisj = 0.0;
01987 if (VABS(zcentDisj) < VSMALL) zcentDisj = 0.0;
01988
01989 Vnm_print(0, "NOsh_setupMGPARA: Disj part length = (%g, %g, %g)\n",
01990 xlenDisj, ylenDisj, zlenDisj);
01991 Vnm_print(0, "NOsh_setupMGPARA: Disj part center displacement = (%g, %g, %g)\n",
01992 xcentDisj, ycentDisj, zcentDisj);
01993
01994
01995 xOlapReg = 0;
01996 yOlapReg = 0;
01997 zOlapReg = 0;
01998 if (npx != 1) xOlapReg = (int)VFLOOR(xofrac*mgparm->fglen[0]/npx/hx + 0.5) + 1;
01999 if (npy != 1) yOlapReg = (int)VFLOOR(yofrac*mgparm->fglen[1]/npy/hy + 0.5) + 1;
02000 if (npz != 1) zOlapReg = (int)VFLOOR(zofrac*mgparm->fglen[2]/npz/hzed + 0.5) + 1;
02001
02002 Vnm_print(0, "NOsh_setupMGPARA: No. of Grid Points in Overlap (%d, %d, %d)\n",
02003 xOlapReg, yOlapReg, zOlapReg);
02004
02005 if (ip == 0) xigminOlap = 0;
02006 else if (ip == (npx - 1)) xigminOlap = xeffGlob - mgparm->dime[0];
02007 else xigminOlap = xigminDisj - xOlapReg;
02008 xigmaxOlap = xigminOlap + mgparm->dime[0] - 1;
02009
02010 if (jp == 0) yigminOlap = 0;
02011 else if (jp == (npy - 1)) yigminOlap = yeffGlob - mgparm->dime[1];
02012 else yigminOlap = yigminDisj - yOlapReg;
02013 yigmaxOlap = yigminOlap + mgparm->dime[1] - 1;
02014
02015 if (kp == 0) zigminOlap = 0;
02016 else if (kp == (npz - 1)) zigminOlap = zeffGlob - mgparm->dime[2];
02017 else zigminOlap = zigminDisj - zOlapReg;
02018 zigmaxOlap = zigminOlap + mgparm->dime[2] - 1;
02019
02020 Vnm_print(0, "NOsh_setupMGPARA: Min Grid Points with Overlap (%d, %d, %d)\n",
02021 xigminOlap, yigminOlap, zigminOlap);
02022 Vnm_print(0, "NOsh_setupMGPARA: Max Grid Points with Overlap (%d, %d, %d)\n",
02023 xigmaxOlap, yigmaxOlap, zigmaxOlap);
02024
02025 xminOlap = hx * xigminOlap;
02026 xmaxOlap = hx * xigmaxOlap;
02027 yminOlap = hy * yigminOlap;
02028 ymaxOlap = hy * yigmaxOlap;
02029 zminOlap = hzed * zigminOlap;
02030 zmaxOlap = hzed * zigmaxOlap;
02031
02032 xlenOlap = xmaxOlap - xminOlap;
02033 ylenOlap = ymaxOlap - yminOlap;
02034 zlenOlap = zmaxOlap - zminOlap;
02035
02036 xcentOlap = (xminOlap + 0.5*xlenOlap) - xcent;
02037 ycentOlap = (yminOlap + 0.5*ylenOlap) - ycent;
02038 zcentOlap = (zminOlap + 0.5*zlenOlap) - zcent;
02039 if (VABS(xcentOlap) < VSMALL) xcentOlap = 0.0;
02040 if (VABS(ycentOlap) < VSMALL) ycentOlap = 0.0;
02041 if (VABS(zcentOlap) < VSMALL) zcentOlap = 0.0;
02042
02043 Vnm_print(0, "NOsh_setupMGPARA: Olap part length = (%g, %g, %g)\n",
02044 xlenOlap, ylenOlap, zlenOlap);
02045 Vnm_print(0, "NOsh_setupMGPARA: Olap part center displacement = (%g, %g, %g)\n",
02046 xcentOlap, ycentOlap, zcentOlap);
02047
02048
02049
02050
02051
02052
02053 if (ip == 0) mgparm->partDisjOwnSide[VAPBS_LEFT] = 0;
02054 else mgparm->partDisjOwnSide[VAPBS_LEFT] = 1;
02055 if (ip == (npx-1)) mgparm->partDisjOwnSide[VAPBS_RIGHT] = 0;
02056 else mgparm->partDisjOwnSide[VAPBS_RIGHT] = 1;
02057 if (jp == 0) mgparm->partDisjOwnSide[VAPBS_BACK] = 0;
02058 else mgparm->partDisjOwnSide[VAPBS_BACK] = 1;
02059 if (jp == (npy-1)) mgparm->partDisjOwnSide[VAPBS_FRONT] = 0;
02060 else mgparm->partDisjOwnSide[VAPBS_FRONT] = 1;
02061 if (kp == 0) mgparm->partDisjOwnSide[VAPBS_DOWN] = 0;
02062 else mgparm->partDisjOwnSide[VAPBS_DOWN] = 1;
02063 if (kp == (npz-1)) mgparm->partDisjOwnSide[VAPBS_UP] = 0;
02064 else mgparm->partDisjOwnSide[VAPBS_UP] = 1;
02065
02066 Vnm_print(0, "NOsh_setupMGPARA: partDisjOwnSide[LEFT] = %d\n",
02067 mgparm->partDisjOwnSide[VAPBS_LEFT]);
02068 Vnm_print(0, "NOsh_setupMGPARA: partDisjOwnSide[RIGHT] = %d\n",
02069 mgparm->partDisjOwnSide[VAPBS_RIGHT]);
02070 Vnm_print(0, "NOsh_setupMGPARA: partDisjOwnSide[FRONT] = %d\n",
02071 mgparm->partDisjOwnSide[VAPBS_FRONT]);
02072 Vnm_print(0, "NOsh_setupMGPARA: partDisjOwnSide[BACK] = %d\n",
02073 mgparm->partDisjOwnSide[VAPBS_BACK]);
02074 Vnm_print(0, "NOsh_setupMGPARA: partDisjOwnSide[UP] = %d\n",
02075 mgparm->partDisjOwnSide[VAPBS_UP]);
02076 Vnm_print(0, "NOsh_setupMGPARA: partDisjOwnSide[DOWN] = %d\n",
02077 mgparm->partDisjOwnSide[VAPBS_DOWN]);
02078
02079
02080 mgparm->fglen[0] = xlenOlap;
02081 mgparm->fglen[1] = ylenOlap;
02082 mgparm->fglen[2] = zlenOlap;
02083 mgparm->partDisjLength[0] = xlenDisj;
02084 mgparm->partDisjLength[1] = ylenDisj;
02085 mgparm->partDisjLength[2] = zlenDisj;
02086 mgparm->partDisjCenter[0] = mgparm->fcenter[0] + xcentDisj;
02087 mgparm->partDisjCenter[1] = mgparm->fcenter[1] + ycentDisj;
02088 mgparm->partDisjCenter[2] = mgparm->fcenter[2] + zcentDisj;
02089 mgparm->fcenter[0] += xcentOlap;
02090 mgparm->fcenter[1] += ycentOlap;
02091 mgparm->fcenter[2] += zcentOlap;
02092
02093 Vnm_print(0, "NOsh_setupCalcMGPARA (%s, %d): Set up *relative* partition \
02094 centers...\n", __FILE__, __LINE__);
02095 Vnm_print(0, "NOsh_setupCalcMGPARA (%s, %d): Absolute centers will be set \
02096 in NOsh_setupMGAUTO\n", __FILE__, __LINE__);
02097 Vnm_print(0, "NOsh_setupCalcMGPARA (%s, %d): partDisjCenter = %g %g %g\n",
02098 __FILE__, __LINE__,
02099 mgparm->partDisjCenter[0],
02100 mgparm->partDisjCenter[1],
02101 mgparm->partDisjCenter[2]);
02102 Vnm_print(0, "NOsh_setupCalcMGPARA (%s, %d): ccenter = %g %g %g\n",
02103 __FILE__, __LINE__,
02104 mgparm->ccenter[0],
02105 mgparm->ccenter[1],
02106 mgparm->ccenter[2]);
02107 Vnm_print(0, "NOsh_setupCalcMGPARA (%s, %d): fcenter = %g %g %g\n",
02108 __FILE__, __LINE__,
02109 mgparm->fcenter[0],
02110 mgparm->fcenter[1],
02111 mgparm->fcenter[2]);
02112
02113
02114
02115 return NOsh_setupCalcMGAUTO(thee, elec);
02116
02117 }
02118
02119 VPUBLIC int NOsh_parseFEM(
02120 NOsh *thee,
02121 Vio *sock,
02122 NOsh_calc *elec
02123 ) {
02124
02125 char tok[VMAX_BUFSIZE];
02126 FEMparm *feparm = VNULL;
02127 PBEparm *pbeparm = VNULL;
02128 int rc;
02129 Vrc_Codes vrc;
02130
02131
02132 if (thee == VNULL) {
02133 Vnm_print(2, "NOsh_parseFEM: Got NULL thee!\n");
02134 return 0;
02135 }
02136 if (sock == VNULL) {
02137 Vnm_print(2, "NOsh_parseFEM: Got pointer to NULL socket!\n");
02138 return 0;
02139 }
02140 if (elec == VNULL) {
02141 Vnm_print(2, "NOsh_parseFEM: Got pointer to NULL elec object!\n");
02142 return 0;
02143 }
02144 feparm = elec->femparm;
02145 if (feparm == VNULL) {
02146 Vnm_print(2, "NOsh_parseFEM: Got pointer to NULL feparm object!\n");
02147 return 0;
02148 }
02149 pbeparm = elec->pbeparm;
02150 if (feparm == VNULL) {
02151 Vnm_print(2, "NOsh_parseFEM: Got pointer to NULL pbeparm object!\n");
02152 return 0;
02153 }
02154
02155 Vnm_print(0, "NOsh_parseFEM: Parsing parameters for FEM calculation\n");
02156
02157
02158 rc = 1;
02159 while (Vio_scanf(sock, "%s", tok) == 1) {
02160
02161 Vnm_print(0, "NOsh_parseFEM: Parsing %s...\n", tok);
02162
02163
02164 if (Vstring_strcasecmp(tok, "end") == 0) {
02165 feparm->parsed = 1;
02166 pbeparm->parsed = 1;
02167 rc = 1;
02168 break;
02169 }
02170
02171
02172 rc = PBEparm_parseToken(pbeparm, tok, sock);
02173 if (rc == -1) {
02174 Vnm_print(0, "NOsh_parseFEM: parsePBE error!\n");
02175 break;
02176 } else if (rc == 0) {
02177
02178 vrc = FEMparm_parseToken(feparm, tok, sock);
02179 if (vrc == VRC_FAILURE) {
02180 Vnm_print(0, "NOsh_parseFEM: parseMG error!\n");
02181 break;
02182 } else if (vrc == VRC_WARNING) {
02183
02184 Vnm_print(2, "NOsh: Unrecognized keyword: %s\n", tok);
02185 break;
02186 }
02187 }
02188 }
02189
02190
02191
02192 if (rc == -1) return 0;
02193 if (rc == 0) return 0;
02194
02195
02196 if ((!FEMparm_check(feparm)) || (!PBEparm_check(pbeparm))) {
02197 Vnm_print(2, "NOsh: FEM parameters not set correctly!\n");
02198 return 0;
02199 }
02200
02201 return 1;
02202
02203 }
02204
02205 VPRIVATE int NOsh_setupCalcFEMANUAL(
02206 NOsh *thee,
02207 NOsh_calc *elec
02208 ) {
02209
02210 FEMparm *feparm = VNULL;
02211 PBEparm *pbeparm = VNULL;
02212 NOsh_calc *calc = VNULL;
02213
02214 VASSERT(thee != VNULL);
02215 VASSERT(elec != VNULL);
02216 feparm = elec->femparm;
02217 VASSERT(feparm != VNULL);
02218 pbeparm = elec->pbeparm;
02219 VASSERT(pbeparm);
02220
02221
02222
02223
02224
02225 if (thee->ncalc >= NOSH_MAXCALC) {
02226 Vnm_print(2, "NOsh: Too many calculations in this run!\n");
02227 Vnm_print(2, "NOsh: Current max is %d; ignoring this calculation\n",
02228 NOSH_MAXCALC);
02229 return 0;
02230 }
02231 thee->calc[thee->ncalc] = NOsh_calc_ctor(NCT_FEM);
02232 calc = thee->calc[thee->ncalc];
02233 (thee->ncalc)++;
02234
02235
02236 NOsh_calc_copy(calc, elec);
02237
02238
02239 return 1;
02240 }
02241
02242 VPUBLIC int NOsh_parseAPOL(
02243 NOsh *thee,
02244 Vio *sock,
02245 NOsh_calc *elec
02246 ) {
02247
02248 char tok[VMAX_BUFSIZE];
02249 APOLparm *apolparm = VNULL;
02250 int rc;
02251
02252
02253 if (thee == VNULL) {
02254 Vnm_print(2, "NOsh_parseAPOL: Got NULL thee!\n");
02255 return 0;
02256 }
02257 if (sock == VNULL) {
02258 Vnm_print(2, "NOsh_parseAPOL: Got pointer to NULL socket!\n");
02259 return 0;
02260 }
02261 if (elec == VNULL) {
02262 Vnm_print(2, "NOsh_parseAPOL: Got pointer to NULL elec object!\n");
02263 return 0;
02264 }
02265 apolparm = elec->apolparm;
02266 if (apolparm == VNULL) {
02267 Vnm_print(2, "NOsh_parseAPOL: Got pointer to NULL feparm object!\n");
02268 return 0;
02269 }
02270
02271 Vnm_print(0, "NOsh_parseAPOL: Parsing parameters for APOL calculation\n");
02272
02273
02274 rc = 1;
02275 while (Vio_scanf(sock, "%s", tok) == 1) {
02276
02277 Vnm_print(0, "NOsh_parseAPOL: Parsing %s...\n", tok);
02278
02279 if (Vstring_strcasecmp(tok, "end") == 0) {
02280 apolparm->parsed = 1;
02281 rc = 1;
02282 break;
02283 }
02284
02285
02286
02287 rc = APOLparm_parseToken(apolparm, tok, sock);
02288 if (rc == -1) {
02289 Vnm_print(0, "NOsh_parseFEM: parseMG error!\n");
02290 break;
02291 } else if (rc == 0) {
02292
02293 Vnm_print(2, "NOsh: Unrecognized keyword: %s\n", tok);
02294 break;
02295 }
02296
02297 }
02298
02299
02300
02301 if (rc == -1) return 0;
02302 if (rc == 0) return 0;
02303
02304
02305 if (!APOLparm_check(apolparm)) {
02306 Vnm_print(2, "NOsh: APOL parameters not set correctly!\n");
02307 return 0;
02308 }
02309
02310 return 1;
02311
02312 }
02313
02314 VPRIVATE int NOsh_setupCalcAPOL(
02315 NOsh *thee,
02316 NOsh_calc *apol
02317 ) {
02318
02319 NOsh_calc *calc = VNULL;
02320
02321 VASSERT(thee != VNULL);
02322 VASSERT(apol != VNULL);
02323
02324
02325
02326
02327
02328 if (thee->ncalc >= NOSH_MAXCALC) {
02329 Vnm_print(2, "NOsh: Too many calculations in this run!\n");
02330 Vnm_print(2, "NOsh: Current max is %d; ignoring this calculation\n",
02331 NOSH_MAXCALC);
02332 return 0;
02333 }
02334 thee->calc[thee->ncalc] = NOsh_calc_ctor(NCT_APOL);
02335 calc = thee->calc[thee->ncalc];
02336 (thee->ncalc)++;
02337
02338
02339 NOsh_calc_copy(calc, apol);
02340
02341 return 1;
02342 }