Ejemplo n.º 1
0
void zmat_build(void)
{
gint i, j, k, n, type;
gdouble r, a, d, x[4][3], v[3];
gdouble  zaxis[3] = {0.0, 0.0, 1.0};
gchar *line;
GSList *list, *species;
struct zmat_pak *zmat;
struct core_pak *core[4] = {NULL, NULL, NULL, NULL};
struct model_pak *model;

model = sysenv.active_model;
if (!model)
  return;

/* CURRENT - using selection as our list of cores to generate a zmatrix from */
if (!model->selection)
  {
  gui_text_show(WARNING, "ZMATRIX: please select a molecule.\n");
  return;
  }

/* destroy old zmatrix */
/* TODO - prompt if non null */
zmat_free(model->zmatrix);
zmat = model->zmatrix = zmat_new();
zmat_angle_units_set(model->zmatrix, DEGREES);

/* setup SIESTA species type */
species = fdf_species_build(model);

/* sort the list so it follows molecular connectivity */
model->selection = zmat_connect_sort(model->selection);

n=0;
for (list=model->selection ; list ; list=g_slist_next(list))
  {
/* current atom/zmatrix line init */
  core[0] = list->data;
  type = fdf_species_index(core[0]->atom_label, species);
  line = NULL;

  zmat->zcores = g_slist_append(zmat->zcores, core[0]);

/* build a ZMATRIX line for processing */
  switch (n)
    {
    case 0:
      if (core[0])
        {
        ARR3SET(x[0], core[0]->x);
        vecmat(model->latmat, x[0]);
        }
      line = g_strdup_printf("%d  0 0 0  %f %f %f  0 0 0\n", type, x[0][0], x[0][1], x[0][2]);
      break;

    case 1:
      if (core[0])
        {
        ARR3SET(x[0], core[0]->x);
        vecmat(model->latmat, x[0]);
        }
      if (core[1])
        {
        ARR3SET(x[1], core[1]->x);
        vecmat(model->latmat, x[1]);
        }

      r = measure_distance(x[0], x[1]);

/* angle with z axis */
      ARR3SET(v, x[0]);
      ARR3SUB(v, x[1]);
      a = R2D * via(v, zaxis, 3);

/* angle between xy projection and x axis */
      d = R2D * angle_x_compute(v[0], v[1]);

      line = g_strdup_printf("%d  1 0 0  %f %f %f 0 0 0\n", type, r, a, d);
      break;

    case 2:
/* coords init */
  for (i=3 ; i-- ; )
    {
    if (core[i])
      {
      ARR3SET(x[i], core[i]->x);
      vecmat(model->latmat, x[i]);
      }
    else
      g_assert_not_reached();
    }

      r = measure_distance(x[0], x[1]);
      a = measure_angle(x[0], x[1], x[2]);

/* create a fake core -> 1 unit displaced in the z direction */
      g_assert(core[3] == NULL);
      core[3] = core_new("x", NULL, model);
      ARR3SET(core[3]->rx, core[2]->rx);
      ARR3ADD(core[3]->rx, zaxis); 
      d = measure_torsion(core);
      core_free(core[3]);

      line = g_strdup_printf("%d  2 1 0  %f %f %f 0 0 0\n", type,r,a,d);
      break;

    default:

/* connectivity test */
      if (!zmat_bond_check(core[0], core[1]))
        {
#if DEBUG_ZMAT_BUILD
printf("[%d] non-connected atoms [%f]\n", n, measure_distance(x[0], x[1]));
#endif
/* need to build a new connectivity chain starting from core[0] */
        core[1] = core[2] = core[3] = NULL;
        if (!zmat_connect_find(n, core, zmat))
          {
          gui_text_show(WARNING, "ZMATRIX: bad connectivity (molecule will be incomplete)\n");
          goto zmat_build_done;
          }
        }

/* coords init */
      for (i=3 ; i-- ; )
        {
        if (core[i])
          {
          ARR3SET(x[i], core[i]->x);
          vecmat(model->latmat, x[i]);
          }
        else
          g_assert_not_reached();
        }

      r = measure_distance(x[0], x[1]);
      a = measure_angle(x[0], x[1], x[2]);
      d = measure_torsion(core);

/* NB: indexing starts from 0, siesta starts from 1 (naturally) */
      i = 1+g_slist_index(zmat->zcores, core[1]);
      j = 1+g_slist_index(zmat->zcores, core[2]);
      k = 1+g_slist_index(zmat->zcores, core[3]);

      line = g_strdup_printf("%d  %d %d %d  %f %f %f 0 0 0\n", type,i,j,k,r,a,d);
    }

/* process a successfully constructed ZMATRIX line */
  if (line)
    {
    zmat_core_add(line, model->zmatrix);
    g_free(line);
    }

/* shuffle */
  core[3] = core[2];
  core[2] = core[1];
  core[1] = core[0];

  n++;
  }

zmat_build_done:

/* do the species typing */
zmat_type(model->zmatrix, species);

free_slist(species);
}
Ejemplo n.º 2
0
gint read_nwchem_geometry(gpointer scan, struct model_pak *model)
{
gint n, zmode=0, end_count=0;
gchar **buff;
struct core_pak *core;

#if DEBUG_READ_NWCHEM_GEOMETRY
printf("read_nwchem_geometry(): start\n");
#endif

// TODO - rewrite this using symbol scanning functionality
while (!scan_complete(scan))
  {
  buff = scan_get_tokens(scan, &n);

// zmatrix?
   if (g_ascii_strncasecmp(*buff, "zmatrix", 7) == 0)
     {
     zmode = 1;
     g_strfreev(buff);
     continue;
     }
   if (g_ascii_strncasecmp(*buff, "variables", 9) == 0)
     {
     zmode = 2;
     g_strfreev(buff);
     continue;
     }
   if (g_ascii_strncasecmp(*buff, "constants", 9) == 0)
     {
     zmode = 3;
     g_strfreev(buff);
     continue;
     }

// end?
   if (n)
     {
     if (g_ascii_strncasecmp(*buff, "end", 3) == 0)
       {
       g_strfreev(buff);
/* if we processed zmatrix entries - expect 2 x end */
       if (zmode && !end_count)
         {
/* keep going until we hit a second end ... */
         end_count++;
         continue;
         }
/* exit */
       break;
       }
     }

/* main parse */
  switch (zmode)
    {
// cartesian coords
    case 0:
// can cart coord line have >4 tokens?
      if (n == 4)
        {
        if (elem_test(*buff))
          {
          core = core_new(*buff, NULL, model);
          model->cores = g_slist_prepend(model->cores, core);
          core->x[0] = str_to_float(*(buff+1));
          core->x[1] = str_to_float(*(buff+2));
          core->x[2] = str_to_float(*(buff+3));

#if DEBUG_READ_NWCHEM_GEOMETRY
printf("Added [%s] ", *buff);
P3VEC(": ", core->x);
#endif
          }
        }
      break;

// zmatrix coords
    case 1:
#if DEBUG_READ_NWCHEM_GEOMETRY
printf("zcoord: %s", scan_cur_line(scan));
#endif
      zmat_nwchem_core_add(scan_cur_line(scan), model->zmatrix);
      break;

// zmatrix vars
    case 2:
#if DEBUG_READ_NWCHEM_GEOMETRY
printf("zvar: %s", scan_cur_line(scan));
#endif
      zmat_var_add(scan_cur_line(scan), model->zmatrix);
      break;

// zmatrix consts
    case 3:
#if DEBUG_READ_NWCHEM_GEOMETRY
printf("zconst: %s", scan_cur_line(scan));
#endif
      zmat_const_add(scan_cur_line(scan), model->zmatrix);
      break;
    }

  g_strfreev(buff);
  }

if (zmode)
  {
#if DEBUG_READ_NWCHEM_GEOMETRY
printf("Creating zmatrix cores...\n");
#endif
  zmat_angle_units_set(model->zmatrix, DEGREES);
  zmat_process(model->zmatrix, model);
  }

#if DEBUG_READ_NWCHEM_GEOMETRY
printf("read_nwchem_geometry(): stop\n");
#endif

return(0);
}