Example #1
0
void write_plotpot_pair(pot_table_t* pt, const char* filename)
{
  double r = 0.0;
  double r_step = 0.0;

  // open file
  FILE* outfile = fopen(filename, "w");
  if (outfile == NULL)
    error(1, "Could not open file %s for writing\n", filename);

#if !defined(APOT)
  int k = 0;

  // write pair data
  for (int i = 0; i < g_param.ntypes; i++) {
    for (int j = i; j < g_param.ntypes; j++) {
      r = pt->begin[k];
      r_step = (pt->end[k] - r) / (NPLOT - 1);
      for (int l = 0; l < NPLOT - 1; l++) {
        fprintf(outfile, "%e %e\n", r, splint_ne(pt, pt->table, k, r));
        r += r_step;
      }
      fprintf(outfile, "%e %e\n\n\n", r, 0.0);
      k++;
    }
  }

#if defined(EAM) || defined(ADP) || defined(MEAM)
  for (int i = g_calc.paircol; i < g_calc.paircol + g_param.ntypes; i++) {
    r = pt->begin[i];
    r_step = (pt->end[i] - pt->begin[i]) / (NPLOT - 1);
    for (int l = 0; l < NPLOT - 1; l++) {
      fprintf(outfile, "%e %e\n", r, splint_ne(pt, pt->table, i, r));
      r += r_step;
    }
    fprintf(outfile, "%e %e\n\n\n", r, 0.0);
  }
  for (int i = g_calc.paircol + g_param.ntypes;
       i < g_calc.paircol + 2 * g_param.ntypes; i++) {
    r = pt->begin[i];
    r_step = (pt->end[i] - pt->begin[i]) / (NPLOT - 1);
    for (int l = 0; l < NPLOT; l++) {
      fprintf(outfile, "%e %e\n", r, splint_ne(pt, pt->table, i, r));
      r += r_step;
    }
    fprintf(outfile, "\n\n\n");
  }
#endif  // EAM || ADP || MEAM

#if defined(MEAM)
  for (int i = g_calc.paircol; i < g_calc.paircol + g_param.ntypes; i++) {
    r = pt->begin[i];
    r_step = (pt->end[i] - pt->begin[i]) / (NPLOT - 1);
    for (int l = 0; l < NPLOT - 1; l++) {
      fprintf(outfile, "%e %e\n", r, splint_ne(pt, pt->table, i, r));
      r += r_step;
    }
    fprintf(outfile, "%e %e\n\n\n", r, 0.0);
  }
  for (int i = g_calc.paircol + g_param.ntypes;
       i < g_calc.paircol + 2 * g_param.ntypes; i++) {
    r = pt->begin[i];
    r_step = (pt->end[i] - pt->begin[i]) / (NPLOT - 1);
    for (int l = 0; l < NPLOT; l++) {
      fprintf(outfile, "%e %e\n", r, splint_ne(pt, pt->table, i, r));
      r += r_step;
    }
    fprintf(outfile, "\n\n\n");
  }
  for (int i = g_calc.paircol + 2 * g_param.ntypes;
       i < 2 * g_calc.paircol + 2 * g_param.ntypes; i++) {
    r = pt->begin[i];
    r_step = (pt->end[i] - pt->begin[i]) / (NPLOT - 1);
    for (int l = 0; l < NPLOT - 1; l++) {
      fprintf(outfile, "%e %e\n", r, splint_ne(pt, pt->table, i, r));
      r += r_step;
    }
    fprintf(outfile, "%e %e\n\n\n", r, 0.0);
  }
  for (int i = 2 * g_calc.paircol + 2 * g_param.ntypes;
       i < 2 * g_calc.paircol + 3 * g_param.ntypes; i++) {
    r = pt->begin[i];
    r_step = (pt->end[i] - pt->begin[i]) / (NPLOT - 1);
    for (int l = 0; l < NPLOT - 1; l++) {
      fprintf(outfile, "%e %e\n", r, splint_ne(pt, pt->table, i, r));
      r += r_step;
    }
    fprintf(outfile, "%e %e\n\n\n", r, 0.0);
  }
#endif  // MEAM

#if defined(ADP)
  for (int i = g_calc.paircol + 2 * g_param.ntypes;
       i < 2 * (g_calc.paircol + g_param.ntypes); i++) {
    r = pt->begin[i];
    r_step = (pt->end[i] - r) / (NPLOT - 1);
    for (int l = 0; l < NPLOT - 1; l++) {
      fprintf(outfile, "%e %e\n", r, splint_ne(pt, pt->table, i, r));
      r += r_step;
    }
    fprintf(outfile, "%e %e\n\n\n", r, 0.0);
  }
  for (int i = 2 * (g_calc.paircol + g_param.ntypes);
       i < 3 * g_calc.paircol + 2 * g_param.ntypes; i++) {
    r = pt->begin[i];
    r_step = (pt->end[i] - r) / (NPLOT - 1);
    for (int l = 0; l < NPLOT - 1; l++) {
      fprintf(outfile, "%e %e\n", r, splint_ne(pt, pt->table, i, r));
      r += r_step;
    }
    fprintf(outfile, "%e %e\n\n\n", r, 0.0);
  }
#endif  // ADP

#else   // APOT

  for (int i = 0; i < g_pot.apot_table.number; i++) {
    r = (g_param.plotmin == 0 ? 0.1 : g_param.plotmin);
    r_step = (g_pot.apot_table.end[i] - r) / (NPLOT - 1);
    double h = g_pot.apot_table.values[i][g_pot.apot_table.n_par[i] - 1];
    for (int j = 0; j < NPLOT; j++) {
      double temp = 0.0;

      (*g_pot.apot_table.fvalue[i])(r, g_pot.apot_table.values[i], &temp);

      if (g_pot.smooth_pot[i])
        temp *= apot_cutoff(r, g_pot.apot_table.end[i], h);

      if (isnan(temp))
        temp = 10e30;

      fprintf(outfile, "%e %e\n", r, temp);
      r += r_step;
    }
    if (i != (g_pot.apot_table.number - 1))
      fprintf(outfile, "\n\n");
  }
#endif  // APOT

  fclose(outfile);
  printf("Potential plotting data written to \t%s\n", filename);
}
Example #2
0
double rescale(pot_table_t* pt, double upper, int flag)
{
  int mincol, maxcol, col, col2, first, vals, h, i, j, typ1, typ2, sign;
  neigh_t* neigh = NULL;
  double fnval, pos, grad, a;
  double min = 1e100, max = -1e100;

  double* xi = pt->table;
  int dimneuxi = pt->last[g_calc.paircol + 2 * g_param.ntypes - 1] -
                 pt->last[g_calc.paircol + g_param.ntypes - 1];
  double* neuxi = (double*)malloc(dimneuxi * sizeof(double));
  double* neuord = (double*)malloc(dimneuxi * sizeof(double));
  double* neustep = (double*)malloc(g_param.ntypes * sizeof(double));
  double* maxrho = (double*)malloc(g_param.ntypes * sizeof(double));
  double* minrho = (double*)malloc(g_param.ntypes * sizeof(double));
  double* left = (double*)malloc(g_param.ntypes * sizeof(double));
  double* right = (double*)malloc(g_param.ntypes * sizeof(double));

  if (neuxi == NULL || neuord == NULL || neustep == NULL || maxrho == NULL ||
      minrho == NULL || left == NULL || right == NULL)
    error(1, "Error allocating memory for rescale function\n");

  for (i = 0; i < g_param.ntypes; i++) {
    maxrho[i] = -1e100;
    minrho[i] = 1e100;
  }

  /* find Max/Min rho  */
  /* init splines - better safe than sorry */
  /* init second derivatives for splines */
  for (col = 0; col < g_calc.paircol; col++) { /* just pair potentials */
    first = pt->first[col];
    if (g_pot.format_type == POTENTIAL_FORMAT_TABULATED_EQ_DIST)
      spline_ed(pt->step[col], pt->table + first, pt->last[col] - first + 1,
                *(pt->table + first - 2), 0.0, pt->d2tab + first);
    else /* format == 4 ! */
      spline_ne(pt->xcoord + first, pt->table + first,
                pt->last[col] - first + 1, *(pt->table + first - 2), 0.0,
                pt->d2tab + first);
  }
  for (col = g_calc.paircol; col < g_calc.paircol + g_param.ntypes;
       col++) { /* rho */
    first = pt->first[col];
    if (g_pot.format_type == POTENTIAL_FORMAT_TABULATED_EQ_DIST)
      spline_ed(pt->step[col], xi + first, pt->last[col] - first + 1,
                *(xi + first - 2), 0.0, pt->d2tab + first);
    else /* format == 4 ! */
      spline_ne(pt->xcoord + first, xi + first, pt->last[col] - first + 1,
                *(xi + first - 2), 0.0, pt->d2tab + first);
  }
  for (col = g_calc.paircol + g_param.ntypes;
       col < g_calc.paircol + 2 * g_param.ntypes; col++) { /* F */
    first = pt->first[col];
    /* gradient 0 at r_cut */
    if (g_pot.format_type == POTENTIAL_FORMAT_TABULATED_EQ_DIST)
      spline_ed(pt->step[col], xi + first, pt->last[col] - first + 1,
                *(xi + first - 2), *(xi + first - 1), pt->d2tab + first);
    else /* format == 4 */
      spline_ne(pt->xcoord + first, xi + first, pt->last[col] - first + 1,
                *(xi + first - 2), *(xi + first - 1), pt->d2tab + first);
  }

  /* re-calculate atom_rho (might be a waste...) */
  for (h = 0; h < g_config.nconf; h++) {
    for (i = 0; i < g_config.inconf[h]; i++)
      g_config.atoms[g_config.cnfstart[h] + i].rho = 0.0;
    for (i = 0; i < g_config.inconf[h]; i++) {
      atom_t* atom = g_config.atoms + i + g_config.cnfstart[h];
      typ1 = atom->type;
      for (j = 0; j < atom->num_neigh; j++) {
        neigh = atom->neigh + j;
        if (neigh->nr > i + g_config.cnfstart[h]) {
          typ2 = neigh->type;
          col2 = g_calc.paircol + typ2;
          if (typ2 == typ1) {
            if (neigh->r < pt->end[col2]) {
              fnval = splint_dir(pt, xi, neigh->slot[1], neigh->shift[1],
                                 neigh->step[1]);
              atom->rho += fnval;
              g_config.atoms[neigh->nr].rho += fnval;
            }
          } else {
            col = g_calc.paircol + typ1;
            if (neigh->r < pt->end[col2]) {
              atom->rho += splint_dir(pt, xi, neigh->slot[1], neigh->shift[1],
                                      neigh->step[1]);
            }
            if (neigh->r < pt->end[col])
              g_config.atoms[neigh->nr].rho +=
                  (*g_splint)(pt, xi, col, neigh->r);
          }
        }
      }
      maxrho[typ1] = MAX(maxrho[typ1], atom->rho);
      minrho[typ1] = MIN(minrho[typ1], atom->rho);
    }
  }
  for (i = 0; i < g_param.ntypes; i++) {
    if (maxrho[i] > max) {
      max = maxrho[i];
      maxcol = i;
    }
    if (minrho[i] < min) {
      min = minrho[i];
      mincol = i;
    }
  }
  /* determine dominant side */
  sign = (max >= -min) ? 1 : -1;

  /* determine new left and right boundary, add 40 percent... */
  for (i = 0; i < g_param.ntypes; i++) {
    j = g_calc.paircol + g_param.ntypes + i;
    left[i] = minrho[i] - 0.3 * pt->step[j];
    right[i] = maxrho[i] + 0.3 * pt->step[j];
    /* is expansion necessary? */
    if (flag || minrho[i] - pt->begin[j] < 0.0 ||
        minrho[i] - pt->begin[j] > 0.95 * pt->step[j] ||
        maxrho[i] - pt->end[j] > 0 ||
        maxrho[i] - pt->end[j] < -0.95 * pt->step[j])
      flag = 1;
  }

  /* determine scaling factor  */
  a = (sign == 1) ? upper / right[maxcol] : upper / left[mincol];

  if (flag || fabs(a) > 1.05 || fabs(a) < 0.95)
    flag = 1;

  /* update needed? */
  if (!flag)
    return 0.0; /* no */

  /* Let's update... */
  /* expand potential  */
  h = 0;
  for (i = 0; i < g_param.ntypes; i++) {
    col = g_calc.paircol + g_param.ntypes + i; /* 1. embedding function */
    vals = pt->last[col] - pt->first[col];
    neustep[i] = (right[i] - left[i]) / (double)vals;
    pos = left[i];
    for (j = 0; j <= vals; j++) {
      neuxi[h] = splint_ne(pt, xi, col, pos); /* inter- or extrapolation */

      neuord[h] = pos;
      h++;
      pos += neustep[i];
    }
    /* correct gradient */
    if (*(xi + pt->first[col] - 2) < 1.e30)
      *(xi + pt->first[col] - 2) = splint_grad_ne(pt, xi, col, left[i]);
    if (*(xi + pt->first[col] - 1) < 1.e30)
      *(xi + pt->first[col] - 1) = splint_grad_ne(pt, xi, col, right[i]);
  }

  /* write back values */
  col = 0; /* first value to be changed */
  for (j = g_calc.paircol + g_param.ntypes;
       j < g_calc.paircol + 2 * g_param.ntypes; j++)
    for (i = pt->first[j]; i <= pt->last[j]; i++) {
      xi[i] = neuxi[col];
      pt->xcoord[i] = neuord[col];
      col++;
    }
  printf("Scaling factor %f\n", a);
  /* scale */
  for (i = g_calc.paircol; i < g_calc.paircol + g_param.ntypes; i++) {
    for (j = pt->first[i]; j <= pt->last[i]; j++) {
      pt->table[j] *= a;
    }
    if (*(xi + pt->first[i] - 2) < 1.e30)
      *(xi + pt->first[i] - 2) *= a;
  }

  /* rescale all embed. by a */
  if (sign == 1) {
    j = 0;
    for (i = g_calc.paircol + g_param.ntypes;
         i < g_calc.paircol + 2 * g_param.ntypes; i++) {
      pt->begin[i] = a * left[j];
      pt->end[i] = a * right[j];
      pt->step[i] = a * neustep[j];
      pt->invstep[i] = 1.0 / pt->step[i];
      /* gradient correction */
      if (xi[pt->first[i] - 2] < 1.e30)
        xi[pt->first[i] - 2] /= a;
      if (xi[pt->first[i] - 1] < 1.e30)
        xi[pt->first[i] - 1] /= a;
      pos = pt->begin[i];
      for (h = pt->first[i]; h <= pt->last[i]; h++) {
        pt->xcoord[h] = pos;
        pos += pt->step[i];
      }
      j++;
    }
  } else { /* reverse - a negativ */
    j = 0;
    for (i = g_calc.paircol + g_param.ntypes;
         i < g_calc.paircol + 2 * g_param.ntypes; i++) {
      pt->begin[i] = a * right[j];
      pt->end[i] = a * left[j];
      pt->step[i] = -a * neustep[j];
      pt->invstep[i] = 1.0 / pt->step[i];
      /* gradient correction and exchange */
      if (xi[pt->first[i] - 2] < 1.e30)
        grad = -xi[pt->first[i] - 2] / a;
      else
        grad = 1.e30;
      if (xi[pt->first[i] - 1] < 1.e30)
        xi[pt->first[i] - 2] = -xi[pt->first[i] - 1] / a;
      else
        xi[pt->first[i] - 2] = 1.e30;
      xi[pt->first[i] - 1] = grad;
      pos = pt->begin[i];
      for (h = pt->first[i]; h <= pt->last[i]; h++) {
        pt->xcoord[h] = pos;
        pos += pt->step[i];
      }
      j++;
    }
    h = 0;
    for (i = 0; i < g_param.ntypes; i++) { /* values in reverse order */
      col = g_calc.paircol + g_param.ntypes + i;
      for (j = pt->last[col]; j >= pt->first[col]; j--) {
        neuxi[h] = xi[j];
        h++;
      }
    }
    col = 0; /* and write back */
    for (j = g_calc.paircol + g_param.ntypes;
         j < g_calc.paircol + 2 * g_param.ntypes; j++)
      for (i = pt->first[j]; i <= pt->last[j]; i++) {
        xi[i] = neuxi[col];
        col++;
      }
  }
  /* re-initialise splines */
  for (col = g_calc.paircol; col < g_calc.paircol + g_param.ntypes;
       col++) { /* rho */
    first = pt->first[col];
    if (g_pot.format_type == POTENTIAL_FORMAT_TABULATED_EQ_DIST)
      spline_ed(pt->step[col], xi + first, pt->last[col] - first + 1,
                *(xi + first - 2), 0.0, pt->d2tab + first);
    else /* format == 4 ! */
      spline_ne(pt->xcoord + first, xi + first, pt->last[col] - first + 1,
                *(xi + first - 2), 0.0, pt->d2tab + first);
  }

  for (col = g_calc.paircol + g_param.ntypes;
       col < g_calc.paircol + 2 * g_param.ntypes; col++) { /* F */
    first = pt->first[col];
    /* gradient 0 at r_cut */
    if (g_pot.format_type == POTENTIAL_FORMAT_TABULATED_EQ_DIST)
      spline_ed(pt->step[col], xi + first, pt->last[col] - first + 1,
                *(xi + first - 2), *(xi + first - 1), pt->d2tab + first);
    else /* format == 4 */
      spline_ne(pt->xcoord + first, xi + first, pt->last[col] - first + 1,
                *(xi + first - 2), *(xi + first - 1), pt->d2tab + first);
  }

  /* correct gauge: U'(n_mean)=0 */
  for (i = 0; i < g_param.ntypes; i++) {
    g_calc.lambda[i] = (*g_splint_grad)(
        &g_pot.opt_pot, pt->table, g_calc.paircol + g_param.ntypes + i,
        0.5 * (pt->begin[g_calc.paircol + g_param.ntypes + i] +
               pt->end[g_calc.paircol + g_param.ntypes + i]));
  }
  for (i = 0; i < g_param.ntypes; i++)
    printf("lambda[%d] = %f\n", i, g_calc.lambda[i]);
  i = 0;

  for (col = 0; col < g_param.ntypes; col++)
    for (col2 = col; col2 < g_param.ntypes; col2++) {
      for (j = pt->first[i]; j <= pt->last[i]; j++)
        pt->table[j] +=
            (pt->xcoord[j] < pt->end[g_calc.paircol + col2]
                 ? g_calc.lambda[col] * splint_ne(pt, pt->table,
                                                  g_calc.paircol + col2,
                                                  pt->xcoord[j])
                 : 0.0) +
            (pt->xcoord[j] < pt->end[g_calc.paircol + col]
                 ? g_calc.lambda[col2] * splint_ne(pt, pt->table,
                                                   g_calc.paircol + col,
                                                   pt->xcoord[j])
                 : 0.0);
      /* Gradient */
      if (pt->table[pt->first[i] - 2] < 1e29) /* natural spline */
        pt->table[pt->first[i] - 2] +=
            (pt->begin[i] < pt->end[g_calc.paircol + col2]
                 ? g_calc.lambda[col] * (*g_splint_grad)(pt, pt->table,
                                                         g_calc.paircol + col2,
                                                         pt->begin[i])
                 : 0.0) +
            (pt->begin[i] < pt->end[g_calc.paircol + col]
                 ? g_calc.lambda[col2] * (*g_splint_grad)(pt, pt->table,
                                                          g_calc.paircol + col,
                                                          pt->begin[i])
                 : 0.0);
      if (pt->table[pt->first[i] - 1] < 1e29) /* natural spline */
        pt->table[pt->first[i] - 1] +=
            (pt->end[i] < pt->end[g_calc.paircol + col2]
                 ? g_calc.lambda[col] * (*g_splint_grad)(pt, pt->table,
                                                         g_calc.paircol + col2,
                                                         pt->end[i])
                 : 0.0) +
            (pt->end[i] < pt->end[g_calc.paircol + col]
                 ? g_calc.lambda[col2] * (*g_splint_grad)(pt, pt->table,
                                                          g_calc.paircol + col,
                                                          pt->end[i])
                 : 0.0);
      i++;
    }
  for (i = 0; i < g_param.ntypes; i++) {
    for (j = pt->first[g_calc.paircol + g_param.ntypes + i];
         j <= pt->last[g_calc.paircol + g_param.ntypes + i]; j++)
      pt->table[j] -= pt->xcoord[j] * g_calc.lambda[i];
    /* Gradients */
    if (pt->table[pt->first[g_calc.paircol + g_param.ntypes + i] - 2] <
        1e29) /* natural spline */
      pt->table[pt->first[g_calc.paircol + g_param.ntypes + i] - 2] -=
          g_calc.lambda[i];
    if (pt->table[pt->first[g_calc.paircol + g_param.ntypes + i] - 1] <
        1e29) /* natural spline */
      pt->table[pt->first[g_calc.paircol + g_param.ntypes + i] - 1] -=
          g_calc.lambda[i];
    g_calc.lambda[i] = 0.0;
  }

  /* init second derivatives for splines */
  for (col = 0; col < g_calc.paircol; col++) { /* just pair potentials */
    first = pt->first[col];
    if (g_pot.format_type == POTENTIAL_FORMAT_TABULATED_EQ_DIST)
      spline_ed(pt->step[col], pt->table + first, pt->last[col] - first + 1,
                *(pt->table + first - 2), 0.0, pt->d2tab + first);
    else /* format == 4 ! */
      spline_ne(pt->xcoord + first, pt->table + first,
                pt->last[col] - first + 1, *(pt->table + first - 2), 0.0,
                pt->d2tab + first);
  }

  free(neuxi);
  free(neuord);
  free(neustep);
  free(maxrho);
  free(minrho);
  free(left);
  free(right);

  /* return factor */
  return a;
}