Пример #1
0
void fractional_min(gdouble *x, gint dim)
{
gint i, j;
gdouble whole;

g_assert(dim < 4);

#if DEBUG_FRAC_MINSQ
P3VEC("b4: ", x);
#endif

for (i=0 ; i<dim ; i++)
  {
/* clamp value -1 < x < 1 */ 
  x[i] = modf(x[i], &whole);

/* clamp to range (-0.5, 0.5) */
  j = (gint) (-2.0 * x[i]);
  x[i] += (gdouble) j;
  }

#if DEBUG_FRAC_MINSQ
P3VEC("af: ", x);
#endif
}
Пример #2
0
void fractional_clamp(gdouble *vec, gint *mov, gint dim)
{
gint i;
gdouble ip;

#if DEBUG_CLAMP
P3VEC("inp: ", vec);
#endif

/* NB: init ALL 3 coords as isolated molecules call this */
/* routine & it is expected that mov to be set to 0,0,0 */
mov[0] = mov[1] = mov[2] = 0;

/*
for (i=0 ; i<dim ; i++)
*/
for (i=dim ; i-- ; )
  {
  mov[i] = -vec[i];
  if (vec[i] < 0.0)
    {
/* increment the move for -ve's with exception -1.0, -2.0, -3.0,... */
    if (modf(vec[i], &ip) != 0.0)
      mov[i]++;
    }
  else
    mov[i] = -vec[i];

  vec[i] += (gdouble) mov[i];
  }

#if DEBUG_CLAMP
P3VEC("out: ", vec);
#endif
}
Пример #3
0
void camera_dump(gpointer data)
{
struct camera_pak *camera = data;

printf("camera [%p]\n", camera);
P4VEC("q: ", camera->q);
P3VEC("x: ", camera->x);
P3VEC("o: ", camera->o);
P3VEC("v: ", camera->v);
}
Пример #4
0
gint facet_equiv(struct model_pak *data, gint *f1, gint *f2)
{
gint i, index[3];
gdouble vec[3];

#if DEBUG_FACET_EQUIV
printf("facet_equiv(): [%d %d %d] and (%d %d %d)\n", f1[0], f1[1], f1[2], f2[0], f2[1], f2[2]);
#endif

/* symmetry test */
if (data->sginfo.spacenum > 0)
  {
  for (i=0 ; i<data->sginfo.order ; i++)
    {
    ARR3SET(vec, f1);
    vecmat(*(data->sginfo.matrix+i), vec);
    ARR3SET(index, vec);

#if DEBUG_FACET_EQUIV
P3VEC("op -> ", vec);
#endif

    if (index[0] == *f2 && index[1] == *(f2+1) && index[2] == *(f2+2))
      {
#if DEBUG_FACET_EQUIV
printf(" *** equivalent (symop %d).\n", i);
#endif
      return(TRUE);  
      }
    }
  }
else
  printf("No space group information.\n");

#if DEBUG_FACET_EQUIV
printf("not equivalent.\n");
#endif

return(FALSE);
}
Пример #5
0
gint region_move_atom(struct core_pak *core, gint direction,
                                    struct model_pak *data)
{
gint flag, primary, secondary, mov[2];
gdouble vec[3], tmp[3], d[3];
GSList *list;
struct core_pak *comp;

#if DEBUG_REGION_SWITCH_ATOM
printf("       model: %s\n", data->basename);
printf(" periodicity: %d\n", data->periodic);
printf("         hkl: %f %f %f\n", data->surface.miller[0],
          data->surface.miller[1], data->surface.miller[2]);
printf("        dhkl: %f\n", data->surface.dspacing);
printf("region sizes: %f %f\n", data->surface.region[0], data->surface.region[1]);
printf("      moving: ");
if (direction == UP)
  printf("UP\n");
else
  printf("DOWN\n");
#endif

/* checks */
g_return_val_if_fail(data != NULL, 1);
g_return_val_if_fail(data->periodic == 2, 1);
if (data->surface.region[0] < 1)
  {
  gui_text_show(ERROR, "region 1 is empty.\n");
  return(1);
  }

/* setup region switching labels */
if (direction == UP)
  {
  primary = REGION1A;
  secondary = REGION2A;
  }
else
  {
  primary = REGION2A;
  secondary = REGION1A;
  }

/* get fractional depth translation vector */
ARR3SET(vec, data->surface.depth_vec);
vecmat(data->ilatmat, vec);

/* calculate offset to region boundary */
ARR3SET(tmp, vec);
if (direction == DOWN)
  {
  VEC3MUL(tmp, data->surface.region[0]);
  VEC3MUL(tmp, -1.0);
  }
else
  {
  if (data->surface.region[1] == 0)
    {
    VEC3MUL(tmp, data->surface.region[0]);
    }
  else
    {
    VEC3MUL(tmp, data->surface.region[1]);
    }
  }

/* if region 2 is empty, just move core to the bottom */
if (data->surface.region[1] == 0.0)
  {
  ARR3ADD(core->x, tmp);
  if (core->shell)
    {
    ARR3ADD((core->shell)->x, tmp);
    }
  atom_colour_scheme(data->colour_scheme, core, data);
  return(0);
  }

/* get coordinates of target atom */
ARR3ADD(tmp, core->x);

#if DEBUG_REGION_SWITCH_ATOM
P3VEC("    translation: ", vec);
P3VEC("  target coords: ", tmp);
#endif

/* find the target */
flag=0;
for (list=data->cores ; list ; list=g_slist_next(list))
  {
  comp = list->data;

/* only atoms of the same type need apply */
  if (core->atom_code != comp->atom_code)
    continue;

/* get difference vector */
  ARR3SET(d, comp->x);
  ARR3SUB(d, tmp);

/* pbc constraint */
  while(d[0] < -FRACTION_TOLERANCE)
    d[0] += 1.0;
  while(d[0] > 0.5)
    d[0] -= 1.0;
  while(d[1] < -FRACTION_TOLERANCE)
    d[1] += 1.0;
  while(d[1] > 0.5)
    d[1] -= 1.0;

/* test difference vector's magnitude */
  if (VEC3MAGSQ(d) < FRACTION_TOLERANCE)
    {
/* change its labelling */
#if DEBUG_REGION_SWITCH_ATOM
printf("Matched core: %p\n", comp);
#endif
    comp->region = secondary;
    if (comp->shell)
      {
      (comp->shell)->region = secondary;
      }
    atom_colour_scheme(data->colour_scheme, comp, data);
    flag++;
    break;
    }
  }

if (!flag)
  {
  gui_text_show(ERROR, "Failed to find a boundary image.\n");
  return(1);
  }

/* now move selected atom to bottom of region 2 */
ARR3SET(tmp, vec);
VEC3MUL(tmp, (data->surface.region[0] + data->surface.region[1]));
if (direction == UP)
  VEC3MUL(tmp, -1.0);
ARR3SUB(core->x, tmp);
core->region = primary;
/* pbc constrain */
fractional_clamp(core->x, mov, 2);

if (core->shell)
  {
  ARR3SUB((core->shell)->x, tmp);
  ARR2ADD((core->shell)->x, mov);
  (core->shell)->region = primary;
  }

atom_colour_scheme(data->colour_scheme, core, data);

return(0);
}
Пример #6
0
void delete_duplicate_cores(struct model_pak *model)
{
gdouble vec[3];
GSList *list1, *list2, *za_list;
gpointer zone;
struct core_pak *core1, *core2;
struct shel_pak *s1, *s2;

/* checks */
g_assert(model != NULL);
g_assert(model->zone_array != NULL);

#if DEBUG_REMOVE_DUPLICATES
printf("Initial cores: %d\n", g_slist_length(model->cores));
printf("Initial shels: %d\n", g_slist_length(model->shels));
#endif

/* enumerate all cores */
for (list1=model->cores ; list1 ; list1=g_slist_next(list1))
  {
  core1 = list1->data;
  if (core1->status & DELETED)
    continue;

/* enumerate cores in current locality */
  zone = zone_get(core1->x, model->zone_array);

#if DEBUG_REMOVE_DUPLICATES_MORE
printf(" + %s [%p] : [%p] :", core1->atom_label, core1, zone);
P3VEC(" ", core1->x);
#endif
/* should use zone_area_cores() as a very small coord difference */
/* can result in cores being put in different (neighbouring) zones */
/*
  for (list2=zone_cores(zone) ; list2 ; list2=g_slist_next(list2))
*/

  za_list = zone_area_cores(1, zone, model->zone_array);
  for (list2=za_list ; list2 ; list2=g_slist_next(list2))
    {
    core2 = list2->data;
    if (core2->status & DELETED)
      continue;

/* avoid double counting */
    if (core1 >= core2)
      continue;

    if (core1->atom_code != core2->atom_code)
      continue;

#if DEBUG_REMOVE_DUPLICATES_MORE
printf(" - %s :", core2->atom_label);
P3VEC(" ", core2->x);
#endif

/* compute and test the minimum separation */
    ARR3SET(vec, core1->x);
    ARR3SUB(vec, core2->x);

    fractional_min(vec, model->periodic);

    if (VEC3MAGSQ(vec) < FRACTION_TOLERANCE)
      {
/* delete core2, unless primary AND core1 is non primary */
      if (core2->primary && !core1->primary)
        {
        core1->status |= DELETED;

/* FIXME - this may be a problem since we start the core2 loop */
/* requiring that core1 be undeleted */
#if DEBUG_REMOVE_DUPLICATES_MORE
printf(" * rm 1\n");
#endif
        }
      else
        {
        core2->status |= DELETED;

#if DEBUG_REMOVE_DUPLICATES_MORE
printf(" * rm 2\n");
#endif
        }
      }
    }
  g_slist_free(za_list);
  }

/* commit before searching for duplicate shells, as a commit */
/* will delete some attached shells */
delete_commit(model);

for (list1=model->shels ; list1 ; list1=g_slist_next(list1))
  {
  s1 = list1->data;
  if (s1->status & DELETED)
    continue;

/* NEW - enumerate shells in the current locality */
  zone = zone_get(s1->x, model->zone_array); 
  for (list2=zone_shells(zone) ; list2 ; list2=g_slist_next(list2))
    {
    s2 = list2->data;

    if (s2->status & DELETED)
      continue;
    if (s1 == s2)
      continue;

    ARR3SET(vec, s1->x);
    ARR3SUB(vec, s2->x);

/* adjust for periodicity */
    fractional_min(vec, model->periodic);

    if (VEC3MAGSQ(vec) < FRACTION_TOLERANCE)
      {
/* delete shell2, unless primary AND shell1 is non primary */
      if (s2->primary && !s1->primary)
        s1->status |= DELETED;
      else
        s2->status |= DELETED;
      }
    }
  }
delete_commit(model);

#if DEBUG_REMOVE_DUPLICATES
printf("Final cores: %d\n", g_slist_length(model->cores));
printf("Final shels: %d\n", g_slist_length(model->shels));
#endif
}
Пример #7
0
gint surf_sysabs(struct model_pak *data, gint h, gint k, gint l)
{
gint i, flag;
gint f1[3] /*, f2[3]*/;
gdouble dp, dummy, vec[3], df[3];

#if DEBUG_FACET_ABSENT
printf("testing %d %d %d\n", h, k, l);
#endif

/* apply the symmetry matrices (skip identity) */
VEC3SET(f1, h, k, l);
for (i=1 ; i<data->sginfo.order ; i++)
  {
/* NEW - identity + translation alone is insufficent */
  if (matrix_is_identity(*(data->sginfo.matrix+i)))
    continue;

  VEC3SET(vec, h, k, l);

  vecmat(*(data->sginfo.matrix+i), vec);
  flag = 0;

/* not needed - we've expanded all symmetry operations (incl. inversion) */
/* test f1 . m = -f1 */
/*
  ARR3SET(df, f1);
  ARR3ADD(df, vec);
  if (VEC3MAGSQ(df) < FRACTION_TOLERANCE)
    if (data->sginfo.inversion)
      flag++;
*/
 
/* test f1 . m = f1 */
  ARR3SET(df, f1);
  ARR3SUB(df, vec);
  if (VEC3MAGSQ(df) < POSITION_TOLERANCE)
    flag++;

  if (flag)
    {
#if DEBUG_FACET_ABSENT
printf("symop [%d] satisfies 1st absence condition.\n", i);
P3MAT("matrix:", *(data->sginfo.matrix+i));
P3VEC("offset:", *(data->sginfo.offset+i));
#endif

/* test if <f1,t> = non-integer */
    ARR3SET(vec, *(data->sginfo.offset+i));
    ARR3MUL(vec, f1);
    dp = fabs(vec[0] + vec[1] + vec[2]);
    if (modf(dp, &dummy) > POSITION_TOLERANCE)
      {
#if DEBUG_FACET_ABSENT
printf("symop [%d] [%f %f %f] satisfies 2nd absence condition.\n",
       i, *(*(data->sginfo.offset+i)+0), *(*(data->sginfo.offset+i)+1),
          *(*(data->sginfo.offset+i)+2));
printf("facet is extinct.\n");
#endif
      return(TRUE);
      }
    }
  }

#if DEBUG_FACET_ABSENT
printf(">>> Not absent\n");
#endif

return(FALSE);
}
Пример #8
0
void zmat_process(gpointer data, struct model_pak *model)
{
gint i, n;
gdouble r, a, d;
gdouble v1[3], v2[3], v3[3], m1[9], m2[9];
gpointer tmp;
GSList *list;
struct zmat_pak *zmat = data;
struct zval_pak *zval;
struct core_pak *core[4] = {NULL, NULL, NULL, NULL};

/* checks */
if (!zmat)
  return;

matrix_lattice_init(model);

#if ZMAT_PROCESS_DEBUG
printf("distance scale = %f\n", zmat->distance_scale);
printf("angle scale = %f\n", zmat->angle_scale);
#endif

/* track the core # - 1st 3 items in zmatrix are exceptions */
n = 0;
for (list=zmat->zlines ; list ; list=g_slist_next(list))
  {
  zval = list->data;

/* check for variable names */
  for (i=3 ; i-- ; )
    {
    if (zval->name[i])
      {
/* hash table lookup for variable value */
      zval->value[i] = zmat_table_lookup(zval->name[i], zmat);
      }
    }

/* create the core */
#if ZMAT_PROCESS_DEBUG
printf("[%d = %s] [%d %d %d]", zval->type, zval->elem,
                               zval->connect[0], zval->connect[1], zval->connect[2]);
P3VEC(" x: ", zval->value);

#endif

/* TODO - need to mark zmatrix generated cores as special */
/* probably have another list in the zmat struct that contains */
/* all the cores created below */

  switch (n)
    {
    case 0:
/* TODO - convert to cartesian if fractional and enforce cart model */
      core[0] = new_core(zval->elem, model);
      model->cores = g_slist_prepend(model->cores, core[0]);
      zmat->zcores = g_slist_prepend(zmat->zcores, core[0]);
      ARR3SET(core[0]->x, zval->value);
      if (zmat->fractional)
        vecmat(model->latmat, core[0]->x);
      else
        {
        VEC3MUL(core[0]->x, zmat->distance_scale);
        }
      break;

    case 1:
      core[1] = new_core(zval->elem, model);
      model->cores = g_slist_prepend(model->cores, core[1]);
      zmat->zcores = g_slist_prepend(zmat->zcores, core[1]);

      r = zmat->distance_scale * zval->value[0];
/*
      a = zmat->angle_scale * zval->value[1];
      d = zmat->angle_scale * zval->value[2];
*/

/* SIESTA hack : z-axis angle is 2nd, and theta is 3rd (last) */
      a = zmat->angle_scale * zval->value[2];
      d = zmat->angle_scale * zval->value[1];

      v1[0] = v1[1] = r * sin(d);
      v1[0] *= cos(a);
      v1[1] *= sin(a);
      v1[2] = r * cos(d);

      ARR3SET(core[1]->x, core[0]->x);
      ARR3ADD(core[1]->x, v1);
      break;

    case 2:
/* check the connection order */
      if (zval->connect[0] == 2)
        {
        tmp = core[0];
        core[0] = core[1];
        core[1] = tmp;
        }

      r = zmat->distance_scale * zval->value[0];
      a = zmat->angle_scale * zval->value[1];
      d = zmat->angle_scale * zval->value[2];

      ARR3SET(v2, core[1]->x);
      ARR3SUB(v2, core[0]->x);

/* get rotation axis for bond angle */
      VEC3SET(v3, 0.0, 0.0, 1.0);
      crossprod(v1, v3, v2);

/* rotate bondlength scaled vector into position */
      matrix_v_rotation(m2, v1, a);
      ARR3SET(v3, v2);
      normalize(v3, 3);
      VEC3MUL(v3, r);
      vecmat(m2, v3);

/* rotate to give required dihedral */
      matrix_v_rotation(m1, v2, d);
      vecmat(m1, v3);

/* generate the atom position */
      core[2] = new_core(zval->elem, model);
      model->cores = g_slist_prepend(model->cores, core[2]);
      zmat->zcores = g_slist_prepend(zmat->zcores, core[2]);

      ARR3SET(core[2]->x, core[0]->x);
      ARR3ADD(core[2]->x, v3);
      break;

    default:
/* get core connectivity (NB: prepending cores - hence n - number) */
      core[0] = g_slist_nth_data(zmat->zcores, n-zval->connect[0]); 
      core[1] = g_slist_nth_data(zmat->zcores, n-zval->connect[1]); 
      core[2] = g_slist_nth_data(zmat->zcores, n-zval->connect[2]); 
g_assert(core[0] != NULL);
g_assert(core[1] != NULL);
g_assert(core[2] != NULL);

      r = zmat->distance_scale * zval->value[0];
      a = zmat->angle_scale * zval->value[1];
      d = zmat->angle_scale * zval->value[2];

/* setup vectors */
      ARR3SET(v2, core[1]->x);
      ARR3SUB(v2, core[0]->x);
      ARR3SET(v3, core[2]->x);
      ARR3SUB(v3, core[1]->x);

/* rotate v3 about v2 to give dihedral */
      matrix_v_rotation(m1, v2, d);
      vecmat(m1, v3);

/* get rotation axis and matrix for bond angle */
      crossprod(v1, v3, v2);
      matrix_v_rotation(m2, v1, a);
      normalize(v2, 3);
      VEC3MUL(v2, r);
      vecmat(m2, v2);

/* generate the atom position */
      core[3] = new_core(zval->elem, model);
      model->cores = g_slist_prepend(model->cores, core[3]);
      zmat->zcores = g_slist_prepend(zmat->zcores, core[3]);

      ARR3SET(core[3]->x, core[0]->x);
      ARR3ADD(core[3]->x, v2);

/* TODO (maybe) - some zmatrix constructions implicitly assume */
/* some checking for duplicate atoms & reversing the torsional */
/* angle sense to accomodate this. */

      break;
    }
  n++;
  }

/* zmatrix cores are created in cartesians - revert to fractional if required */
if (model->fractional)
  {
  for (list=zmat->zcores ; list ; list=g_slist_next(list))
    {
    core[0] = list->data;
    vecmat(model->ilatmat, core[0]->x);
    }
  }
}
Пример #9
0
gint read_nwout_block(FILE *fp, struct model_pak *model)
{
gint num_tokens;
gchar **buff, line[LINELEN], *text;
GString *gstring;
GSList *clist;
struct core_pak *core;

clist = model->cores;
  
/* skip until get a 1 in first column for first coordinate */
if (fgetline(fp, line))
  return(1);
while (g_ascii_strncasecmp(line, "    1", 5) != 0)
  {
  if (fgetline(fp, line))
    return(1);
  }

buff = tokenize(line, &num_tokens);
while (num_tokens > 0)
  {
  if (clist)
    {
    core = clist->data;
    clist = g_slist_next(clist);
    }
  else
    {
    core = new_core(*(buff+1), model);
    model->cores = g_slist_append(model->cores, core);
    }

  core->x[0] = str_to_float(*(buff+3));
  core->x[1] = str_to_float(*(buff+4));
  core->x[2] = str_to_float(*(buff+5));

#if DEBUG_READ_NWOUT
P3VEC("coords: ", core->x);
#endif

/* get next line */
  g_strfreev(buff);
  if (fgetline(fp, line))
    return(2);
  buff = tokenize(line, &num_tokens);
  }

g_strfreev(buff);

/* read until get the details of the current optimisation step */  
while (g_ascii_strncasecmp(line, "@", 1) != 0)
  {
  if (fgetline(fp, line))
    return(0);
  }

buff = tokenize(line, &num_tokens);
while (g_ascii_strncasecmp(line, "@", 1) == 0)
  {
  if (g_ascii_isdigit(buff[1][0]))
    {
    text = format_value_and_units(*(buff+2), 5);
    gstring = g_string_new(text);
    g_free(text);
    g_string_append(gstring, " a.u.");
    property_add_ranked(3, "Energy", gstring->str, model);
    g_string_free(gstring, TRUE);
 
    text = format_value_and_units(*(buff+5), 5);
    gstring = g_string_new(text);
    g_free(text);
    g_string_append(gstring, " a.u./A");
    property_add_ranked(4, "RMS Gradient", gstring->str, model);
    g_string_free(gstring, TRUE);
    }
  /* get next line */
  g_strfreev(buff);
  if (fgetline(fp, line))
    return(2);
  buff = tokenize(line, &num_tokens);
  }

return(0);
}
Пример #10
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);
}