Exemple #1
0
void PairCompute::doWork(PatchList *patchList) {

    Patch *p1 = &(patchList->patches[patchId1]);
    Patch *p2 = &(patchList->patches[patchId2]);
    int doEnergy = patchList->doEnergy;
    nonbonded params;
    params.p[0] = p1->image(image1,patchList->lattice);
    params.p[1] = p2->image(image2,patchList->lattice);
    params.ff[0] = p1->f_nbond;
    params.ff[1] = p2->f_nbond;
    params.numAtoms[0] = p1->numAtoms;
    params.numAtoms[1] = p2->numAtoms;
    params.reduction = patchList->reductionData;
    params.pressureProfileReduction = 0;

    params.minPart = 0; // minPart;
    params.maxPart = 1; // maxPart;
    params.numParts = 1; // numParts;

    if ( patchList->doFull ) {
      params.fullf[0] = p1->f_slow;
      params.fullf[1] = p2->f_slow;
      if ( patchList->doMerge ) {
        if ( doEnergy ) calcMergePairEnergy(&params);
        else calcMergePair(&params);
      } else {
        if ( doEnergy ) calcFullPairEnergy(&params);
        else calcFullPair(&params);
      }
    }
    else
      if ( doEnergy ) calcPairEnergy(&params);
      else calcPair(&params);

}
int ComputeNonbondedPair::noWork() {

  if (patch[0]->flags.doGBIS) {
    gbisPhase = 1 + (gbisPhase % 3);//1->2->3->1...
  }

#ifndef NAMD_CUDA
  if ( patch[0]->flags.doNonbonded && (numAtoms[0] && numAtoms[1]) ) {
    return 0;  // work to do, enqueue as usual
  } else {
#else
  {
#endif

    if (patch[0]->flags.doGBIS) {
     if (gbisPhase == 1) {
      for (int i=0; i<2; i++) {
        psiSumBox[i]->skip();
        intRadBox[i]->skip();
      }
      if (patch[0]->flags.doNonbonded) return 1;
      else gbisPhase = 2;
     }
     if (gbisPhase == 2) {
      for (int i=0; i<2; i++) {
        bornRadBox[i]->skip();
        dEdaSumBox[i]->skip();
      }
      if (patch[0]->flags.doNonbonded) return 1;
      else gbisPhase = 3;
     }
     if (gbisPhase == 3) {
      for (int i=0; i<2; i++) {
        dHdrPrefixBox[i]->skip();
      }
     }
    }

    // skip all boxes
    for (int i=0; i<2; i++) {
      positionBox[i]->skip();
      forceBox[i]->skip();
      if ( patch[0]->flags.doMolly ) avgPositionBox[i]->skip();
      // BEGIN LA
      if (patch[0]->flags.doLoweAndersen) velocityBox[i]->skip();
      // END LA
    }

    reduction->item(REDUCTION_COMPUTE_CHECKSUM) += 1.;
    reduction->submit();
    if (accelMDOn) amd_reduction->submit();
    if (pressureProfileOn) 
      pressureProfileReduction->submit();

#ifndef NAMD_CUDA
    // Inform load balancer
    LdbCoordinator::Object()->skipWork(ldObjHandle);
#endif

    return 1;  // no work to do, do not enqueue
  }
}

void ComputeNonbondedPair::doForce(CompAtom* p[2], CompAtomExt* pExt[2], Results* r[2])
{
  // Inform load balancer. 
  // I assume no threads will suspend until endWork is called

  //single phase declarations
  int doEnergy = patch[0]->flags.doEnergy;
  int a = 0;  int b = 1;
  // swap to place more atoms in inner loop (second patch)
  if ( numAtoms[0] > numAtoms[1] ) { a = 1; b = 0; }
  CompAtom* v[2];


/*******************************************************************************
 * Prepare Parameters
*******************************************************************************/
  if (!patch[0]->flags.doGBIS || gbisPhase == 1) {

#ifdef TRACE_COMPUTE_OBJECTS
    double traceObjStartTime = CmiWallTimer();
#endif

  DebugM(2,"doForce() called.\n");
  DebugM(2, numAtoms[0] << " patch #1 atoms and " <<
	numAtoms[1] << " patch #2 atoms\n");


  for ( int i = 0; i < reductionDataSize; ++i )
    reductionData[i] = 0;
  if (pressureProfileOn) {
    int n = pressureProfileAtomTypes; 
    memset(pressureProfileData, 0, 3*n*n*pressureProfileSlabs*sizeof(BigReal));
    // adjust lattice dimensions to allow constant pressure
    const Lattice &lattice = patch[0]->lattice;
    pressureProfileThickness = lattice.c().z / pressureProfileSlabs;
    pressureProfileMin = lattice.origin().z - 0.5*lattice.c().z;
  }

    params.reduction = reductionData;
    params.pressureProfileReduction = pressureProfileData;

    params.minPart = minPart;
    params.maxPart = maxPart;
    params.numParts = numParts;

    params.workArrays = workArrays;

    params.pairlists = &pairlists;
    params.savePairlists = 0;
    params.usePairlists = 0;
    if ( patch[0]->flags.savePairlists ) {
      params.savePairlists = 1;
      params.usePairlists = 1;
    } else if ( patch[0]->flags.usePairlists && patch[1]->flags.usePairlists ) {
      if ( ! pairlistsValid ||
           ( patch[0]->flags.maxAtomMovement +
             patch[1]->flags.maxAtomMovement > pairlistTolerance ) ) {
        reductionData[pairlistWarningIndex] += 1;
      } else {
        params.usePairlists = 1;
      }
    }
    if ( ! params.usePairlists ) {
      pairlistsValid = 0;
    }
    params.plcutoff = cutoff;
    params.groupplcutoff = cutoff +
	patch[0]->flags.maxGroupRadius + patch[1]->flags.maxGroupRadius;
    if ( params.savePairlists ) {
      pairlistsValid = 1;
      pairlistTolerance = patch[0]->flags.pairlistTolerance +
                          patch[1]->flags.pairlistTolerance;
      params.plcutoff += pairlistTolerance;
      params.groupplcutoff += pairlistTolerance;
    }


    const Lattice &lattice = patch[0]->lattice;
    params.offset = lattice.offset(trans[a]) - lattice.offset(trans[b]);

    // Atom Sorting : If we are sorting the atoms along the line connecting
    //   the patch centers, then calculate a normalized vector pointing from
    //   patch a to patch b (i.e. outer loop patch to inner loop patch).
    #if NAMD_ComputeNonbonded_SortAtoms != 0

      // Center of patch a (outer-loop; i-loop) and patch b (inner-loop; j/k-loop)
      PatchMap* patchMap = PatchMap::Object();
      ScaledPosition p_a_center, p_b_center;
      p_a_center.x = patchMap->min_a(patchID[a]);
      p_a_center.y = patchMap->min_b(patchID[a]);
      p_a_center.z = patchMap->min_c(patchID[a]);
      p_b_center.x = patchMap->min_a(patchID[b]);
      p_b_center.y = patchMap->min_b(patchID[b]);
      p_b_center.z = patchMap->min_c(patchID[b]);
      p_a_center.x += patchMap->max_a(patchID[a]);
      p_a_center.y += patchMap->max_b(patchID[a]);
      p_a_center.z += patchMap->max_c(patchID[a]);
      p_b_center.x += patchMap->max_a(patchID[b]);
      p_b_center.y += patchMap->max_b(patchID[b]);
      p_b_center.z += patchMap->max_c(patchID[b]);
      p_a_center *= (BigReal)0.5;
      p_b_center *= (BigReal)0.5;
      p_a_center = lattice.unscale(p_a_center);
      p_b_center = lattice.unscale(p_b_center);

      // Adjust patch a's center by the offset
      p_a_center.x += params.offset.x;
      p_a_center.y += params.offset.y;
      p_a_center.z += params.offset.z;

      // Calculate and fill in the projected line vector
      params.projLineVec = p_b_center - p_a_center;
      params.projLineVec /= params.projLineVec.length(); // Normalize the vector

    #endif

      params.p[0] = p[a];
      params.p[1] = p[b];
      params.pExt[0] = pExt[a]; 
      params.pExt[1] = pExt[b];
      // BEGIN LA
      params.doLoweAndersen = patch[0]->flags.doLoweAndersen;
      if (params.doLoweAndersen) {
	  DebugM(4, "opening velocity boxes\n");
	  v[0] = velocityBox[0]->open();
	  v[1] = velocityBox[1]->open();
	  params.v[0] = v[a];
	  params.v[1] = v[b];
      }
      // END LA
      params.ff[0] = r[a]->f[Results::nbond];
      params.ff[1] = r[b]->f[Results::nbond];
      params.numAtoms[0] = numAtoms[a];
      params.numAtoms[1] = numAtoms[b];

      // DMK - Atom Separation (water vs. non-water)
      #if NAMD_SeparateWaters != 0
        params.numWaterAtoms[0] = numWaterAtoms[a];
        params.numWaterAtoms[1] = numWaterAtoms[b];
      #endif


/*******************************************************************************
 * Call Nonbonded Functions
*******************************************************************************/
      if (numAtoms[0] && numAtoms[1]) {//only do if has atoms since gbis noWork doesn't account for no atoms

      //force calculation calls
      if ( patch[0]->flags.doFullElectrostatics )
      {
	params.fullf[0] = r[a]->f[Results::slow];
	params.fullf[1] = r[b]->f[Results::slow];
	if ( patch[0]->flags.doMolly ) {
          if ( doEnergy )
            calcPairEnergy(&params);
	  else calcPair(&params);
	  CompAtom *p_avg[2];
	  p_avg[0] = avgPositionBox[0]->open();
	  p_avg[1] = avgPositionBox[1]->open();
	  params.p[0] = p_avg[a];
	  params.p[1] = p_avg[b];
	  if ( doEnergy ) calcSlowPairEnergy(&params);
	  else calcSlowPair(&params);
	  avgPositionBox[0]->close(&p_avg[0]);
	  avgPositionBox[1]->close(&p_avg[1]);
        } else if ( patch[0]->flags.maxForceMerged == Results::slow ) {
          if ( doEnergy ) calcMergePairEnergy(&params);
    else calcMergePair(&params);
  } else {
    if ( doEnergy ) calcFullPairEnergy(&params);
    else calcFullPair(&params);
  }
      }
      else
        if ( doEnergy ) calcPairEnergy(&params);
        else calcPair(&params);

      }//end if has atoms
      
      // BEGIN LA
      if (params.doLoweAndersen) {
	  DebugM(4, "closing velocity boxes\n");
	  velocityBox[0]->close(&v[0]);
	  velocityBox[1]->close(&v[1]);
      }
      // END LA
    }// end not gbis

/*******************************************************************************
 * gbis Loop
*******************************************************************************/
if (patch[0]->flags.doGBIS) {
  SimParameters *simParams = Node::Object()->simParameters;
  gbisParams.sequence = sequence();
  gbisParams.doGBIS = patch[0]->flags.doGBIS;
  gbisParams.numPatches = 2;//pair
  gbisParams.gbisPhase = gbisPhase;
  gbisParams.doFullElectrostatics = patch[0]->flags.doFullElectrostatics;
  gbisParams.epsilon_s = simParams->solvent_dielectric;
  gbisParams.epsilon_p = simParams->dielectric;
  gbisParams.rho_0 = simParams->coulomb_radius_offset;
  gbisParams.kappa = simParams->kappa;
  gbisParams.cutoff = simParams->cutoff;
  gbisParams.doSmoothing = simParams->switchingActive;
  gbisParams.a_cut = simParams->alpha_cutoff;
  gbisParams.delta = simParams->gbis_delta;
  gbisParams.beta = simParams->gbis_beta;
  gbisParams.gamma = simParams->gbis_gamma;
  gbisParams.alpha_max = simParams->alpha_max;
  gbisParams.cid = cid;
  gbisParams.patchID[0] = patch[a]->getPatchID();
  gbisParams.patchID[1] = patch[b]->getPatchID();
  gbisParams.maxGroupRadius = patch[0]->flags.maxGroupRadius;
  if (patch[1]->flags.maxGroupRadius > gbisParams.maxGroupRadius)
    gbisParams.maxGroupRadius = patch[1]->flags.maxGroupRadius;
  gbisParams.doEnergy = doEnergy;
  gbisParams.fsMax = simParams->fsMax;
  for (int i = 0; i < numGBISPairlists; i++)
    gbisParams.gbisStepPairlists[i] = &gbisStepPairlists[i];

  //open boxes
  if (gbisPhase == 1) {
      gbisParams.intRad[0] = intRadBox[a]->open();
      gbisParams.intRad[1] = intRadBox[b]->open();
      gbisParams.psiSum[0] = psiSumBox[a]->open();
      gbisParams.psiSum[1] = psiSumBox[b]->open();
      gbisParams.gbInterEnergy=0;
      gbisParams.gbSelfEnergy=0;

  } else if (gbisPhase == 2) {
      gbisParams.bornRad[0] = bornRadBox[a]->open();
      gbisParams.bornRad[1] = bornRadBox[b]->open();
      gbisParams.dEdaSum[0] = dEdaSumBox[a]->open();
      gbisParams.dEdaSum[1] = dEdaSumBox[b]->open();
  } else if (gbisPhase == 3) {
      gbisParams.dHdrPrefix[0] = dHdrPrefixBox[a]->open();
      gbisParams.dHdrPrefix[1] = dHdrPrefixBox[b]->open();
  }

  //make call to calculate GBIS
  if ( !ComputeNonbondedUtil::commOnly ) {
    calcGBIS(&params,&gbisParams);
  }

  //close boxes
  if (gbisPhase == 1) {
      psiSumBox[0]->close(&(gbisParams.psiSum[a]));
      psiSumBox[1]->close(&(gbisParams.psiSum[b]));
  } else if (gbisPhase == 2) {
      dEdaSumBox[0]->close(&(gbisParams.dEdaSum[a]));
      dEdaSumBox[1]->close(&(gbisParams.dEdaSum[b]));


  } else if (gbisPhase == 3) {
      bornRadBox[0]->close(&(gbisParams.bornRad[a]));
      bornRadBox[1]->close(&(gbisParams.bornRad[b]));
      reduction->item(REDUCTION_ELECT_ENERGY) += gbisParams.gbInterEnergy;
      reduction->item(REDUCTION_ELECT_ENERGY) += gbisParams.gbSelfEnergy;
      intRadBox[0]->close(&(gbisParams.intRad[a]));
      intRadBox[1]->close(&(gbisParams.intRad[b]));
      dHdrPrefixBox[0]->close(&(gbisParams.dHdrPrefix[a]));
      dHdrPrefixBox[1]->close(&(gbisParams.dHdrPrefix[b]));
  }

}//end if doGBIS


  if (!patch[0]->flags.doGBIS || gbisPhase == 3) {
  submitReductionData(reductionData,reduction);
  if (accelMDOn) submitReductionData(reductionData,amd_reduction);
  if (pressureProfileOn)
    submitPressureProfileData(pressureProfileData, pressureProfileReduction);

#ifdef TRACE_COMPUTE_OBJECTS
    traceUserBracketEvent(TRACE_COMPOBJ_IDOFFSET+cid, traceObjStartTime, CmiWallTimer());
#endif


  reduction->submit();
  if (accelMDOn) amd_reduction->submit();
  if (pressureProfileOn)
    pressureProfileReduction->submit();
  }//end gbis end phase

}//end do Force