/* * *************************************************************************** * Routine: Vmpi_ctor * * Purpose: The Vmpi constructor. * * Author: Michael Holst * *************************************************************************** */ VPUBLIC Vmpi* Vmpi_ctor(void) { #if defined(HAVE_MPI_H) int dummy; #endif Vmpi *thee = VNULL; VDEBUGIO("Vmpi_ctor: CREATING object.."); thee = Vmem_malloc( VNULL, 1, sizeof(Vmpi) ); thee->mpi_rank = 0; thee->mpi_size = 0; #if defined(HAVE_MPI_H) VASSERT( MPI_SUCCESS == MPI_Initialized(&dummy) ); VASSERT( MPI_SUCCESS == MPI_Comm_rank(MPI_COMM_WORLD, &(thee->mpi_rank)) ); VASSERT( MPI_SUCCESS == MPI_Comm_size(MPI_COMM_WORLD, &(thee->mpi_size)) ); Vnm_setIoTag(thee->mpi_rank, thee->mpi_size); Vnm_print(2,"Vmpi_ctor: process %d of %d is ALIVE!\n", thee->mpi_rank, thee->mpi_size); #endif VDEBUGIO("..done.\n"); return thee; }
void apbsinitial_(int dime[3], double grid[3], double gcent[3], double cgrid[3], double cgcent[3], double fgrid[3], double fgcent[3], double *pdie, double *sdie, double *srad, double *swin, double *sdens, double *kelvin, int *ionn, double ionc[maxion], int ionq[maxion], double ionr[maxion], char *pbtypef, int *pbtypelen, char *pbsolnf, int *pbsolnlen, char *bcflf, int *bcfllen, char *chgmf, int *chgmlen, char *srfmf, int *srfmlen, int fortranAppendedPbtypeLen, int fortranAppendedPbsolnLen, int fortranAppendedBfclLen, int fortranAppendedChgmLen, int fortranAppendedSrfmLen) { /* All character strings passed from FORTRAN result in an integer appended to the list of arguments, each equal to the static length specified in the TINKER common block 'pb.i' (20). Further below the FORTRAN strings will be converted into null terminated C-strings. */ char pbtype[21]; // lpbe char pbsoln[21]; // mg-manual or mg-auto char bcfl[21]; // zero, sdh, mdh char chgm[21]; // spl4 char srfm[21]; // mol, smol, spl2 /* Bogus argc and argv variables used for Vcom constructor. */ int argc = 0; char **argv; /* CPU info */ int rank, size; /* APBS "input file" is a character buffer */ char buff[4096]; char tmp[1024]; /* Loop index */ int i; /* Start the timer - although keep in mind it is not stopped until apbsfinal is called. */ Vnm_tstart(APBS_TIMER_WALL_CLOCK, "APBS WALL CLOCK"); /* Convert FORTRAN strings to null-terminated C-String */ strncpy(pbtype, pbtypef, *pbtypelen); strncpy(pbsoln, pbsolnf, *pbsolnlen); strncpy(bcfl, bcflf, *bcfllen); strncpy(chgm, chgmf, *chgmlen); strncpy(srfm, srfmf, *srfmlen); pbtype[*pbtypelen] = '\0'; pbsoln[*pbsolnlen] = '\0'; bcfl[*bcfllen] = '\0'; chgm[*chgmlen] = '\0'; srfm[*srfmlen] = '\0'; /* Rather than require an APBS input file, a character buffer is loaded with two ELEC statements: (1) The homogeneous calculation. (2) The solvated calculation. Many options for partial charge systems are not yet supported for AMOEBA (or are not appropriate). The subset of ELEC options that can be modified are configured using TINKER keywords. Initialization of the "nosh" input data structure then proceeds using the buffer data. If the syntax of the ELEC statement changes, then corresponding changes will be needed to be made below. */ /* Homogeneous */ strcpy(buff,"ELEC NAME HOMOGENEOUS\n"); sprintf(tmp,"\t%s\n",pbsoln); strcat(buff,tmp); sprintf(tmp,"\t%s\n",pbtype); strcat(buff,tmp); sprintf(tmp,"\tDIME\t%3i %3i %3i\n",dime[0],dime[1],dime[2]); strcat(buff,tmp); // MG-AUTO if (strcmp(pbsoln,"MG-AUTO") == 0) { sprintf(tmp,"\tCGLEN %10.6f %10.6f %10.6f\n", dime[0]*cgrid[0], dime[1]*cgrid[1], dime[2]*cgrid[2]); strcat(buff,tmp); sprintf(tmp,"\tCGCENT %10.6f %10.6f %10.6f\n", cgcent[0], cgcent[1],cgcent[2]); strcat(buff,tmp); sprintf(tmp,"\tFGLEN %10.6f %10.6f %10.6f\n", dime[0]*fgrid[0], dime[1]*fgrid[1], dime[2]*fgrid[2]); strcat(buff,tmp); sprintf(tmp,"\tFGCENT %10.6f %10.6f %10.6f\n", fgcent[0], fgcent[1], fgcent[2]); strcat(buff,tmp); } else { // MG-MANUAL sprintf(tmp,"\tGLEN %10.6f %10.6f %10.6f\n", dime[0]*grid[0], dime[1]*grid[1], dime[2]*grid[2]); strcat(buff,tmp); sprintf(tmp,"\tGCENT %10.6f %10.6f %10.6f\n", gcent[0], gcent[1], gcent[2]); strcat(buff,tmp); } strcat(buff,"\tMOL\t1\n"); sprintf(tmp,"\tBCFL\t%s\n", bcfl); strcat(buff,tmp); sprintf(tmp,"\tPDIE %10.6f\n", *pdie); strcat(buff,tmp); sprintf(tmp,"\tSDIE %10.6f\n", *pdie); strcat(buff,tmp); sprintf(tmp,"\tCHGM\t%s\n", chgm); strcat(buff,tmp); sprintf(tmp,"\tSRFM\t%s\n", srfm); strcat(buff,tmp); sprintf(tmp,"\tSRAD %10.6f\n", *srad); strcat(buff,tmp); sprintf(tmp,"\tSWIN %10.6f\n", *swin); strcat(buff,tmp); sprintf(tmp,"\tSDENS %10.6f\n", *sdens); strcat(buff,tmp); sprintf(tmp,"\tTEMP %10.6f\n", *kelvin); strcat(buff,tmp); strcat(buff,"END\n\n"); /* Solvated */ strcat(buff,"ELEC NAME SOLVATED\n"); sprintf(tmp,"\t%s\n",pbsoln); strcat(buff,tmp); sprintf(tmp,"\t%s\n",pbtype); strcat(buff,tmp); sprintf(tmp,"\tDIME\t%3i %3i %3i\n",dime[0],dime[1],dime[2]); strcat(buff,tmp); // MG-AUTO if (strcmp(pbsoln,"MG-AUTO") == 0) { sprintf(tmp,"\tCGLEN %10.6f %10.6f %10.6f\n", dime[0]*cgrid[0], dime[1]*cgrid[1], dime[2]*cgrid[2]); strcat(buff,tmp); sprintf(tmp,"\tCGCENT %10.6f %10.6f %10.6f\n", cgcent[0], cgcent[1], cgcent[2]); strcat(buff,tmp); sprintf(tmp,"\tFGLEN %10.6f %10.6f %10.6f\n", dime[0]*fgrid[0], dime[1]*fgrid[1], dime[2]*fgrid[2]); strcat(buff,tmp); sprintf(tmp,"\tFGCENT %10.6f %10.6f %10.6f\n", fgcent[0], fgcent[1], fgcent[2]); strcat(buff,tmp); } else { // MG-MANUAL sprintf(tmp,"\tGLEN %10.6f %10.6f %10.6f\n", dime[0]*grid[0], dime[1]*grid[1], dime[2]*grid[2]); strcat(buff,tmp); sprintf(tmp,"\tGCENT %10.6f %10.6f %10.6f\n", gcent[0], gcent[1], gcent[2]); strcat(buff,tmp); } strcat(buff,"\tMOL\t1\n"); sprintf(tmp,"\tBCFL\t%s\n", bcfl); strcat(buff,tmp); sprintf(tmp,"\tPDIE %10.6f\n", *pdie); strcat(buff,tmp); sprintf(tmp,"\tSDIE %10.6f\n", *sdie); strcat(buff,tmp); sprintf(tmp,"\tCHGM\t%s\n", chgm); strcat(buff,tmp); sprintf(tmp,"\tSRFM\t%s\n", srfm); strcat(buff,tmp); sprintf(tmp,"\tSRAD %10.6f\n", *srad); strcat(buff,tmp); sprintf(tmp,"\tSWIN %10.6f\n", *swin); strcat(buff,tmp); sprintf(tmp,"\tSDENS %10.6f\n", *sdens); strcat(buff,tmp); sprintf(tmp,"\tTEMP %10.6f\n", *kelvin); strcat(buff,tmp); for (i=0; i < *ionn; i++) { sprintf(tmp,"\tION\t%2i %10.6f %10.6f\n", ionq[i], ionc[i], ionr[i]); strcat(buff,tmp); } strcat(buff,"END\n"); strcat(buff,"\nQUIT\n"); /* Misc. initializations */ for (i=0; i<NOSH_MAXMOL; i++) { alist[i] = VNULL; dielXMap[i] = VNULL; dielYMap[i] = VNULL; dielZMap[i] = VNULL; kappaMap[i] = VNULL; potMap[i] = VNULL; chargeMap[i] = VNULL; } for (i=0; i<2; i++) { permU[i] = VNULL; indU[i] = VNULL; nlIndU[i] = VNULL; } /* Initialization of Vcom, Vmem, and Nosh (via Vio). */ VASSERT(Vcom_init(&argc, &argv)); com = Vcom_ctor(1); rank = Vcom_rank(com); size = Vcom_size(com); startVio(); Vnm_setIoTag(rank, size); mem = Vmem_ctor("MAIN"); /* Print (to io.mc) and then parse the input buffer. */ Vnm_tprint(0, "\n********* TINKER generated input buffer *********\n\n"); Vnm_tprint(0, "%s", buff); Vnm_tprint(0, "\n*************************************************\n\n"); nosh = NOsh_ctor(rank, size); sock = Vio_ctor("BUFF", "ASC", VNULL, "BUFFER", "r"); Vio_bufTake(sock, buff, strlen(buff)); if (!NOsh_parseInput(nosh, sock)) { Vnm_tprint( 2, "Error while parsing input file.\n"); return; } /* Release the buffer and kill Vio */ Vio_bufGive(sock); Vio_dtor(&sock); }
/* * *************************************************************************** * Routine: Vcom_ctor2 * * Purpose: Construct the communications object * * Notes: This routine sets up data members of class and initializes MPI. * * This is broken into two parts to be callable from FORTRAN. * * Author: Nathan Baker and Michael Holst * *************************************************************************** */ VPUBLIC int Vcom_ctor2(Vcom *thee, int commtype) { int rc = 0; #if defined(HAVE_MPI_H) char estr[MPI_MAX_ERROR_STRING]; int elen, dummy; Vcom_core *core = thee->core; #endif /* * See what type of communications we should use. Maybe each type of * communications object should have its own ctor2() function. */ switch ( commtype ) { case 1: /* MPI 1.1 */ thee->type = commtype; #if defined(HAVE_MPI_H) /* Start up MPI */ rc = MPI_Initialized(&dummy); if (rc != MPI_SUCCESS) { MPI_Error_string(rc, estr, &elen); Vnm_print(2, "Vcom_ctor2: MPI_Init returned error: %s\n", estr); return 0; } /* Get the total number of processors */ rc = MPI_Comm_size(MPI_COMM_WORLD, &(thee->mpi_size)); if (rc != MPI_SUCCESS) { MPI_Error_string(rc, estr, &elen); Vnm_print(2, "Vcom_ctor2: MPI_Comm_size returned error: %s\n", estr); return 0; } /* Get my processor rank */ rc = MPI_Comm_rank(MPI_COMM_WORLD, &(thee->mpi_rank)); if (rc != MPI_SUCCESS) { MPI_Error_string(rc, estr, &elen); Vnm_print(2, "Vcom_ctor2: MPI_Comm_rank returned error: %s\n", estr); return 0; } /* Construct the communications group including all processors */ core->mpi_comm = MPI_COMM_WORLD; /* Initialize Vnm with MPI rank */ Vnm_setIoTag(thee->mpi_rank, thee->mpi_size); /* Some i/o */ Vnm_print(2,"Vcom_ctor2: process %d of %d is ALIVE!\n", thee->mpi_rank, thee->mpi_size); rc = 1; break; #else /* defined(HAVE_MPI_H) */ /* this might not be an error if this is a sequential code... */ rc = 1; break; #endif /* defined(HAVE_MPI_H) */ default: Vnm_print(2, "Vcom_ctor2: Invalid communications type!\n"); rc = 0; } /* switch (commtype) */ return rc; }