Beispiel #1
0
void gui_siesta_mode_show(GtkWidget *w, gpointer dialog)
{
    gint i, atom, state;
    gdouble scale, x1[3], x2[3], colour[3];
    gpointer button, spin;
    GSList *list;
    struct core_pak *core;
    struct spatial_pak *spatial;
    struct model_pak *model;

    g_assert(dialog != NULL);

    model = dialog_model(dialog);
    g_assert(model != NULL);

    button = dialog_child_get(dialog, "phonon_toggle");
    g_assert(button != NULL);

    spatial_destroy_by_label("siesta_phonons", model);

    state = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(button));
    if (!state)
    {
        redraw_canvas(SINGLE);
        return;
    }

    spin = dialog_child_get(dialog, "phonon_scaling");
    scale = SPIN_FVAL(spin);

    /* create & init the spatial object */
    spatial = spatial_new("siesta_phonons", SPATIAL_VECTOR, 2, TRUE, model);

    atom = 0;
    /* get eigenvectors from all atoms */
    for (list=model->cores ; list; list=g_slist_next(list))
    {
        core = list->data;
        ARR3SET(x1, core->x);

        /* get current eigenvector */
        i = model->siesta.sorted_eig_values[model->siesta.current_animation];
        x2[0] = mesch_me_get(model->siesta.eigen_xyz_atom_mat, 3*atom, i);
        x2[1] = mesch_me_get(model->siesta.eigen_xyz_atom_mat, 3*atom+1, i);
        x2[2] = mesch_me_get(model->siesta.eigen_xyz_atom_mat, 3*atom+2, i);
        atom++;

        /* compute coords */
        VEC3MUL(x2, scale);
        vecmat(model->ilatmat, x2);
        ARR3ADD(x2, x1);
        /* add to spatial */
        spatial_vertex_add(x2, colour, spatial);
        spatial_vertex_add(x1, colour, spatial);
    }

    /* drawing update */
    coords_compute(model);
    redraw_canvas(SINGLE);
}
Beispiel #2
0
void show_phonon_components(struct model_pak *model)
{
gdouble f, lc, lf, xc[3], xf[3];
gpointer ptr;
GSList *list;
struct core_pak *core;

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

/* get required mode to analyse */
ptr = g_slist_nth_data(model->phonons, model->current_phonon-1);
if (!ptr)
  return;
f = str_to_float(ptr);

printf("--------------------------------------------------------------------------\n");
printf("Mode: %d, Frequency = %f\n", model->current_phonon, f);
printf("--------------------------------------------------------------------------\n");
printf("  atom  |   len   |     x        y        z    |      a        b        c\n");
printf("--------------------------------------------------------------------------\n");

for (list=model->selection ; list; list=g_slist_next(list))
  {
  core = (struct core_pak *) list->data;

/* get eigen-vector components */
  xc[0] = *((gdouble *) g_slist_nth_data(core->vibx_list, model->current_phonon-1));
  xc[1] = *((gdouble *) g_slist_nth_data(core->viby_list, model->current_phonon-1));
  xc[2] = *((gdouble *) g_slist_nth_data(core->vibz_list, model->current_phonon-1));
  ARR3SET(xf, xc);
  vecmat(model->ilatmat, xf);

  lc = VEC3MAG(xc);
  lf = VEC3MAG(xf);

  VEC3MUL(xc, 1.0/lc);
  VEC3MUL(xf, 1.0/lf);

  printf("%6s  | %7.4f | %7.2f  %7.2f  %7.2f  |  %7.2f  %7.2f  %7.2f\n",
          core->atom_label, lc, xc[0], xc[1], xc[2], xf[0], xf[1], xf[2]);

  }
}
Beispiel #3
0
void camera_rescale(gdouble r, gpointer data)
{
gdouble x[3];
struct camera_pak *camera = data;

ARR3SET(x, camera->x);
normalize(x, 3);
VEC3MUL(x, r);
ARR3SET(camera->x, x);
}
Beispiel #4
0
void set_colour_value(GtkWidget *cs, gdouble *x)
{
GdkColor colour;

gtk_color_selection_get_current_color(GTK_COLOR_SELECTION(cs), &colour);

x[0] = colour.red;
x[1] = colour.green;
x[2] = colour.blue;
VEC3MUL(x, 1.0/65535.0);
}
Beispiel #5
0
void camera_rotate_animate(gint axis, gdouble *angle, gint overwrite, struct model_pak *model)
{
gdouble a, radian[3];
GSList *journey;
struct camera_pak *camera;

g_assert(model != NULL);

dialog_destroy_type(ANIM);

/* TODO - angle checks */
ARR3SET(radian, angle);
VEC3MUL(radian, D2R);

journey = NULL;
for (a=radian[0] ; a<radian[1]+0.5*radian[2] ; a+=radian[2])
  {
  camera = camera_dup(model->camera);
  switch (axis)
    {
    case 1:
      quat_concat_euler(camera->q, ROLL, a);
      break;

    case 2:
      quat_concat_euler(camera->q, YAW, a);
      break;

    default:
      quat_concat_euler(camera->q, PITCH, a);
    }
  journey = g_slist_prepend(journey, camera);
  }

journey = g_slist_reverse(journey);

if (overwrite)
  {
  free_slist(model->transform_list);
  model->transform_list = journey;
  }
else
  model->transform_list = g_slist_concat(model->transform_list, journey);

model->num_frames = g_slist_length(model->transform_list);
model->animation = TRUE;

redraw_canvas(SINGLE);
}
Beispiel #6
0
gint facet_visible(struct model_pak *data, struct plane_pak *plane)
{
gdouble a, norm[3], vec[3];

/* NEW - an edge (2 vertices) is not to be treated as visible */
if (g_slist_length(plane->vertices) < 3)
  return(FALSE);

/* get plane  normal */
ARR3SET(norm, plane->norm);

VEC3MUL(norm, -1.0);

#if DEBUG_FACET
printf("facet (%2d%2d%2d), norm: %5.2f,%5.2f,%5.2f    " 
,plane->index[0] ,plane->index[1] ,plane->index[2]
,norm[0],norm[1],norm[2]);
#endif

/* absolute viewing vector, determining if visible or not */
camera_view(vec, data->camera);

/* got correct facet normal - is it visible? */
a = via(norm,vec,3);
if (a < 0.5*G_PI)
  {
#if DEBUG_FACET
printf("view: %5.2f,%5.2f,%5.2f (%5.1f) YES\n",vec[0],vec[1],vec[2],180.0*a/PI);
#endif
  return(TRUE);
  }
/* else... */
#if DEBUG_FACET
printf("view: %5.2f,%5.2f,%5.2f (%5.1f) NO\n",vec[0],vec[1],vec[2],180.0*a/PI);
#endif
return(FALSE);
}
Beispiel #7
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);
}
Beispiel #8
0
void camera_waypoint_animate(gint frames, gint overwrite, struct model_pak *model)
{
gint i;
gdouble a, af, v[3], e[3], o[3], tmp[3];
gdouble jf, jv[3], x[3], mat[9];
GSList *list, *journey;
struct camera_pak *cam, *cam1, *cam2;

/* checks */
g_assert(model != NULL);
g_assert(frames > 0);
if (g_slist_length(model->waypoint_list) < 2)
  {
  gui_text_show(ERROR, "You need to make at least 2 waypoint.\n");
  return;
  }

/* close any active animation dialog */
dialog_destroy_type(ANIM);

#if DEBUG_CAMERA_ANIMATE
printf("frames for each traversal: %d\n", frames);
#endif

list = model->waypoint_list;
cam1 = list->data;
list = g_slist_next(list);

/* create the camera journey */
journey = NULL;
while (list)
  {
  cam2 = list->data;

/* setup camera journey vector */
  ARR3SET(jv, cam2->x);
  ARR3SUB(jv, cam1->x);

/* add starting camera over journey leg */
  for (i=0 ; i<frames ; i++)
    {
/* journey fraction */
    jf = i;
    jf /= frames;

    ARR3SET(x, jv);
    VEC3MUL(x, jf);    

    cam = camera_dup(cam1);
    ARR3ADD(cam->x, x);

    journey = g_slist_prepend(journey, cam);
    }
 
/* approx 5 degrees */
#define ROTATION_INCREMENT 0.08727
/* (v x e plane alignment) */
proj_vop(v, cam2->v, cam1->o);
a = via(v, cam1->v, 3);

/* compute rotation increment */
af = (gint) nearest_int(a / ROTATION_INCREMENT);
if (!af)
  af = 1.0;

/* test rotation sense */
matrix_v_rotation(mat, cam1->o, a);
ARR3SET(tmp, cam1->v);
vecmat(mat, tmp);
if (via(tmp, v, 3) > 0.1)
  a *= -1.0;

/* build rotaton */
matrix_v_rotation(mat, cam1->o, a/af);

/* apply to camera */
ARR3SET(v, cam1->v);
ARR3SET(e, cam1->e);
for (i=af ; i-- ; )
  {
  cam = camera_dup(cam1);
  ARR3SET(cam->x, cam2->x);

  vecmat(mat, v);
  vecmat(mat, e);

  ARR3SET(cam->v, v);
  ARR3SET(cam->e, e);

  journey = g_slist_prepend(journey, cam);
  }

/* TODO - apply elevation to get v in complete coincidence */
/* rotate about e to achieve coincidence */
a = via(v, cam2->v, 3);

/* compute rotation increment */
af = (gint) nearest_int(a / ROTATION_INCREMENT);
if (!af)
  af = 1.0;

/* test rotation sense */
matrix_v_rotation(mat, e, a);
ARR3SET(tmp, v);
vecmat(mat, tmp);
if (via(tmp, cam2->v, 3) > 0.1)
  a *= -1.0;

/* build rotaton */
matrix_v_rotation(mat, e, a/af);

/* apply to camera */
ARR3SET(o, cam1->o);
for (i=af ; i-- ; )
  {
  cam = camera_dup(cam1);
  ARR3SET(cam->x, cam2->x);

  vecmat(mat, v);
  vecmat(mat, o);

  ARR3SET(cam->v, v);
  ARR3SET(cam->o, o);
  ARR3SET(cam->e, e);

  journey = g_slist_prepend(journey, cam);
  }

/* endpoint camera */
  journey = g_slist_prepend(journey, camera_dup(cam2));

/* get next journey leg */
  cam1 = cam2;
  list = g_slist_next(list);
  }
journey = g_slist_reverse(journey);

if (overwrite)
  {
  free_slist(model->transform_list);
  model->transform_list = journey;
  }
else
  model->transform_list = g_slist_concat(model->transform_list, journey);

model->num_frames = g_slist_length(model->transform_list);
model->animation = TRUE;

redraw_canvas(SINGLE);
}
Beispiel #9
0
void povray_hdr(FILE *fp, struct model_pak *data)
{
gdouble xvec, yvec, amb, pos[3], colour[3];
gdouble x[3], o[3], v[3], e[3];
GSList *list;
struct light_pak *light;
struct camera_pak *camera;

g_assert(data != NULL);
g_assert(data->camera != NULL);

fprintf(fp,"#include \"colors.inc\" \n");
fprintf(fp,"#include \"finish.inc\" \n");
fprintf(fp,"#include \"glass.inc\" \n");
fprintf(fp,"#include \"metals.inc\" \n");
fprintf(fp,"#include \"textures.inc\" \n");

/* background colour (except for glass morphologies) */
fprintf(fp,"background { color rgb<%f,%f,%f0> }\n", sysenv.render.bg_colour[0],
                        sysenv.render.bg_colour[1], sysenv.render.bg_colour[2]);  

/* pixel to angstrom conversion, with yet another magic number... */
p2a = 0.565 * (gdouble) sysenv.render.width / data->rmax;

/* preserve model aspect ratio for the given image size */
xvec = yvec = 2.0*sysenv.rsize;
if (sysenv.render.width > sysenv.render.height)
  xvec *= sysenv.render.width/sysenv.render.height;
if (sysenv.render.height > sysenv.render.width)
  yvec *= sysenv.render.height/sysenv.render.width;

/* compute camera position and orientation */
camera = data->camera;
ARR3SET(x, camera->x);
ARR3SET(o, camera->o);
ARR3SET(v, camera->v);

switch (camera->mode)
  {
  case FREE:
    break;

  default:
  case LOCKED:
    quat_rotate(x, camera->q);
    quat_rotate(o, camera->q);
    quat_rotate(v, camera->q);
    break;
  }
/* convert viewing vector to a location */
ARR3ADD(v, x);

/* camera zoom */
xvec *= camera->zoom;
yvec *= camera->zoom;

/* NEW - enable movies of left/right eye to be produced */
if (sysenv.stereo)
  {
/* get axis for eye translation (view x up vector) */
  crossprod(e, v, o);
  normalize(e, 3);

/* the old 2% rule ... */
  VEC3MUL(e, 0.02 * sysenv.rsize); 

/* default is left eye only */
  if (sysenv.render.stereo_right)
    {
    ARR3ADD(x, e);
    ARR3ADD(v, e);
    }
  else
    {
    ARR3SUB(x, e);
    ARR3SUB(v, e);
    }
  }

/* sky is the orientation vector */
/* right and up give the perspective */
if (camera->perspective)
  {
  fprintf(fp,"camera { location <%f,%f,%f>\n", x[0], x[1], x[2]);
  fprintf(fp,"    sky <%f,%f,%f>\n", o[0], o[1], o[2]);
  fprintf(fp,"    right <%f,0,0> up <%f,0,0>\n", xvec, yvec);
  fprintf(fp,"    look_at <%f,%f,%f>\n", v[0], v[1], v[2]);
  fprintf(fp,"    angle %f }\n", camera->fov);
  }
else
  {
  fprintf(fp,"camera { orthographic location <%f,%f,%f>\n", x[0], x[1], x[2]);
  fprintf(fp,"    sky <%f,%f,%f>\n", o[0], o[1], o[2]);
  fprintf(fp,"    right <%f,0,0> up <%f,0,0>\n", xvec, yvec);
  fprintf(fp,"    look_at <%f,%f,%f> }\n", v[0], v[1], v[2]);
  }

/* create light sources */
for (list=sysenv.render.light_list ; list ; list=g_slist_next(list))
  {
  light = list->data;
  ARR3SET(pos, light->x);

/* OpenGL -> POVRay axes */
  pos[0] *= -1.0;
  pos[1] *= -1.0;
  pos[2] *= -1.0;

  quat_rotate(pos, camera->q);

  switch (light->type)
    {
    case POSITIONAL:
      fprintf(fp,"light_source\n  {\n <%f,%f,%f>\n", pos[0], pos[1], pos[2]);
      break;

    case DIRECTIONAL:
/* move away far enough so the rays are ~ // */
      VEC3MUL(pos, 100.0*data->rmax);
      fprintf(fp,"light_source\n  {\n <%f,%f,%f>\n", pos[0], pos[1], pos[2]);
      break;

    default:
      continue;
    }

/* simulate OpenGL style lights */
  ARR3SET(colour, light->colour);
  VEC3MUL(colour, light->specular);

  if (sysenv.render.shadowless)
    fprintf(fp,"  color rgb<%f,%f,%f> shadowless }\n", colour[0], colour[1], colour[2]);
  else
    {
/* old style lighting */
/*
    fprintf(fp,"  color rgb<%f,%f,%f> }\n", colour[0], colour[1], colour[2]);
*/
    fprintf (fp,"color White\n");
    fprintf (fp,"   area_light <5, 0, 0,>, <0, 0, 5>, 5, 5\n");
    fprintf (fp,"   adaptive 1\n   jitter\n}\n");
    }
  }

/* fill-light to bring out the shadows */
fprintf(fp,"light_source{<%f,%f,%f> color Gray80 shadowless}\n", pos[0], pos[1], pos[2]);

/* morph is too dark with just the above, sky_sphere is *nice* */
/* TODO - choice of colour eg white/grey/light blue */
/* NB: white is a bit too bright (even with 0 ambience) */
if (data->id == MORPH)
  {
  if (!sysenv.render.wire_surface && !sysenv.render.shadowless)
    {
    fprintf(fp,"sky_sphere { pigment {gradient y  color_map "
               "{[0, 1 color Gray20 color White]} rotate x*45}}\n");
    }
  }

/* POVRay is a bit darker than OpenGL */
amb = 20.0*sysenv.render.ambience;

fprintf(fp,"global_settings { ambient_light rgb<%f, %f, %f> assumed_gamma 2.2}\n",amb,amb,amb);
}
Beispiel #10
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);
*/
}
Beispiel #11
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);
    }
  }
}
gint write_gromacs_gro(gchar *filename, struct model_pak *model)
{
gint n, c, i, s;
gdouble x[3], min[3], max[3];
GSList *list;
struct core_pak *core;
FILE *fp;

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

/* init min/max for box calculation */
for (i=3 ; i-- ; )
  {
  max[i] = -G_MAXDOUBLE;
  min[i] = G_MAXDOUBLE;
  }

fprintf(fp, "GROMACS coordinates (generated by GDIS v%f)\n", VERSION);

c = g_slist_length(model->cores);
s = g_slist_length(model->shels);

fprintf(fp, "%5d\n", c+s);

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

/* cartesians */
  ARR3SET(x, core->x);
  vecmat(model->latmat, x);
/* angs -> nm */
  VEC3MUL(x, 0.1);
  fprintf(fp, "%5i%5s%5s%5i%8.3f%8.3f%8.3f%8.4f%8.4f%8.4f\n",
               n, "UNK", core->atom_label, 1, 
               x[0], x[1], x[2], 0.1*core->v[0], 0.1*core->v[1], 0.1*core->v[2]);

/* record min/max for box calculation */
  for (i=3 ; i-- ; )
    {
    if (x[i] < min[i])
      min[i] = x[i];
    if (x[i] > max[i])
      max[i] = x[i];
    }

  if (core->shell)
    {
/* TODO - has an 'x' post-fix to the atom_label */
    }

  n++;
  }

/* this is the distance between the min and max atom coords in x, y, and z */
/* box calculation */
if (model->periodic == 3)
  {
  fprintf(fp, "% f %f %f\n", 0.1*model->pbc[0], 0.1*model->pbc[1], 0.1*model->pbc[2]);
  }
else
  {
  for (i=0 ; i<3 ; i++)
    fprintf(fp, " %f", fabs(max[i] - min[i]));
  fprintf(fp, "\n");
  }

fclose(fp);

return(0);
}
Beispiel #13
0
// not really an animate function as such...
void gui_animate_phonon_vectors(struct model_pak *model)
{
gdouble *v, x1[3], x2[3], colour[3];
gpointer spatial, ptr;
GSList *list, *xlist, *ylist, *zlist;
struct core_pak *core, *prim;

if (!model)
  return;

/* create & init the spatial object */
spatial_destroy_by_label("phonons", model);
spatial = spatial_new("phonons", SPATIAL_VECTOR, 2, TRUE, model);

/* get eigenvectors from all atoms */
for (list=model->cores ; list; list=g_slist_next(list))
  {
  core = list->data;
  ARR3SET(x1, core->x);

/* get eigenvector list */
  if (core->primary)
    {
    xlist = core->vibx_list; 
    ylist = core->viby_list; 
    zlist = core->vibz_list; 
    }
  else
    {
    prim = core->primary_core;
    xlist = prim->vibx_list; 
    ylist = prim->viby_list; 
    zlist = prim->vibz_list; 
    }

  if (!xlist || !ylist || !zlist)
    {
    printf("Missing phonon eigenvectors.\n");
    return;
    }

/* vibrational eigenvector */
/* NB: current_phonon starts from 1 */
  ptr = g_slist_nth_data(xlist, model->current_phonon-1);
  if (ptr)
    x2[0] = *((gdouble *) ptr);

  ptr = g_slist_nth_data(ylist, model->current_phonon-1);
  if (ptr)
    x2[1] = *((gdouble *) ptr);

  v = g_slist_nth_data(zlist, model->current_phonon-1);
  if (ptr)
    x2[2] = *v;

/* pulse offset scaling */
  VEC3MUL(x2, sysenv.render.phonon_scaling);
  vecmat(model->ilatmat, x2);

/* TODO - unify with siesta */
/*
  i = model->siesta.sorted_eig_values[model->siesta.current_animation];
  x2[0] = mesch_me_get(model->siesta.eigen_xyz_atom_mat, 3*atom, i);
  x2[1] = mesch_me_get(model->siesta.eigen_xyz_atom_mat, 3*atom+1, i);
  x2[2] = mesch_me_get(model->siesta.eigen_xyz_atom_mat, 3*atom+2, i);
  atom++;
*/

/* compute coords */
  ARR3ADD(x2, x1);

/* add to spatial */
  spatial_vertex_add(x2, colour, spatial);
  spatial_vertex_add(x1, colour, spatial);
  }

coords_compute(model);

gui_refresh(GUI_CANVAS);
}
Beispiel #14
0
gint gui_phonon_loop(void)
{
gint current_phonon;
gdouble f;
gpointer ptr;
GSList *list, *xlist, *ylist, *zlist;
struct core_pak *core, *prim;
struct model_pak *model;

model = tree_model_get();
if (!model)
  return(FALSE);
if (!model->animating)
  {
  gui_phonon_cleanup(model);
  return(FALSE);
  }

//current_phonon = displayed_phonon;
current_phonon = model->current_phonon;

/* NB: list numbering starts from 0 */
ptr = g_slist_nth_data(model->phonons, current_phonon-1);
if (!ptr)
  {
#if DEBUG_PHONON_LOOP
printf("Bad phonon %d/%d\n",  current_phonon, g_slist_length(model->phonons));
#endif
  gui_phonon_cleanup(model);
  return(FALSE);
  }
if (!model->pulse_direction)
  {
  gui_phonon_cleanup(model);
  return(FALSE);
  }

/* setup scaling for this step */
model->pulse_count += model->pulse_direction;
if (model->pulse_count <= -sysenv.render.phonon_resolution)
  {
  model->pulse_count = -sysenv.render.phonon_resolution;
  model->pulse_direction = 1;
  }
if (model->pulse_count >= sysenv.render.phonon_resolution)
  {
  model->pulse_count = sysenv.render.phonon_resolution;
  model->pulse_direction = -1;
  }

f = sysenv.render.phonon_scaling;
f *= (gdouble) model->pulse_count;
f /= sysenv.render.phonon_resolution;

/* get eigenvectors from all atoms */
for (list=model->cores ; list; list=g_slist_next(list))
  {
  core = list->data;

/* get eigenvector list */
  if (core->primary)
    {
    xlist = core->vibx_list; 
    ylist = core->viby_list; 
    zlist = core->vibz_list; 
    }
  else
    {
    prim = core->primary_core;
    xlist = prim->vibx_list; 
    ylist = prim->viby_list; 
    zlist = prim->vibz_list; 
    }
  g_assert(xlist != NULL);
  g_assert(ylist != NULL);
  g_assert(zlist != NULL);

/* vibrational eigenvector */
  ptr = g_slist_nth_data(xlist, current_phonon-1);
  if (!ptr)
    {
    gui_phonon_cleanup(model);
    return(FALSE);
    }
  core->offset[0] = *((gdouble *) ptr);

  ptr = g_slist_nth_data(ylist, current_phonon-1);
  if (!ptr)
    {
    gui_phonon_cleanup(model);
    return(FALSE);
    }
  core->offset[1] = *((gdouble *) ptr);

  ptr = g_slist_nth_data(zlist, current_phonon-1);
  if (!ptr)
    {
    gui_phonon_cleanup(model);
    return(FALSE);
    }
  core->offset[2] = *((gdouble *) ptr);

/* pulse offset scaling */
  VEC3MUL(core->offset, f);
  vecmat(model->ilatmat, core->offset);

/* TODO - shell also? */
  }

/* recalc coords and adjust bond orientations */
coords_compute(model);
connect_midpoints(model);
redraw_canvas(SINGLE);

return(TRUE);
}
Beispiel #15
0
gint siesta_phonon_timer(gpointer dialog)
{
    static gint count=0;
    gint atom, mode;
    gchar *text, *name;
    gdouble f, x1[3];
    gpointer spin;
    GSList *list;
    struct core_pak *core;
    struct model_pak *model;

    /* checks */
    if (!dialog_valid(dialog))
        return(FALSE);

    model = dialog_model(dialog);
    g_assert(model != NULL);

    /* stop animation? */
    if (!model->pulse_direction)
    {
        siesta_phonon_cleanup(model);
        coords_compute(model);
        redraw_canvas(SINGLE);
        return(FALSE);
    }

    /* setup animation resolution */
    spin = dialog_child_get(dialog, "phonon_resolution");
    model->pulse_max = SPIN_FVAL(spin);

    /* setup scaling for this step */
    model->pulse_count += model->pulse_direction;
    if (model->pulse_count <= -model->pulse_max)
    {
        model->pulse_count = -model->pulse_max;
        model->pulse_direction = 1;
    }
    if (model->pulse_count >= model->pulse_max)
    {
        model->pulse_count = model->pulse_max;
        model->pulse_direction = -1;
    }

    spin = dialog_child_get(dialog, "phonon_scaling");
    f = SPIN_FVAL(spin);
    f *= (gdouble) model->pulse_count;
    f /= model->pulse_max;

    atom = 0;

    mode = model->siesta.sorted_eig_values[model->siesta.current_animation];

    /* get eigenvectors from all atoms */
    for (list=model->cores ; list; list=g_slist_next(list))
    {
        core = list->data;
        ARR3SET(x1, core->x);

//get x,y,z for given freq.
        core->offset[0] = mesch_me_get(model->siesta.eigen_xyz_atom_mat, 3*atom, mode);
        core->offset[1] = mesch_me_get(model->siesta.eigen_xyz_atom_mat, 3*atom+1, mode);
        core->offset[2] = mesch_me_get(model->siesta.eigen_xyz_atom_mat, 3*atom+2, mode);
        atom++;

        /* pulse offset scaling */
        VEC3MUL(core->offset, f);
        vecmat(model->ilatmat, core->offset);
    }

    /* recalc coords */
    coords_compute(model);

    /* CURRENT - output to povray for movie rendering */
    if (model->phonon_movie)
    {
        if (!model->pulse_count && model->pulse_direction==1)
        {
            model->phonon_movie = FALSE;
            count=0;

            text = g_strdup_printf("%s -delay 20 %s_*.tga %s.%s",
                                   sysenv.convert_path, model->phonon_movie_name,
                                   model->phonon_movie_name, model->phonon_movie_type);

            system(text);
            g_free(text);

            return(FALSE);
        }
        else
        {
            text = g_strdup_printf("%s_%06d.pov", model->phonon_movie_name, count++);
            name = g_build_filename(sysenv.cwd, text, NULL);
            write_povray(name, model);

            povray_exec(sysenv.cwd, name);

            g_free(text);
            g_free(name);
        }

    }
    else
        redraw_canvas(SINGLE);

    return(TRUE);
}