예제 #1
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
}
예제 #2
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);
}
예제 #3
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);
}