///////////////////////////////////////////////////////////////////////
// Driver
int main(int argc, char* argv[]) {
  if (argc < 11 || argc > 13) {
    printf("Make a mask set to 1 for grid nodes within radius of any point.\n");
    printf("Usage: %s srcGrid pointFile paramFile epsilonDest Rmin2Dest switchDist cutoffDist Vmax blurCount [both | 6 | 12  [x | y | z | xy | xyz]] outFile\n", argv[0]);
    return 0;
  }

  const char* srcFile = argv[1];
  const char* pointFile = argv[2];
  const char* paramFile = argv[3];
  const double epsilonDest = strtod(argv[4], NULL);
  const double Rmin2Dest = strtod(argv[5], NULL);
  const double switchDist = strtod(argv[6], NULL);
  const double cutoffDist = strtod(argv[7], NULL);
  double Vmax = strtod(argv[8], NULL);
  const int blurCount = atoi(argv[9]);
  const char *component = (argc > 11) ? argv[10] : "";
  const char* wrap = (argc > 12) ? argv[11] : "";
  const char* outFile = argv[argc-1];
  
  // Figure out which LJ component to output
  // ljcomp = 0 : combined
  // ljcomp = 1 : 6
  // ljcomp = 2 : 12
  const int ljcomp = (strcmp(component, "12") == 0) ? 2 : (strcmp(component, "6") == 0) ? 1 : 0;
  if (ljcomp == 2) {
      // If we're doing the '12' component, double 'Vmax'. We do this
      // because -1 * 'Vmax' is used for the lower bound of the 6
      // component, so if we just used 'Vmax' for the 12 component,
      // and if both component are pegged, then they add to zero,
      // which is bad
      Vmax *= 2;
  }
  
  // Figure out wrapping situation
  bool wrapX = false, wrapY = false, wrapZ = false;
  for (unsigned int i = 0; i < strlen(wrap); i++) {
      wrapX = wrapX || (tolower(wrap[i]) == 'x');
      wrapY = wrapY || (tolower(wrap[i]) == 'y');
      wrapZ = wrapZ || (tolower(wrap[i]) == 'z');
  }
  printf("Wrapping X Y Z = %d %d %d\n", wrapX, wrapY, wrapZ);
  
  // Load the grids.
  Grid src(srcFile);
  src.zero();
  int n = src.length();
  printf("Loaded `%s' which contains %d nodes.\n", srcFile, n); 
  
  // Load the coordinates.
  printf("Loading the coordinates.\n");
  Scatter pos(pointFile);
  printf("Loaded %d points from `%s'.\n", pos.length(), pointFile);
  
  // Load LJ parameters
  printf("Loading the source parameters.\n");
  Scatter param(paramFile);
  printf("Loaded %d points from `%s'.\n", param.length(), paramFile);
  
  // Generate the cell decomposition.
  double cutoff = 1.2*cutoffDist;
  Matrix3 sys = src.getBox();
  Vector3 origin = src.getOrigin();
  printf("\nGenerating cell decomposition for %s with cutoff = %.10g...\n", argv[1], cutoff);
  CellDecomposition cell(sys, origin, cutoff);
  printf("Cell decomposition of %i cells\n", cell.length());
  cell.decompose(pos);
  printf("Cell decomposition contains %i points\n", cell.countPoints());
  
  printf("cutoffDist = %f\n", cutoffDist);
  
  // Make the mask.
  Grid mask(src);
  int counter = 0;
  int complete = 0;
#pragma omp parallel for
  for (int i = 0; i < n; i++) {
    Vector3 r = src.getPosition(i);
    // Get the indices (in pos) of possible neighboring points.
    IndexList neigh = cell.neighborhood(r);
    const int nNeighs = neigh.length();

    for (int j = 0; j < nNeighs; j++) {
      // Get the position of each possible neighboring point.
      Vector3 p = pos.get(neigh.get(j));
      if (within(p, r, cutoffDist, src)) {
	// wrap selected directions
	Vector3 d1 = p - r;
 	Vector3 d2 = src.wrapDiff(p - r);
	Vector3 d = Vector3(wrapX ? d2.x : d1.x,
			    wrapY ? d2.y : d1.y,
			    wrapZ ? d2.z : d1.z);
	
	double R = d.length();
	Vector3 par = param.get(neigh.get(j));
	double ignored = par.x;
	double epsilon = par.y;
	double Rmin2 = par.z;
	//printf("got epsilon = %f Rmin2 = %f\n", epsilon, Rmin2);
	double val = (Rmin2 + Rmin2Dest) / R;
	double V = mask.getValue(i);
	double V_curr;
	switch (ljcomp) {
	case 0:
	    // both
	    V_curr = sqrt(epsilon * epsilonDest) * (pow(val, 12) - 2 * pow(val, 6));
	    break;
	case 1:
	    // 6 component
	    V_curr = sqrt(epsilon * epsilonDest) * - 2 * pow(val, 6);
	    break;
	case 2:
	    // 12 component
	    V_curr = sqrt(epsilon * epsilonDest) * pow(val, 12);
	    break;
	}
	//printf("%d: R = %f ep = %f epD = %f Rmin2 = %f Rmin2D = %f V = %f\n", neigh.get(j), R, epsilon, epsilonDest, Rmin2, Rmin2Dest, V_curr);
	if (R >= switchDist) {
	    double RR = (R - switchDist)/(cutoffDist - switchDist);
	    V_curr *= 1 + RR*RR * (2*RR - 3);
	}
	
	double V_new = (V + V_curr > Vmax) ? Vmax : (V + V_curr < -Vmax) ? -Vmax : V + V_curr;
	mask.setValue(i, V_new);
	//break;
      }
    }

    // Write the progress.
#pragma omp critical
    {
	int comp = (100*(long)counter)/n;
	if (abs(complete - comp) >= 5) {
	    printf("%d percent complete\n", comp);
	    complete = comp;
	}
	counter++;
    }
  }

  // Blur.
  for (int j = 0; j < blurCount; j++) mask.blur();

  char comments[256];
  sprintf(comments, "%s patched", srcFile);
  mask.write(outFile, comments);
  printf("Wrote `%s'.\n", outFile);

  return 0;
}
Example #2
0
///////////////////////////////////////////////////////////////////////
// Driver
int main(int argc, char* argv[]) {
 if ( argc != 11 && argc != 10) {
    printf("Usage: %s srcGrid poreLength poreDiamX poreDiamY cornerRad wellWidth wellDepth barrierHeight [surfWidth] outGrid\n", argv[0]);
    printf("If `surfWidth' is specified, then the upper and lower membrane surfaces only barriers. The pore is unaffected.\n");
    return 0;
  }

  const char* srcGrid = argv[1];
  const char* outGrid = argv[argc-1];

  const double poreLength = strtod(argv[2], NULL);
  const double poreDiamX = strtod(argv[3], NULL);
  const double poreDiamY = strtod(argv[4], NULL);
  const double cornerRad = strtod(argv[5], NULL);
  const double wellWidth = strtod(argv[6], NULL);
  const double wellDepth = strtod(argv[7], NULL);
  const double barrierHeight = strtod(argv[8], NULL);
  const double surfWidth = strtod(argv[9], NULL);
  bool surfBarrier = (argc == 11);

  CylinderPore pore(poreLength, poreDiamX, poreDiamY, cornerRad);

  //double wallShift = wellWidth*1.5;
  WallEnergy wall(-fabs(wellWidth), -0.5*fabs(wellWidth), -fabs(wellDepth), 0.0, barrierHeight);
  WallEnergy wallSurf(-fabs(surfWidth), -0.5*fabs(surfWidth), 0.0, 0.0, barrierHeight);

  // Load the grid.
  Grid src(srcGrid);
  printf("Loaded the grid `%s'.\n", srcGrid);

  // Mark the pore.
  printf("Marking the pore...\n");
  const int n = src.length();
  for (int i = 0; i < n; i++) {
    Vector3 r = src.wrapDiffNearest(src.getPosition(i));
    
    if (pore.in(r)) src.setValue(i, 1.0);
    else src.setValue(i, 0.0);
  }
  src.write("test.dx");

  // Find the surface.
  printf("Marking the surface...\n");
  Grid surf(src);
  surf.blur();
  int surfNum = 0;
  for (int i = 0; i < n; i++) {
    double v = surf.getValue(i);
    if (v > 0.01 && v < 0.99) { 
      surf.setValue(i, 1.0);
      surfNum++;
    }
    else surf.setValue(i, 0.0);
  }

  // Write the surface grid.
  char outSurf[256];
  sprintf(outSurf, "surf_%s", outGrid);
  surf.write(outSurf, "surface");
  printf("Wrote the surface `%s'.\n", outSurf);

  // Make a list of surface positions.
  Vector3* surfPos = new Vector3[surfNum];
  int j = 0; 
  for (int i = 0; i < n; i++) {
    if (surf.getValue(i) > 0.0) {
      surfPos[j] = surf.getPosition(i);
      j++;
    }
  }
  printf("Extracted %d surface nodes.\n", surfNum);

  // Generate the cell decomposition.
  double cutoff = 1.5*wellWidth;
  Matrix3 sys = src.getBox();
  Vector3 origin = src.getOrigin();
  printf("\nGenerating cell decomposition for %s with cutoff = %.10g...\n", argv[1], cutoff);
  CellDecomposition cell(sys, origin, cutoff);
  printf("Cell decomposition of %i cells\n", cell.length());
  cell.decompose(surfPos, surfNum);
  printf("Cell decomposition contains %i points\n", cell.countPoints());

  // Now go through the grid to create the output potential.
  Grid dest(src);
  int complete = 0;
  for (int i = 0; i < n; i++) {
    double v = src.getValue(i);
    // If the position is inside the membrane, set it to the max value.
    if (v > 0.0) {
      dest.setValue(i, barrierHeight);
      continue;
    }

    // Find the distance to the surface.
    Vector3 r = src.getPosition(i);
    // Get the indices (in pos) of possible neighboring points.
    IndexList neigh = cell.neighborhood(r);
    const int nNeighs = neigh.length();
    if (nNeighs < 1) {
      dest.setValue(i, 0.0);
      continue;
    }

    // Find the minimum distance to a surface point.
    Vector3 d =  src.wrapDiffNearest(surfPos[neigh.get(0)] - r);
    double minDist = d.length();
    for (int j = 1; j < nNeighs; j++) {
      Vector3 d = src.wrapDiffNearest(surfPos[neigh.get(j)] - r);
      if (d.length() < minDist) minDist = d.length();
    }
    
    // Set the value using the WallEnergy function.
    if (surfBarrier) {
      double w = pore.surfaceWeight(r);
      dest.setValue(i, (1.0-w)*wall.energy(-minDist) + w*wallSurf.hardEnergy(-minDist));
    }
    else dest.setValue(i, wall.energy(-minDist));

    // Write the progress.
    int comp = (100*i)/n;
    if (abs(complete - comp) >= 5) {
      printf("%d percent complete\n", comp);
      complete = comp;
    }
  } 

  delete[] surfPos;

  char comments[256];
  sprintf(comments, "poreLength %g poreDiamX %g poreDiamY %g cornerRad %g wellWidth %g wellDepth %g barrierHeight %g", poreLength, poreDiamX, poreDiamY, cornerRad, wellWidth, wellDepth, barrierHeight);
  dest.write(outGrid, comments);
  printf("Wrote `%s'.\n", outGrid);

  return 0;
}