Exemple #1
0
/*
 * ***************************************************************************
 * Routine:  MCsh_ctor
 *
 * Purpose:  The MCsh constructor.
 *
 * Author:   Michael Holst
 * ***************************************************************************
 */
VPUBLIC MCsh* MCsh_ctor(PDE *tpde, int argc, char **argv)
{
    MCsh *thee = VNULL;

    VDEBUGIO("MCsh_ctor: CREATING object..");

    thee = Vmem_malloc( VNULL, 1, sizeof(MCsh) );
    thee->vmem = Vmem_ctor( "MCsh" );

    VDEBUGIO("..done.\n");

    /* the environment and shell object */
    thee->PR[0] = '\0';
    thee->USER_shell = VNULL;
    thee->vsh = Vsh_ctor(VNULL, argc, argv);

    /* the differential equation object */
    thee->pde = tpde;

    /* the geometry manager object */
    thee->gm = Gem_ctor( VNULL, thee->pde );

    /* the approximation object */
    thee->aprx = Aprx_ctor( VNULL, thee->gm, thee->pde );

    /* the algebra manager object */
    thee->am = AM_ctor( VNULL, thee->aprx );

    return thee;
}
Exemple #2
0
/*
 * ***************************************************************************
 * Routine:  Bnode_ctor
 *
 * Purpose:  The Block node constructor.
 *
 * Author:   Michael Holst
 * ***************************************************************************
 */
VPUBLIC Bnode* Bnode_ctor(Vmem *vmem, int pnumB, int pnumR[MAXV])
{
    int i;
    Bnode *thee = VNULL;

    VDEBUGIO("Bnode_ctor: CREATING object..");

    thee = Vmem_malloc( VNULL, 1, sizeof(Bnode) );
    if (vmem == VNULL) {
        thee->vmem = Vmem_ctor( "Bnode" );
        thee->iMadeVmem = 1;
    } else {
        thee->vmem = vmem;
        thee->iMadeVmem = 0;
    }

    VDEBUGIO("..done.\n");

    thee->numB   = pnumB;
    for (i=0; i<thee->numB; i++) {
        thee->ND[i] = Node_ctor(vmem, pnumR[i]);
    }

    return thee;
}
Exemple #3
0
/* Main (FORTRAN stub) constructor */
VPUBLIC Vrc_Codes Vclist_ctor2(Vclist *thee, Valist *alist, double max_radius,
        int npts[VAPBS_DIM], Vclist_DomainMode mode, 
        double lower_corner[VAPBS_DIM], double upper_corner[VAPBS_DIM]) {

    int i;
    VclistCell *cell;

    /* Check and store parameters */
    if ( Vclist_storeParms(thee, alist, max_radius, npts, mode, lower_corner,
                upper_corner) == VRC_FAILURE ) {
        Vnm_print(2, "Vclist_ctor2:  parameter check failed!\n");
        return VRC_FAILURE;
    }

    /* Set up memory */
    thee->vmem = Vmem_ctor("APBS::VCLIST");
    if (thee->vmem == VNULL) {
        Vnm_print(2, "Vclist_ctor2:  memory object setup failed!\n");
        return VRC_FAILURE;
    }

    /* Set up cells */
    thee->cells = Vmem_malloc( thee->vmem, thee->n, sizeof(VclistCell) );
    if (thee->cells == VNULL) {
        Vnm_print(2, 
                "Vclist_ctor2:  Failed allocating %d VclistCell objects!\n",
                thee->n);
        return VRC_FAILURE;
    }
    for (i=0; i<thee->n; i++) {
        cell = &(thee->cells[i]);
        cell->natoms = 0;
    }

    /* Set up the grid */
    if ( Vclist_setupGrid(thee) == VRC_FAILURE ) {
        Vnm_print(2, "Vclist_ctor2:  grid setup failed!\n");
        return VRC_FAILURE;
    }

    /* Assign atoms to grid cells */
    if (Vclist_assignAtoms(thee) == VRC_FAILURE) {
        Vnm_print(2, "Vclist_ctor2:  atom assignment failed!\n");
        return VRC_FAILURE;
    }
	

	


    return VRC_SUCCESS;
}
Exemple #4
0
/*
 * ***************************************************************************
 * Routine:  Bmat_ctor
 *
 * Purpose:  The block sparse matrix constructor.
 *
 * Notes:    This constructor only does minimal initialization of a Bmat
 *           object after creating the object itself; it doesn't create
 *           any storage for either the integer structure arrays or the
 *           nonzero storage arrays.
 *
 *           This constructor only fixes the number of blocks and the
 *           numbers of rows and columns in each block; the nonzero
 *           structure is not set yet.
 *
 * Author:   Michael Holst
 * ***************************************************************************
 */
VPUBLIC Bmat* Bmat_ctor(Vmem *vmem, const char *name,
    int pnumB, int pnumR[MAXV], int pnumC[MAXV],
    MATmirror pmirror[MAXV][MAXV])
{
    int p,q;
    char bname[15];
    Bmat *thee = VNULL;

    VDEBUGIO("Bmat_ctor: CREATING object..");

    thee = Vmem_malloc( VNULL, 1, sizeof(Bmat) );
    if (vmem == VNULL) {
        thee->vmem = Vmem_ctor( "Bmat" );
        thee->iMadeVmem = 1;
    } else {
        thee->vmem = vmem;
        thee->iMadeVmem = 0;
    }

    strncpy(thee->name, name, 10);
    thee->coarse = VNULL;
    thee->fine   = VNULL;
    thee->numB   = pnumB;
    for (p=0; p<thee->numB; p++) {
        for (q=0; q<thee->numB; q++) {
            thee->mirror[p][q] = pmirror[p][q];
            thee->AD[p][q]     = VNULL;
        }
    }

    /* create upper-triangular blocks before the lower-triangular blocks */
    for (p=0; p<thee->numB; p++) {
        for (q=0; q<thee->numB; q++) {
            if ( !thee->mirror[p][q] ) {
                sprintf(bname, "%s_%d%d", thee->name, p, q);
                thee->AD[p][q] = Mat_ctor(thee->vmem,bname,pnumR[p],pnumC[q]);
            } else { /* ( thee->mirror[p][q] ) */
                /* first make sure that the mirror of this guy exists! */
                VASSERT( !thee->mirror[q][p] );
                VASSERT( thee->AD[q][p] != VNULL );
                thee->AD[p][q] = thee->AD[q][p];
            }
        }
    }

    VDEBUGIO("..done.\n");

    return thee;
}
Exemple #5
0
VPUBLIC int Vcsm_ctor2(Vcsm *thee, Valist *alist, Gem *gm) { 
 
    VASSERT( thee != VNULL );

    /* Memory management object */
    thee->vmem = Vmem_ctor("APBS:VCSM");

    /* Set up the atom list and grid manager */
    if( alist == VNULL) {
        Vnm_print(2,"Vcsm_ctor2: got null pointer to Valist object!\n");
        return 0;
    }
    thee->alist = alist;
    if( gm == VNULL) {
        Vnm_print(2,"Vcsm_ctor2: got a null pointer to the Gem object!\n");
        return 0;
    }
    thee->gm = gm;
   
    thee->initFlag = 0;
    return 1;
}
Exemple #6
0
/*
 * ***************************************************************************
 * Routine:  Gem_ctor
 *
 * Purpose:  Geometry manager constructor.
 *
 * Author:   Michael Holst
 * ***************************************************************************
 */
VPUBLIC Gem* Gem_ctor(Vmem *vmem, PDE *tpde)
{
    int i;
    Gem* thee = VNULL;

    thee = Vmem_malloc( VNULL, 1, sizeof(Gem) );
    if (vmem == VNULL) {
        thee->vmem = Vmem_ctor( "Gem" );
        thee->iMadeVmem = 1;
    } else {
        thee->vmem = vmem;
        thee->iMadeVmem = 0;
    }
   
    VDEBUGIO("Gem_ctor: CREATING object..");
    VDEBUGIO("..done.\n");

    thee->xUp     = defaultxUpFunc;
    thee->xUpFlag = 0;

    if (tpde != VNULL) {
        thee->iMadePDE = 0;
        thee->pde      = tpde;
    } else {
        thee->iMadePDE = 1;
        thee->pde      = PDE_ctor_default();
    }

    thee->vertices  = VNULL;
    thee->edges     = VNULL;
    thee->simplices = VNULL;
    for (i=0; i<VMAXSQ; i++) {
        thee->sQueM[i] = VNULL;
    }

    Gem_reset(thee, 0, 0);

    return thee;
}
Exemple #7
0
VPUBLIC int Vgreen_ctor2(Vgreen *thee, Valist *alist) { 
 
    VASSERT( thee != VNULL );

    /* Memory management object */
    thee->vmem = Vmem_ctor("APBS:VGREEN");

    /* Set up the atom list and grid manager */
    if (alist == VNULL) {
        Vnm_print(2,"Vgreen_ctor2: got null pointer to Valist object!\n");
    }

    thee->alist = alist;

    /* Setup FMM tree (if applicable) */
#ifdef HAVE_TREE
    if (!treesetup(thee)) {
        Vnm_print(2, "Vgreen_ctor2:  Error setting up FMM tree!\n");
        return 0;
    }
#endif /* ifdef HAVE_TREE */
   
    return 1;
}
Exemple #8
0
/*
 * ***************************************************************************
 * Routine:  Slu_ctor
 *
 * Purpose:  The Slu constructor.
 *
 * Author:   Michael Holst and Stephen Bond
 * ***************************************************************************
 */
VPUBLIC Slu* Slu_ctor(Vmem *vmem, int skey, int m, int n, int nnz,
    int *ia, int *ja, double *a)
{
    Slu* thee = VNULL;

    VDEBUGIO("Slu_ctor: CREATING object..");

    thee = Vmem_malloc( VNULL, 1, sizeof(Slu) );
    if (vmem == VNULL) {
        thee->vmem = Vmem_ctor( "Slu" );
        thee->iMadeVmem = 1;
    } else {
        thee->vmem = vmem;
        thee->iMadeVmem = 0;
    }

    /* dimensions */
    thee->m = m;
    thee->n = n;

    /* storage key */
    thee->skey = skey;

    /* pointer to factors */
    thee->work = VNULL;

    /* arrays */
    thee->a  = a;
    thee->ia = ia;
    thee->ja = ja;

    VDEBUGIO("..done.\n");

    /* return */
    return thee;
}
Exemple #9
0
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);
}
Exemple #10
0
/* ///////////////////////////////////////////////////////////////////////////
// Routine:  Vpee_ctor2
//
// Author:   Nathan Baker
/////////////////////////////////////////////////////////////////////////// */
VPUBLIC int Vpee_ctor2(Vpee *thee,
                       Gem *gm,
                       int localPartID,
                       int killFlag,
                       double killParam
                       ) {

    int ivert,
        nLocalVerts;
    SS *simp;
    VV *vert;
    double radius,
           dx,
           dy,
           dz;

    VASSERT(thee != VNULL);

    /* Sanity check on input values */
    if (killFlag == 0) {
        Vnm_print(0, "Vpee_ctor2: No error attenuation outside partition.\n");
    } else if (killFlag == 1) {
        Vnm_print(0, "Vpee_ctor2: Error outside local partition ignored.\n");
    } else if (killFlag == 2) {
        Vnm_print(0, "Vpee_ctor2: Error ignored outside sphere with radius %4.3f times the radius of the circumscribing sphere\n", killParam);
        if (killParam < 1.0) {
          Vnm_print(2, "Vpee_ctor2: Warning! Parameter killParam = %4.3 < 1.0!\n",
            killParam);
          Vnm_print(2, "Vpee_ctor2: This may result in non-optimal marking and refinement!\n");
        }
    } else if (killFlag == 3) {
        Vnm_print(0, "Vpee_ctor2: Error outside local partition and immediate neighbors ignored [NOT IMPLEMENTED].\n");
    } else {
        Vnm_print(2, "Vpee_ctor2: UNRECOGNIZED killFlag PARAMETER! BAILING!.\n");
        VASSERT(0);
    }

    thee->gm = gm;
    thee->localPartID = localPartID;
    thee->killFlag = killFlag;
    thee->killParam = killParam;
    thee->mem = Vmem_ctor("APBS::VPEE");

    /* Now, figure out the center of geometry for the local partition.  The
     * general plan is to loop through the vertices, loop through the
     * vertices' simplex lists and find the vertices with simplices containing
     * chart values we're interested in. */
    thee->localPartCenter[0] = 0.0;
    thee->localPartCenter[1] = 0.0;
    thee->localPartCenter[2] = 0.0;
    nLocalVerts = 0;
    for (ivert=0; ivert<Gem_numVV(thee->gm); ivert++) {
        vert = Gem_VV(thee->gm, ivert);
        simp = VV_firstSS(vert);
        VASSERT(simp != VNULL);
        while (simp != VNULL) {
            if (SS_chart(simp) == thee->localPartID) {
                thee->localPartCenter[0] += VV_coord(vert, 0);
                thee->localPartCenter[1] += VV_coord(vert, 1);
                thee->localPartCenter[2] += VV_coord(vert, 2);
                nLocalVerts++;
                break;
            }
            simp = SS_link(simp, vert);
        }
    }
    VASSERT(nLocalVerts > 0);
    thee->localPartCenter[0] =
      thee->localPartCenter[0]/((double)(nLocalVerts));
    thee->localPartCenter[1] =
      thee->localPartCenter[1]/((double)(nLocalVerts));
    thee->localPartCenter[2] =
      thee->localPartCenter[2]/((double)(nLocalVerts));
    Vnm_print(0, "Vpee_ctor2: Part %d centered at (%4.3f, %4.3f, %4.3f)\n",
      thee->localPartID, thee->localPartCenter[0], thee->localPartCenter[1],
      thee->localPartCenter[2]);


    /* Now, figure out the radius of the sphere circumscribing the local
     * partition.  We need to keep track of vertices so we don't double count
     * them. */
    thee->localPartRadius = 0.0;
    for (ivert=0; ivert<Gem_numVV(thee->gm); ivert++) {
        vert = Gem_VV(thee->gm, ivert);
        simp = VV_firstSS(vert);
        VASSERT(simp != VNULL);
        while (simp != VNULL) {
            if (SS_chart(simp) == thee->localPartID) {
                dx = thee->localPartCenter[0] - VV_coord(vert, 0);
                dy = thee->localPartCenter[1] - VV_coord(vert, 1);
                dz = thee->localPartCenter[2] - VV_coord(vert, 2);
                radius = dx*dx + dy*dy + dz*dz;
                if (radius > thee->localPartRadius) thee->localPartRadius =
                  radius;
                break;
            }
            simp = SS_link(simp, vert);
        }
    }
    thee->localPartRadius = VSQRT(thee->localPartRadius);
    Vnm_print(0, "Vpee_ctor2: Part %d has circumscribing sphere of radius %4.3f\n",
      thee->localPartID, thee->localPartRadius);

    return 1;
}