Пример #1
0
struct core_pak *copy_core(struct core_pak *core, struct model_pak *src,
                                                  struct model_pak *dest)
{
gint items=0;
gdouble vec[3];
struct core_pak *copyc;
struct shel_pak *copys;

/* checks */
g_assert(core != NULL);
g_assert(src != NULL);
g_assert(dest != NULL);

/* duplicate data structure */
copyc = dup_core(core);
items++;

/* setup status */
copyc->status = copyc->status & (~SELECT & ~SELECT);
copyc->orig = copyc->primary = TRUE;
copyc->primary_core = NULL;
VEC3SET(copyc->offset, 0.0, 0.0, 0.0);

/* coords, account for transformation matrices */
ARR3SET(vec, core->rx);
vecmat(dest->ilatmat, vec);
ARR3ADD(vec, dest->centroid);
ARR3SET(copyc->x, vec);

dest->cores = g_slist_prepend(dest->cores, copyc);

/* attached shell? */
if (copyc->shell)
  {
  copys = copyc->shell;
  items++;

/* main info */
  copys->status = copys->status & (~SELECT);
  copys->primary=copys->orig=TRUE; 
  copys->primary_shell = NULL;
  VEC3SET(copys->offset, 0.0, 0.0, 0.0);

/* coords, account for transformation matrices */
  ARR3SET(vec, copys->rx);
  vecmat(dest->ilatmat, vec);
  ARR3ADD(vec, dest->centroid);
  ARR3SET(copys->x, vec);

  dest->shels = g_slist_prepend(dest->shels, copys);
  }

return(copyc);
}
Пример #2
0
gpointer core_new(gchar *elem, gchar *label, struct model_pak *model)
{
struct core_pak *core;

g_assert(elem != NULL);
g_assert(model != NULL);

core = g_malloc(sizeof(struct core_pak));

/* element related initialization */
core_init(elem, core, model);

/* general initialization */
if (label)
  core->atom_label = g_strdup(label);
else
  core->atom_label = g_strdup(elem);

VEC4SET(core->x, 0.0, 0.0, 0.0, 1.0);
VEC4SET(core->rx, 0.0, 0.0, 0.0, 1.0);
VEC3SET(core->v, 0.0, 0.0, 0.0);
VEC3SET(core->offset, 0.0, 0.0, 0.0);
core->status = NORMAL;
core->primary = TRUE;
core->orig = TRUE;
core->ghost = FALSE;
core->breathe = FALSE;
core->growth = FALSE;
core->translate = FALSE;
core->render_mode = BALL_STICK;
core->render_wire = FALSE;
core->region = REGION1A;
core->radius = 0.0;
core->has_sof = FALSE;
core->sof = 1.0;
core->charge = 0.0;
core->lookup_charge = TRUE;
core->flags = NULL;
core->bonds = NULL;
core->mol = NULL;
core->shell = NULL;
core->primary_core = NULL;
core->vibx_list = NULL;
core->viby_list = NULL;
core->vibz_list = NULL;

/* NEW: hydrogen bond capabilities */
if (g_strrstr(elem, "H") != NULL)
  core->hydrogen_bond = TRUE;
else 
  core->hydrogen_bond = FALSE;

return(core);
}
Пример #3
0
gpointer shell_new(gchar *elem, gchar *label, struct model_pak *model)
{
gint code;
struct elem_pak elem_data;
struct shel_pak *shell;

g_assert(elem != NULL);
g_assert(model != NULL);

shell = g_malloc(sizeof(struct shel_pak));

/* attempt to match atom type with database */
code = elem_test(elem);
if (!code)
  printf("Warning: element [%s] not found.\n", elem);

/* init modifiable element data */
get_elem_data(code, &elem_data, model);
ARR3SET(shell->colour, elem_data.colour);

shell->atom_code = code;
if (label)
  shell->shell_label = g_strdup(label);
else
  shell->shell_label = g_strdup(elem);
VEC4SET(shell->x, 0.0, 0.0, 0.0, 1.0);
VEC4SET(shell->rx, 0.0, 0.0, 0.0, 1.0);
VEC3SET(shell->v, 0.0, 0.0, 0.0);
VEC3SET(shell->offset, 0.0, 0.0, 0.0);
shell->status = NORMAL;
shell->primary = TRUE;
shell->orig = TRUE;
shell->breathe = FALSE;
shell->translate = FALSE;
shell->region = REGION1A;
shell->core = NULL;
shell->primary_shell = NULL;
shell->radius = 0.0;
shell->charge = 0.0;
shell->has_sof = FALSE;
shell->sof = 1.0;
shell->lookup_charge = TRUE;
shell->flags = NULL;

return(shell);
}
Пример #4
0
void camera_default(gdouble r, gpointer data)
{
struct camera_pak *camera = data;

camera->mode = LOCKED;
camera->perspective = FALSE;
camera->fov = 70.0;

/* FIXME - not sure why the < 1.0 case is needed ... */
if (r < 1.0)
  camera->zoom = r;
else
  camera->zoom = 1.0;

VEC4SET(camera->q, 1.0, 0.0, 0.0, 0.0);
VEC3SET(camera->x, 0.0, -2.0*r, 0.0);
VEC3SET(camera->o, 0.0, 0.0, 1.0);
VEC3SET(camera->v, 0.0, 1.0, 0.0);
VEC3SET(camera->e, 1.0, 0.0, 0.0);
}
Пример #5
0
void quat_concat_euler(gdouble *q, gint type, gdouble a)
{
gdouble v[3];

switch (type)
  {
  case PITCH:
    VEC3SET(v, 1.0, 0.0, 0.0);
    break;
  case ROLL:
    VEC3SET(v, 0.0, 1.0, 0.0);
    break;
  default:
  case YAW:
    VEC3SET(v, 0.0, 0.0, 1.0);
    break;
  }

/* general axis rotation */
quat_concat(q, v, a);
}
Пример #6
0
void xml_parse_vertex(const gchar **names, const gchar **values)
{
gint i=0;
gdouble x[3], n[3], c[3];

g_assert(xml_spatial != NULL);

VEC3SET(x, 0.0, 0.0, 0.0);
VEC3SET(n, 0.0, 0.0, 0.0);
VEC3SET(c, 0.0, 0.0, 0.0);

while (*(names+i))
  {
  if (g_ascii_strncasecmp(*(names+i), "red", 3) == 0)
    c[0] = str_to_float(*(values+i));
  if (g_ascii_strncasecmp(*(names+i), "green", 5) == 0)
    c[1] = str_to_float(*(values+i));
  if (g_ascii_strncasecmp(*(names+i), "blue", 4) == 0)
    c[2] = str_to_float(*(values+i));

  if (g_ascii_strncasecmp(*(names+i), "x3", 2) == 0)
    x[0] = str_to_float(*(values+i));
  if (g_ascii_strncasecmp(*(names+i), "y3", 2) == 0)
    x[1] = str_to_float(*(values+i));
  if (g_ascii_strncasecmp(*(names+i), "z3", 2) == 0)
    x[2] = str_to_float(*(values+i));

  if (g_ascii_strncasecmp(*(names+i), "nx", 2) == 0)
    n[0] = str_to_float(*(values+i));
  if (g_ascii_strncasecmp(*(names+i), "ny", 2) == 0)
    n[1] = str_to_float(*(values+i));
  if (g_ascii_strncasecmp(*(names+i), "nz", 2) == 0)
    n[2] = str_to_float(*(values+i));

  i++;
  }
spatial_vnorm_add(x, n, c, xml_spatial);
}
Пример #7
0
void siesta_phonon_cleanup(struct model_pak *model)
{
    GSList *list;
    struct core_pak *core;

    g_assert(model != NULL);

    for (list=model->cores ; list; list=g_slist_next(list))
    {
        core = list->data;

        VEC3SET(core->offset, 0.0, 0.0, 0.0);
    }
}
Пример #8
0
void gui_phonon_cleanup(struct model_pak *model)
{
GSList *list;
struct core_pak *core;

g_assert(model != NULL);

/* reset offsets */
for (list=model->cores ; list; list=g_slist_next(list))
  {
  core = list->data;
  VEC3SET(core->offset, 0.0, 0.0, 0.0);
  }
model->animating = FALSE;

/* recalc coords and adjust bond orientations */
coords_compute(model);
connect_midpoints(model);
redraw_canvas(SINGLE);
}
Пример #9
0
struct shel_pak *dup_shel(struct shel_pak *orig)
{
struct shel_pak *shel;

/* checks */
g_assert(orig != NULL);

shel = g_malloc(sizeof(struct shel_pak));

memcpy(shel, orig, sizeof(struct shel_pak));

/* clear pointers */
shel->core = NULL;
shel->primary_shell = NULL;
VEC3SET(shel->pic, 0, 0, 0);

/* duplicate strings */
shel->flags = g_strdup(orig->flags);

return(shel);
}
Пример #10
0
gpointer zval_new(void)
{
struct zval_pak *zval;

zval = g_malloc(sizeof(struct zval_pak));

zval->type = -1;

zval->connect[0] = -1;
zval->connect[1] = -1;
zval->connect[2] = -1;

zval->fitting[0] = -1;
zval->fitting[1] = -1;
zval->fitting[2] = -1;

zval->name[0] = NULL;
zval->name[1] = NULL;
zval->name[2] = NULL;

VEC3SET(zval->value, 0.0, 0.0, 0.0);

return(zval);
}
Пример #11
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);
}
Пример #12
0
gint load_planes(gchar *filename, struct model_pak *data)
{
gint h, k, l, num_tokens;
gint cflag=FALSE, sflag=FALSE, gflag=FALSE;
gdouble m[3];
gchar **buff;
GSList *list, *new_planes;
struct plane_pak *plane=NULL;
struct shift_pak *shift=NULL;
FILE *fp;

fp = fopen(filename, "rt");
if (!fp)
  return(1);

/* get next line */
new_planes = NULL;
for (;;)
  {
  buff = get_tokenized_line(fp, &num_tokens);
  if (!buff)
    break;

/* NB: only update space/cell etc. data if this call did */
/* not originate from an import planes call */
  if (data->id == MORPH)
    {
/* cell parameters */
    if (g_ascii_strncasecmp(*buff,"cell",4) == 0)
      {
      if (num_tokens >= 7)
        {
        cflag=TRUE;
        data->pbc[0] = str_to_float(*(buff+1));
        data->pbc[1] = str_to_float(*(buff+2));
        data->pbc[2] = str_to_float(*(buff+3));
        data->pbc[3] = PI*str_to_float(*(buff+4))/180.0;
        data->pbc[4] = PI*str_to_float(*(buff+5))/180.0;
        data->pbc[5] = PI*str_to_float(*(buff+6))/180.0;
/* compute direct & reciprocal lattices */
/* NB: enables fn_make_plane() to correctly compute Dhkl */
        matrix_lattice_init(data);
        }
      else
        printf("load_planes() error: bad cell line.\n");
      }

/* space group */
    if (g_ascii_strncasecmp(*buff,"space",5) == 0)
      {
      if (num_tokens > 1)
        {
      sflag=TRUE;
      data->sginfo.spacename = g_strjoinv(" ", buff+1);
      data->sginfo.spacenum = 0;
        }
      }

/* default morphology type */
    if (g_ascii_strncasecmp(*buff, "morph", 5) == 0)
      {
      if (num_tokens >= 3)
        {
        if (g_ascii_strncasecmp(*(buff+1), "unrelaxed", 9) == 0)
          {
          if (g_ascii_strncasecmp(*(buff+2), "equil", 5) == 0)
            data->morph_type = EQUIL_UN;
          if (g_ascii_strncasecmp(*(buff+2), "growth", 6) == 0)
            data->morph_type = GROWTH_UN;
          }
  
        if (g_ascii_strncasecmp(*(buff+1), "relaxed", 7) == 0)
          {
          if (g_ascii_strncasecmp(*(buff+2), "equil", 5) == 0)
            data->morph_type = EQUIL_RE;
          if (g_ascii_strncasecmp(*(buff+2), "growth", 6) == 0)
            data->morph_type = GROWTH_RE;
          }
        }
      else
        printf("load_planes() error: bad type line.\n");
      }
    }

/* process miller line */
  if (g_ascii_strncasecmp(*buff,"miller",6) == 0)
    {
/* init space group (latmat? - if so, remove the make_latmat() in cell parse) */
    if (cflag && sflag)
      {
      if (!gflag)
        {
        if (space_lookup(data))
          printf("Error in space group lookup.\n");
        gflag = TRUE;
        }
      }
    else
      {
      if (data->id == MORPH)
        {
        printf("load_planes() error: miller encountered before space or cell.\n");
        return(2);
        }
      }

    if (num_tokens >= 4)
      {
      h = (gint) str_to_float(*(buff+1));
      k = (gint) str_to_float(*(buff+2));
      l = (gint) str_to_float(*(buff+3));
#if DEBUG_LOAD_PLANES
printf("read plane: %d %d %d\n", h, k, l);
#endif
      VEC3SET(m, h, k, l);
/* FIXME - signature change */
/*
      plane = plane_find(m, data);
*/

      if (!plane)
        {
        plane = plane_new(m, data);
        if (plane)
          new_planes = g_slist_prepend(new_planes, plane);
        }
      }
    }

/* potential data */
  if (num_tokens >= 8 && plane)
    {
/* NB: use create_shift(), as it sets some important defaults */
    shift = shift_new(0.0);
    if (shift)
      {
      shift->shift = str_to_float(*(buff+0));
      shift->region[0] = str_to_float(*(buff+1));
      shift->region[1] = str_to_float(*(buff+2));
      shift->esurf[0] = str_to_float(*(buff+3));
      shift->eatt[0] = str_to_float(*(buff+4));
      shift->esurf[1] = str_to_float(*(buff+5));
      shift->eatt[1] = str_to_float(*(buff+6));
      shift->gnorm = str_to_float(*(buff+7));
#if DEBUG_LOAD_PLANES
printf("adding shift: %f\n", shift->shift);
#endif
/* append to preserve order (eg import on existing plane set) */
      plane->shifts = g_slist_append(plane->shifts, shift);
      }
    }
  g_strfreev(buff);
  }
data->planes = g_slist_concat(data->planes, g_slist_reverse(new_planes));

/* compute dhkl's for the plane's list */
for (list=data->planes ; list ; list=g_slist_next(list))
  {
  plane = list->data;

/* create default shift if none found */
  if (!plane->shifts)
    {
    shift = shift_new(0.0);
    if (shift)
      plane->shifts = g_slist_append(plane->shifts, shift);
    }
/* get best energy for the plane */
/* FIXME - signature changed */
/*
  update_plane_energy(plane, data);
*/
  }

/* compute symmetry related faces */
/* FIXME - new surface rewrite */
/*
surf_symmetry_generate(data);
*/

fclose(fp);
return(0);
}
Пример #13
0
void docking_project_create(GtkWidget *w, struct model_pak *model)
{
gint a, b, i, m, n, rx, ry, rz, size, rigid_save;
gint a_max, b_max, rx_max, ry_max, rz_max;
gchar *file, *dump, *dump_save, *rigid_move_save;
gdouble dx, dy, dz, x[3], scale[3], mat[9], dock_centroid[3], q[4];
GString *name, *rigid;
GSList *list, *core_list, *shell_list;
struct dock_pak *dock;
struct core_pak *core, *core2;
struct shel_pak *shell, *shell2;
FILE *fp;

/* checks */
g_assert(model != NULL);
size = g_slist_length(model->selection);
if (!size)
  {
  gui_text_show(WARNING, "Please select the subset you wish to dock.\n");
  return;
  }

/* create new docking project */
dock = g_malloc(sizeof(struct dock_pak));

/* NEW - setup project path */
/*
g_path_get_dirname(model->fullpath);
g_get_current_dir();
*/

/* seek a file name that doesn't exist (avoid background overwriting) */
name = g_string_new(NULL);
i=0;
do
  {
  g_string_sprintf(name, "project_%06d", i);
  i++;
  }
while (g_file_test(name->str, G_FILE_TEST_EXISTS));

dock->path = g_build_path(sysenv.cwd, name->str, NULL);

printf("creating new project: [%s]\n", dock->path);

#if WIN32
if (mkdir(dock->path))
#else
if (mkdir(dock->path, 0700))
#endif
  {
  gui_text_show(ERROR, "Failed to create project directory.\n");
  g_free(dock->path);
  g_free(dock);
  return;
  }

/* project control file */
g_string_sprintf(name, "%s%sproject.pcf", dock->path, DIR_SEP);
fp = fopen(name->str, "wt");

/* save original variables */
dump_save = model->gulp.dump_file;
model->gulp.dump_file = NULL;
rigid_save = model->gulp.rigid;
model->gulp.rigid = dock_rigid_on;
rigid_move_save = model->gulp.rigid_move;
model->gulp.rigid_move = NULL;
if (model->gulp.rigid)
  {
  rigid = g_string_new(NULL);
  if (dock_rigid_x)
    g_string_sprintf(rigid, "x");
  if (dock_rigid_y)
    g_string_sprintfa(rigid, "y");
  if (dock_rigid_z)
    g_string_sprintfa(rigid, "z");
  model->gulp.rigid_move = g_string_free(rigid, FALSE);
  }

/* duplicate selection for docking */
core_list = NULL;
shell_list = NULL;
VEC3SET(dock_centroid, 0.0, 0.0, 0.0);
for (list=model->selection ; list ; list=g_slist_next(list))
  {
  core2 = dup_core(list->data);
  core_list = g_slist_prepend(core_list, core2);
  if (core2->shell)
    shell_list = g_slist_prepend(shell_list, core2->shell);
/* compute centroid */
  ARR3ADD(dock_centroid, core2->x);
  }

/* NB: lists must have the same order as original selection */
core_list = g_slist_reverse(core_list);
shell_list = g_slist_reverse(shell_list);
VEC3MUL(dock_centroid, 1.0/(gdouble) size);

/* fractional translation grid units */
scale[0] = dock_cell[0] / dock_grid[0];
scale[1] = dock_cell[1] / dock_grid[1];

/* rotational increments */
dx = PI/dock_rotate[0];
dy = PI/dock_rotate[1];
dz = PI/dock_rotate[2];

/* translational sampling */
if (dock_grid_on)
  {
  a_max = dock_grid[0];
  b_max = dock_grid[1];
  }
else
  {
  a_max = 1;
  b_max = 1;
  }

/* rotational sampling */
if (dock_rotate_on)
  {
  rx_max = dock_rotate[0];
  ry_max = dock_rotate[1];
  rz_max = dock_rotate[2];
  }
else
  {
  rx_max = 1;
  ry_max = 1;
  rz_max = 1;
  }

/* project header */
fprintf(fp, "%%title solvent mapping project\n");
fprintf(fp, "%%set %d %d %f %f\n", a_max, b_max, dock_cell[0], dock_cell[1]);

/* loop over all grid translations */
m = n = 0;
for (a=0 ; a<a_max ; a++)
  {
  for (b=0 ; b<b_max ; b++)
    {
    VEC3SET(x, a, b, 0.0);
    x[0] *= scale[0];
    x[1] *= scale[1];

/* loop over rotations */
    VEC4SET(q, 1.0, 0.0, 0.0, 0.0);
    for (rx=0 ; rx<rx_max ; rx++)
      {
      if (rx)
        quat_concat_euler(q, PITCH, dx);

    for (ry=0 ; ry<ry_max ; ry++)
      {
      if (ry)
        quat_concat_euler(q, ROLL, dy);

    for (rz=0 ; rz<rz_max ; rz++)
      {
      if (rz)
        quat_concat_euler(q, YAW, dz);

/* build total rotation matrix */
      quat_matrix(mat, q);

/* transform the cores and shells */
      i = 0;
      for (list=model->selection ; list ; list=g_slist_next(list))
        {
        core = list->data;

/* FIXME - should we restore this after? how? */
core->region = 2;

/* get original selection core coordinates */
        core2 = g_slist_nth_data(core_list, i);
        ARR3SET(core->x, core2->x);
/* perform the rotation (NB: must be done about origin in cartesian space) */
        ARR3SUB(core->x, dock_centroid);
        vecmat(model->latmat, core->x);
        vecmat(mat, core->x);
        vecmat(model->ilatmat, core->x);
        ARR3ADD(core->x, dock_centroid);
/* add the current translation offset */
        ARR3ADD(core->x, x);

/* as above, for the associated shell */
        if (core->shell)
          {
          shell = core->shell;
shell->region = 2;
          shell2 = core2->shell;
g_assert(shell2 != NULL);
          ARR3SET(shell->x, shell2->x);
          ARR3SUB(shell->x, dock_centroid);
          vecmat(model->latmat, shell->x);
          vecmat(mat, shell->x);
          vecmat(model->ilatmat, shell->x);
          ARR3ADD(shell->x, dock_centroid);
          ARR3ADD(shell->x, x);
          }
        i++;
        }
/* write docking configuration */
/*
      file = g_strdup_printf("%s_%06d.gin", model->basename, n);
*/

/* m identifies grid points (for later minimum check) */
fprintf(fp, "%s_%06d.gin %f %f %d\n", model->basename, n, x[0], x[1], m);

      file = g_strdup_printf("%s%s%s_%06d.gin", dock->path, DIR_SEP, model->basename, n);
      dump = g_strdup_printf("%s_%06d.res", model->basename, n);

      model->gulp.dump_file = dump;

      write_gulp(file, model);

      g_free(file);
      g_free(dump);
      n++;

      }
      }
      }
    m++;
    }
  }

/* restore original variables */
model->gulp.dump_file = dump_save;
model->gulp.rigid = rigid_save;
g_free(model->gulp.rigid_move);
model->gulp.rigid_move = rigid_move_save;

/* restore original selection (delete, then concat saved list) */
i = 0;
for (list=model->selection ; list ; list=g_slist_next(list))
  {
  core = list->data;
  core2 = g_slist_nth_data(core_list, i);
  ARR3SET(core->x, core2->x);
  if (core->shell)
    {
    shell = core->shell;
    shell2 = core2->shell;
g_assert(shell2 != NULL);
    ARR3SET(shell->x, shell2->x);
    }
  i++;
  }

/* free docking core/shell lists */
free_slist(core_list);
free_slist(shell_list);

g_string_free(name, TRUE);
fclose(fp);
/* run docking in background unless told to stop after setup */
/*
if (!dock_no_execute)
  submit_task("Docking", &docking_execute, dock, &docking_cleanup, dock, model);
*/
}
Пример #14
0
gint read_diffax(gchar *filename, struct model_pak *model)
{
gint num_tokens, num_layer, tot_layer;
gdouble offset;
gchar **buff;
GSList *list1, *list2;
struct core_pak *core;
struct layer_pak *layer;
FILE *fp;

/* checks */
g_return_val_if_fail(model != NULL, 1);
g_return_val_if_fail(filename != NULL, 2);
fp = fopen(filename, "rt");
if (!fp)
  return(3);

/* setup */
model->id = DIFFAX_INP;
model->fractional = TRUE;
model->periodic = 3;
model->colour_scheme = REGION;

strcpy(model->filename, filename);
g_free(model->basename);
model->basename = parse_strip(filename);

/* scan the file */
while ((buff = get_tokenized_line(fp, &num_tokens)))
  {
  diffax_keyword_search:;

/* restricted unit cell */
  if (g_ascii_strncasecmp("structural", *buff, 10) == 0)
    {
    g_strfreev(buff);
    buff = get_tokenized_line(fp, &num_tokens);
    if (num_tokens > 3)
      {
      model->pbc[0] = str_to_float(*(buff+0));
      model->pbc[1] = str_to_float(*(buff+1));
      model->pbc[2] = str_to_float(*(buff+2));
      model->pbc[3] = PI/2.0;
      model->pbc[4] = PI/2.0;
      model->pbc[5] = D2R*str_to_float(*(buff+3));
      }
    }

/* layer testing */
  if (g_ascii_strncasecmp("layer", *buff, 5) == 0)
    {
    layer = g_malloc(sizeof(struct model_pak));
    layer->width = 1.0;
    VEC3SET(layer->centroid, 0.5, 0.5, 0.5);
    layer->cores = NULL;
    model->layer_list = g_slist_prepend(model->layer_list, layer);

    g_strfreev(buff);
    buff = get_tokenized_line(fp, &num_tokens);
    if (buff)
      {
/* TODO - if centrosymmetric : add a -1 operation */
      }

/* get layer data */
    g_strfreev(buff);
    buff = get_tokenized_line(fp, &num_tokens);
    while (buff)
      {
      if (elem_symbol_test(*buff))
        {
        if (num_tokens > 6)
          {
/*
printf("[%s] [%s  %s  %s]\n", *buff, *(buff+2), *(buff+3), *(buff+4));
*/
          core = new_core(*buff, model);
          model->cores = g_slist_prepend(model->cores, core);
          layer->cores = g_slist_prepend(layer->cores, core);

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

          core->sof = str_to_float(*(buff+5));
          }
        }
      else
        goto diffax_keyword_search;

/* get next line of tokens */
      g_strfreev(buff);
      buff = get_tokenized_line(fp, &num_tokens);
      }
    }

  g_strfreev(buff);
  }

/* TODO - enumerate layers and scale, so they are stacked 1..n in a single cell */
/* also label the layers as different region types */
model->layer_list = g_slist_reverse(model->layer_list);
num_layer = 0;
tot_layer = g_slist_length(model->layer_list);

model->pbc[2] *= tot_layer;

#if DEBUG_READ_DIFFAX
printf("Read in %d layers.\n", tot_layer);
#endif

for (list1=model->layer_list ; list1 ; list1=g_slist_next(list1))
  {
  layer = (struct layer_pak *) list1->data;
  layer->width = 1.0 / (gdouble) tot_layer;

  offset = (gdouble) num_layer * layer->width;

  VEC3SET(layer->centroid, 0.0, 0.0, offset);

  for (list2=layer->cores ; list2 ; list2=g_slist_next(list2))
    {
    core = (struct core_pak *) list2->data;

/* scale to within the big cell (encloses all DIFFAX layers) */
    core->x[2] *= layer->width;

/* offset each particular layer */
    core->x[2] += offset;

    core->region = num_layer;
    }
  num_layer++;
  }

/* end of read */
fclose(fp);

/* post read setup */
model->cores = g_slist_reverse(model->cores);
model_prep(model);

return(0);
}
Пример #15
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);
    }
  }
}
Пример #16
0
gint read_rietica(gchar *filename, struct model_pak *model)
{
gint i, phases=0, skip, num_tokens;
gchar **buff, *line;
float x, y, z;
gpointer scan;
GSList *list;
struct core_pak *core;

/* checks */
g_assert(model != NULL);
scan = scan_new(filename);
if (!scan)
  return(1);

/* FIXME - stop the previous file routines setting this */
model->id = -1;

while (!scan_complete(scan))
  {
  buff = scan_get_tokens(scan, &num_tokens);
  
/* search for structure start */
  if (num_tokens)
    {
    if (g_ascii_strncasecmp(*buff, "***", 3) == 0)
      {
      if (phases)
        model = model_new();
      phases++;

/* structure name - omit the 1st and last tokens (ie "***") */
      if (num_tokens > 1)
        {
        g_free(*(buff+num_tokens-1));
        *(buff+num_tokens-1) = NULL;
        g_free(model->basename);
        model->basename = g_strjoinv(" ", buff+1);
        }

/* parse spacegroup */
      line = scan_get_line(scan);
      line = scan_get_line(scan);
      model->sginfo.spacename = g_strstrip(g_strdup(line));
      model->sginfo.spacenum = -1;

/* parse a structure */
      skip = 0;
      while (!scan_complete(scan))
        {
        g_strfreev(buff);
        buff = scan_get_tokens(scan, &num_tokens);

        if (num_tokens)
          {
          if (elem_symbol_test(*buff))
            {
/* new core */
/*
            if (num_tokens > 6)
*/
              {
              core = new_core(*buff, model);
              model->cores = g_slist_prepend(model->cores, core);

/* formatted output can result in -ve signs "joining" tokens */
              line = scan_cur_line(scan);
/* no doubt some fortran programmer thought this was a clever format */
              sscanf(line, "%*16c%8f%8f%8f", &x, &y, &z);
              VEC3SET(core->x, x, y, z);

/*
printf("> %s", line);
P3VEC(" - ", core->x);
              core->x[0] = str_to_float(*(buff+2));
              core->x[1] = str_to_float(*(buff+3));
              core->x[2] = str_to_float(*(buff+4));
              core->sof = str_to_float(*(buff+6));
*/

              skip = 0;
              }
            }
          else
            skip++;
          }

/* 4 lines after the last core - parse cell info and terminate structure */
        if (skip == 4)
          {
          if (num_tokens > 5)
            {
            for (i=6 ; i-- ; )
              model->pbc[i] = str_to_float(*(buff+i));
            model->pbc[3] *= D2R;
            model->pbc[4] *= D2R;
            model->pbc[5] *= D2R;
            }
          break;
          }
        }
      }
    }
  g_strfreev(buff);
  }

/* setup all new structures */
for (list=sysenv.mal ; list ; list=g_slist_next(list))
  {
  model = list->data;

  if (model->id == -1)
    {
    model->id = RIETICA;
    model->periodic = 3;
    model->fractional = TRUE;
    strcpy(model->filename, filename);
    model->cores = g_slist_reverse(model->cores);
    model_prep(model);
    }
  }

scan_free(scan);

return(0);
}