Example #1
0
int inputrec2nboundeddim(t_inputrec *ir)
{
    if (ir->nwall == 2 && ir->ePBC == epbcXY)
    {
        return 3;
    }
    else
    {
        return ePBC2npbcdim(ir->ePBC);
    }
}
Example #2
0
t_grid *init_grid(FILE *fplog, t_forcerec *fr)
{
    int     d, m;
    char   *ptr;
    t_grid *grid;

    snew(grid, 1);

    grid->npbcdim = ePBC2npbcdim(fr->ePBC);

    if (fr->ePBC == epbcXY && fr->nwall == 2)
    {
        grid->nboundeddim = 3;
    }
    else
    {
        grid->nboundeddim = grid->npbcdim;
    }

    if (debug)
    {
        fprintf(debug, "The coordinates are bounded in %d dimensions\n",
                grid->nboundeddim);
    }

    /* The ideal number of cg's per ns grid cell seems to be 10 */
    grid->ncg_ideal = 10;
    ptr             = getenv("GMX_NSCELL_NCG");
    if (ptr)
    {
        sscanf(ptr, "%d", &grid->ncg_ideal);
        if (fplog)
        {
            fprintf(fplog, "Set ncg_ideal to %d\n", grid->ncg_ideal);
        }
        if (grid->ncg_ideal <= 0)
        {
            gmx_fatal(FARGS, "The number of cg's per cell should be > 0");
        }
    }
    if (debug)
    {
        fprintf(debug, "Set ncg_ideal to %d\n", grid->ncg_ideal);
    }

    return grid;
}
Example #3
0
static void low_set_ddbox(t_inputrec *ir, ivec *dd_nc, matrix box,
                          gmx_bool bCalcUnboundedSize, int ncg, t_block *cgs, rvec *x,
                          t_commrec *cr_sum,
                          gmx_ddbox_t *ddbox)
{
    rvec av, stddev;
    real b0, b1;
    int  d;

    ddbox->npbcdim     = ePBC2npbcdim(ir->ePBC);
    ddbox->nboundeddim = inputrec2nboundeddim(ir);

    for (d = 0; d < ddbox->nboundeddim; d++)
    {
        ddbox->box0[d]     = 0;
        ddbox->box_size[d] = box[d][d];
    }

    if (ddbox->nboundeddim < DIM && bCalcUnboundedSize)
    {
        calc_cgcm_av_stddev(cgs, ncg, x, av, stddev, cr_sum);

        /* GRID_STDDEV_FAC * stddev
         * gives a uniform load for a rectangular block of cg's.
         * For a sphere it is not a bad approximation for 4x1x1 up to 4x2x2.
         */
        for (d = ddbox->nboundeddim; d < DIM; d++)
        {
            b0 = av[d] - GRID_STDDEV_FAC*stddev[d];
            b1 = av[d] + GRID_STDDEV_FAC*stddev[d];
            if (debug)
            {
                fprintf(debug, "Setting global DD grid boundaries to %f - %f\n",
                        b0, b1);
            }
            ddbox->box0[d]     = b0;
            ddbox->box_size[d] = b1 - b0;
        }
    }

    set_tric_dir(dd_nc, ddbox, box);
}
Example #4
0
static void read_posres(gmx_mtop_t *mtop,t_molinfo *molinfo,bool bTopB,
			char *fn,
			int rc_scaling, int ePBC, 
			rvec com)
{
  bool   bFirst = TRUE;
  rvec   *x,*v,*xp;
  dvec   sum;
  double totmass;
  t_atoms dumat;
  matrix box,invbox;
  int    natoms,npbcdim=0;
  char   title[STRLEN];
  int    a,i,ai,j,k,mb,nat_molb;
  gmx_molblock_t *molb;
  t_params *pr;
  t_atom *atom;

  get_stx_coordnum(fn,&natoms);
  if (natoms != mtop->natoms) {
    sprintf(warn_buf,"The number of atoms in %s (%d) does not match the number of atoms in the topology (%d). Will assume that the first %d atoms in the topology and %s match.",fn,natoms,mtop->natoms,min(mtop->natoms,natoms),fn);
    warning(NULL);
  }
  snew(x,natoms);
  snew(v,natoms);
  init_t_atoms(&dumat,natoms,FALSE);
  read_stx_conf(fn,title,&dumat,x,v,NULL,box);
  
  npbcdim = ePBC2npbcdim(ePBC);
  clear_rvec(com);
  if (rc_scaling != erscNO) {
    copy_mat(box,invbox);
    for(j=npbcdim; j<DIM; j++) {
      clear_rvec(invbox[j]);
      invbox[j][j] = 1;
    }
    m_inv_ur0(invbox,invbox);
  }

  /* Copy the reference coordinates to mtop */
  clear_dvec(sum);
  totmass = 0;
  a = 0;
  for(mb=0; mb<mtop->nmolblock; mb++) {
    molb = &mtop->molblock[mb];
    nat_molb = molb->nmol*mtop->moltype[molb->type].atoms.nr;
    pr = &(molinfo[molb->type].plist[F_POSRES]);
    if (pr->nr > 0) {
      atom = mtop->moltype[molb->type].atoms.atom;
      for(i=0; (i<pr->nr); i++) {
	ai=pr->param[i].AI;
	if (ai >= natoms) {
	  gmx_fatal(FARGS,"Position restraint atom index (%d) in moltype '%s' is larger than number of atoms in %s (%d).\n",
		    ai+1,*molinfo[molb->type].name,fn,natoms);
	}
	if (rc_scaling == erscCOM) {
	  /* Determine the center of mass of the posres reference coordinates */
	  for(j=0; j<npbcdim; j++) {
	    sum[j] += atom[ai].m*x[a+ai][j];
	  }
	  totmass  += atom[ai].m;
	}
      }
      if (!bTopB) {
	molb->nposres_xA = nat_molb;
	snew(molb->posres_xA,molb->nposres_xA);
	for(i=0; i<nat_molb; i++) {
	  copy_rvec(x[a+i],molb->posres_xA[i]);
	}
      } else {
	molb->nposres_xB = nat_molb;
	snew(molb->posres_xB,molb->nposres_xB);
	for(i=0; i<nat_molb; i++) {
	  copy_rvec(x[a+i],molb->posres_xB[i]);
	}
      }
    }
    a += nat_molb;
  }
  if (rc_scaling == erscCOM) {
    if (totmass == 0)
      gmx_fatal(FARGS,"The total mass of the position restraint atoms is 0");
    for(j=0; j<npbcdim; j++)
      com[j] = sum[j]/totmass;
    fprintf(stderr,"The center of mass of the position restraint coord's is %6.3f %6.3f %6.3f\n",com[XX],com[YY],com[ZZ]);
  }

  if (rc_scaling != erscNO) {
    for(mb=0; mb<mtop->nmolblock; mb++) {
      molb = &mtop->molblock[mb];
      nat_molb = molb->nmol*mtop->moltype[molb->type].atoms.nr;
      if (molb->nposres_xA > 0 || molb->nposres_xB > 0) {
	xp = (!bTopB ? molb->posres_xA : molb->posres_xB);
	for(i=0; i<nat_molb; i++) {
	  for(j=0; j<npbcdim; j++) {
	    if (rc_scaling == erscALL) {
	      /* Convert from Cartesian to crystal coordinates */
	      xp[i][j] *= invbox[j][j];
	      for(k=j+1; k<npbcdim; k++) {
		xp[i][j] += invbox[k][j]*xp[i][k];
	      }
	    } else if (rc_scaling == erscCOM) {
	      /* Subtract the center of mass */
	      xp[i][j] -= com[j];
	    }
	  }
	}
      }
    }

    if (rc_scaling == erscCOM) {
      /* Convert the COM from Cartesian to crystal coordinates */
      for(j=0; j<npbcdim; j++) {
	com[j] *= invbox[j][j];
	for(k=j+1; k<npbcdim; k++) {
	  com[j] += invbox[k][j]*com[k];
	}
      }
    }
  }
  
  free_t_atoms(&dumat,TRUE);
  sfree(x);
  sfree(v);
}
Example #5
0
static void low_set_pbc(t_pbc *pbc, int ePBC, ivec *dd_nc, matrix box)
{
    int         order[5] = {0, -1, 1, -2, 2};
    int         ii, jj, kk, i, j, k, d, dd, jc, kc, npbcdim, shift;
    ivec        bPBC;
    real        d2old, d2new, d2new_c;
    rvec        trial, pos;
    gmx_bool    bXY, bUse;
    const char *ptr;

    pbc->ndim_ePBC = ePBC2npbcdim(ePBC);

    copy_mat(box, pbc->box);
    pbc->bLimitDistance = FALSE;
    pbc->max_cutoff2    = 0;
    pbc->dim            = -1;

    for (i = 0; (i < DIM); i++)
    {
        pbc->fbox_diag[i]  =  box[i][i];
        pbc->hbox_diag[i]  =  pbc->fbox_diag[i]*0.5;
        pbc->mhbox_diag[i] = -pbc->hbox_diag[i];
    }

    ptr = check_box(ePBC, box);
    if (ePBC == epbcNONE)
    {
        pbc->ePBCDX = epbcdxNOPBC;
    }
    else if (ptr)
    {
        fprintf(stderr,   "Warning: %s\n", ptr);
        pr_rvecs(stderr, 0, "         Box", box, DIM);
        fprintf(stderr,   "         Can not fix pbc.\n");
        pbc->ePBCDX          = epbcdxUNSUPPORTED;
        pbc->bLimitDistance  = TRUE;
        pbc->limit_distance2 = 0;
    }
    else
    {
        if (ePBC == epbcSCREW && dd_nc)
        {
            /* This combinated should never appear here */
            gmx_incons("low_set_pbc called with screw pbc and dd_nc != NULL");
        }

        npbcdim = 0;
        for (i = 0; i < DIM; i++)
        {
            if ((dd_nc && (*dd_nc)[i] > 1) || (ePBC == epbcXY && i == ZZ))
            {
                bPBC[i] = 0;
            }
            else
            {
                bPBC[i] = 1;
                npbcdim++;
            }
        }
        switch (npbcdim)
        {
            case 1:
                /* 1D pbc is not an mdp option and it is therefore only used
                 * with single shifts.
                 */
                pbc->ePBCDX = epbcdx1D_RECT;
                for (i = 0; i < DIM; i++)
                {
                    if (bPBC[i])
                    {
                        pbc->dim = i;
                    }
                }
                for (i = 0; i < pbc->dim; i++)
                {
                    if (pbc->box[pbc->dim][i] != 0)
                    {
                        pbc->ePBCDX = epbcdx1D_TRIC;
                    }
                }
                break;
            case 2:
                pbc->ePBCDX = epbcdx2D_RECT;
                for (i = 0; i < DIM; i++)
                {
                    if (!bPBC[i])
                    {
                        pbc->dim = i;
                    }
                }
                for (i = 0; i < DIM; i++)
                {
                    if (bPBC[i])
                    {
                        for (j = 0; j < i; j++)
                        {
                            if (pbc->box[i][j] != 0)
                            {
                                pbc->ePBCDX = epbcdx2D_TRIC;
                            }
                        }
                    }
                }
                break;
            case 3:
                if (ePBC != epbcSCREW)
                {
                    if (TRICLINIC(box))
                    {
                        pbc->ePBCDX = epbcdxTRICLINIC;
                    }
                    else
                    {
                        pbc->ePBCDX = epbcdxRECTANGULAR;
                    }
                }
                else
                {
                    pbc->ePBCDX = (box[ZZ][YY] == 0 ? epbcdxSCREW_RECT : epbcdxSCREW_TRIC);
                    if (pbc->ePBCDX == epbcdxSCREW_TRIC)
                    {
                        fprintf(stderr,
                                "Screw pbc is not yet implemented for triclinic boxes.\n"
                                "Can not fix pbc.\n");
                        pbc->ePBCDX = epbcdxUNSUPPORTED;
                    }
                }
                break;
            default:
                gmx_fatal(FARGS, "Incorrect number of pbc dimensions with DD: %d",
                          npbcdim);
        }
        pbc->max_cutoff2 = max_cutoff2(ePBC, box);

        if (pbc->ePBCDX == epbcdxTRICLINIC ||
            pbc->ePBCDX == epbcdx2D_TRIC ||
            pbc->ePBCDX == epbcdxSCREW_TRIC)
        {
            if (debug)
            {
                pr_rvecs(debug, 0, "Box", box, DIM);
                fprintf(debug, "max cutoff %.3f\n", sqrt(pbc->max_cutoff2));
            }
            pbc->ntric_vec = 0;
            /* We will only use single shifts, but we will check a few
             * more shifts to see if there is a limiting distance
             * above which we can not be sure of the correct distance.
             */
            for (kk = 0; kk < 5; kk++)
            {
                k = order[kk];
                if (!bPBC[ZZ] && k != 0)
                {
                    continue;
                }
                for (jj = 0; jj < 5; jj++)
                {
                    j = order[jj];
                    if (!bPBC[YY] && j != 0)
                    {
                        continue;
                    }
                    for (ii = 0; ii < 3; ii++)
                    {
                        i = order[ii];
                        if (!bPBC[XX] && i != 0)
                        {
                            continue;
                        }
                        /* A shift is only useful when it is trilinic */
                        if (j != 0 || k != 0)
                        {
                            d2old = 0;
                            d2new = 0;
                            for (d = 0; d < DIM; d++)
                            {
                                trial[d] = i*box[XX][d] + j*box[YY][d] + k*box[ZZ][d];
                                /* Choose the vector within the brick around 0,0,0 that
                                 * will become the shortest due to shift try.
                                 */
                                if (d == pbc->dim)
                                {
                                    trial[d] = 0;
                                    pos[d]   = 0;
                                }
                                else
                                {
                                    if (trial[d] < 0)
                                    {
                                        pos[d] = min( pbc->hbox_diag[d], -trial[d]);
                                    }
                                    else
                                    {
                                        pos[d] = max(-pbc->hbox_diag[d], -trial[d]);
                                    }
                                }
                                d2old += sqr(pos[d]);
                                d2new += sqr(pos[d] + trial[d]);
                            }
                            if (BOX_MARGIN*d2new < d2old)
                            {
                                if (j < -1 || j > 1 || k < -1 || k > 1)
                                {
                                    /* Check if there is a single shift vector
                                     * that decreases this distance even more.
                                     */
                                    jc = 0;
                                    kc = 0;
                                    if (j < -1 || j > 1)
                                    {
                                        jc = j/2;
                                    }
                                    if (k < -1 || k > 1)
                                    {
                                        kc = k/2;
                                    }
                                    d2new_c = 0;
                                    for (d = 0; d < DIM; d++)
                                    {
                                        d2new_c += sqr(pos[d] + trial[d]
                                                       - jc*box[YY][d] - kc*box[ZZ][d]);
                                    }
                                    if (d2new_c > BOX_MARGIN*d2new)
                                    {
                                        /* Reject this shift vector, as there is no a priori limit
                                         * to the number of shifts that decrease distances.
                                         */
                                        if (!pbc->bLimitDistance || d2new <  pbc->limit_distance2)
                                        {
                                            pbc->limit_distance2 = d2new;
                                        }
                                        pbc->bLimitDistance = TRUE;
                                    }
                                }
                                else
                                {
                                    /* Check if shifts with one box vector less do better */
                                    bUse = TRUE;
                                    for (dd = 0; dd < DIM; dd++)
                                    {
                                        shift = (dd == 0 ? i : (dd == 1 ? j : k));
                                        if (shift)
                                        {
                                            d2new_c = 0;
                                            for (d = 0; d < DIM; d++)
                                            {
                                                d2new_c += sqr(pos[d] + trial[d] - shift*box[dd][d]);
                                            }
                                            if (d2new_c <= BOX_MARGIN*d2new)
                                            {
                                                bUse = FALSE;
                                            }
                                        }
                                    }
                                    if (bUse)
                                    {
                                        /* Accept this shift vector. */
                                        if (pbc->ntric_vec >= MAX_NTRICVEC)
                                        {
                                            fprintf(stderr, "\nWARNING: Found more than %d triclinic correction vectors, ignoring some.\n"
                                                    "  There is probably something wrong with your box.\n", MAX_NTRICVEC);
                                            pr_rvecs(stderr, 0, "         Box", box, DIM);
                                        }
                                        else
                                        {
                                            copy_rvec(trial, pbc->tric_vec[pbc->ntric_vec]);
                                            pbc->tric_shift[pbc->ntric_vec][XX] = i;
                                            pbc->tric_shift[pbc->ntric_vec][YY] = j;
                                            pbc->tric_shift[pbc->ntric_vec][ZZ] = k;
                                            pbc->ntric_vec++;
                                        }
                                    }
                                }
                                if (debug)
                                {
                                    fprintf(debug, "  tricvec %2d = %2d %2d %2d  %5.2f %5.2f  %5.2f %5.2f %5.2f  %5.2f %5.2f %5.2f\n",
                                            pbc->ntric_vec, i, j, k,
                                            sqrt(d2old), sqrt(d2new),
                                            trial[XX], trial[YY], trial[ZZ],
                                            pos[XX], pos[YY], pos[ZZ]);
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
Example #6
0
//! Do the real arithmetic for filling the pbc struct
static void low_set_pbc(t_pbc *pbc, int ePBC,
                        const ivec dd_pbc, const matrix box)
{
    int         order[3] = { 0, -1, 1 };
    ivec        bPBC;
    const char *ptr;

    pbc->ePBC      = ePBC;
    pbc->ndim_ePBC = ePBC2npbcdim(ePBC);

    copy_mat(box, pbc->box);
    pbc->max_cutoff2    = 0;
    pbc->dim            = -1;
    pbc->ntric_vec      = 0;

    for (int i = 0; (i < DIM); i++)
    {
        pbc->fbox_diag[i]  =  box[i][i];
        pbc->hbox_diag[i]  =  pbc->fbox_diag[i]*0.5;
        pbc->mhbox_diag[i] = -pbc->hbox_diag[i];
    }

    ptr = check_box(ePBC, box);
    if (ePBC == epbcNONE)
    {
        pbc->ePBCDX = epbcdxNOPBC;
    }
    else if (ptr)
    {
        fprintf(stderr,   "Warning: %s\n", ptr);
        pr_rvecs(stderr, 0, "         Box", box, DIM);
        fprintf(stderr,   "         Can not fix pbc.\n\n");
        pbc->ePBCDX = epbcdxUNSUPPORTED;
    }
    else
    {
        if (ePBC == epbcSCREW && NULL != dd_pbc)
        {
            /* This combinated should never appear here */
            gmx_incons("low_set_pbc called with screw pbc and dd_nc != NULL");
        }

        int npbcdim = 0;
        for (int i = 0; i < DIM; i++)
        {
            if ((dd_pbc && dd_pbc[i] == 0) || (ePBC == epbcXY && i == ZZ))
            {
                bPBC[i] = 0;
            }
            else
            {
                bPBC[i] = 1;
                npbcdim++;
            }
        }
        switch (npbcdim)
        {
            case 1:
                /* 1D pbc is not an mdp option and it is therefore only used
                 * with single shifts.
                 */
                pbc->ePBCDX = epbcdx1D_RECT;
                for (int i = 0; i < DIM; i++)
                {
                    if (bPBC[i])
                    {
                        pbc->dim = i;
                    }
                }
                GMX_ASSERT(pbc->dim < DIM, "Dimension for PBC incorrect");
                for (int i = 0; i < pbc->dim; i++)
                {
                    if (pbc->box[pbc->dim][i] != 0)
                    {
                        pbc->ePBCDX = epbcdx1D_TRIC;
                    }
                }
                break;
            case 2:
                pbc->ePBCDX = epbcdx2D_RECT;
                for (int i = 0; i < DIM; i++)
                {
                    if (!bPBC[i])
                    {
                        pbc->dim = i;
                    }
                }
                for (int i = 0; i < DIM; i++)
                {
                    if (bPBC[i])
                    {
                        for (int j = 0; j < i; j++)
                        {
                            if (pbc->box[i][j] != 0)
                            {
                                pbc->ePBCDX = epbcdx2D_TRIC;
                            }
                        }
                    }
                }
                break;
            case 3:
                if (ePBC != epbcSCREW)
                {
                    if (TRICLINIC(box))
                    {
                        pbc->ePBCDX = epbcdxTRICLINIC;
                    }
                    else
                    {
                        pbc->ePBCDX = epbcdxRECTANGULAR;
                    }
                }
                else
                {
                    pbc->ePBCDX = (box[ZZ][YY] == 0 ? epbcdxSCREW_RECT : epbcdxSCREW_TRIC);
                    if (pbc->ePBCDX == epbcdxSCREW_TRIC)
                    {
                        fprintf(stderr,
                                "Screw pbc is not yet implemented for triclinic boxes.\n"
                                "Can not fix pbc.\n");
                        pbc->ePBCDX = epbcdxUNSUPPORTED;
                    }
                }
                break;
            default:
                gmx_fatal(FARGS, "Incorrect number of pbc dimensions with DD: %d",
                          npbcdim);
        }
        pbc->max_cutoff2 = max_cutoff2(ePBC, box);

        if (pbc->ePBCDX == epbcdxTRICLINIC ||
            pbc->ePBCDX == epbcdx2D_TRIC ||
            pbc->ePBCDX == epbcdxSCREW_TRIC)
        {
            if (debug)
            {
                pr_rvecs(debug, 0, "Box", box, DIM);
                fprintf(debug, "max cutoff %.3f\n", sqrt(pbc->max_cutoff2));
            }
            /* We will only need single shifts here */
            for (int kk = 0; kk < 3; kk++)
            {
                int k = order[kk];
                if (!bPBC[ZZ] && k != 0)
                {
                    continue;
                }
                for (int jj = 0; jj < 3; jj++)
                {
                    int j = order[jj];
                    if (!bPBC[YY] && j != 0)
                    {
                        continue;
                    }
                    for (int ii = 0; ii < 3; ii++)
                    {
                        int i = order[ii];
                        if (!bPBC[XX] && i != 0)
                        {
                            continue;
                        }
                        /* A shift is only useful when it is trilinic */
                        if (j != 0 || k != 0)
                        {
                            rvec trial;
                            rvec pos;
                            real d2old = 0;
                            real d2new = 0;

                            for (int d = 0; d < DIM; d++)
                            {
                                trial[d] = i*box[XX][d] + j*box[YY][d] + k*box[ZZ][d];
                                /* Choose the vector within the brick around 0,0,0 that
                                 * will become the shortest due to shift try.
                                 */
                                if (d == pbc->dim)
                                {
                                    trial[d] = 0;
                                    pos[d]   = 0;
                                }
                                else
                                {
                                    if (trial[d] < 0)
                                    {
                                        pos[d] = std::min( pbc->hbox_diag[d], -trial[d]);
                                    }
                                    else
                                    {
                                        pos[d] = std::max(-pbc->hbox_diag[d], -trial[d]);
                                    }
                                }
                                d2old += gmx::square(pos[d]);
                                d2new += gmx::square(pos[d] + trial[d]);
                            }
                            if (BOX_MARGIN*d2new < d2old)
                            {
                                /* Check if shifts with one box vector less do better */
                                gmx_bool bUse = TRUE;
                                for (int dd = 0; dd < DIM; dd++)
                                {
                                    int shift = (dd == 0 ? i : (dd == 1 ? j : k));
                                    if (shift)
                                    {
                                        real d2new_c = 0;
                                        for (int d = 0; d < DIM; d++)
                                        {
                                            d2new_c += gmx::square(pos[d] + trial[d] - shift*box[dd][d]);
                                        }
                                        if (d2new_c <= BOX_MARGIN*d2new)
                                        {
                                            bUse = FALSE;
                                        }
                                    }
                                }
                                if (bUse)
                                {
                                    /* Accept this shift vector. */
                                    if (pbc->ntric_vec >= MAX_NTRICVEC)
                                    {
                                        fprintf(stderr, "\nWARNING: Found more than %d triclinic correction vectors, ignoring some.\n"
                                                "  There is probably something wrong with your box.\n", MAX_NTRICVEC);
                                        pr_rvecs(stderr, 0, "         Box", box, DIM);
                                    }
                                    else
                                    {
                                        copy_rvec(trial, pbc->tric_vec[pbc->ntric_vec]);
                                        pbc->tric_shift[pbc->ntric_vec][XX] = i;
                                        pbc->tric_shift[pbc->ntric_vec][YY] = j;
                                        pbc->tric_shift[pbc->ntric_vec][ZZ] = k;
                                        pbc->ntric_vec++;

                                        if (debug)
                                        {
                                            fprintf(debug, "  tricvec %2d = %2d %2d %2d  %5.2f %5.2f  %5.2f %5.2f %5.2f  %5.2f %5.2f %5.2f\n",
                                                    pbc->ntric_vec, i, j, k,
                                                    sqrt(d2old), sqrt(d2new),
                                                    trial[XX], trial[YY], trial[ZZ],
                                                    pos[XX], pos[YY], pos[ZZ]);
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}