Пример #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
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);
}
Пример #3
0
void quat_rotate(gdouble *vec, gdouble *quat)
{
gdouble rot[9];
 
quat_matrix(rot, quat);
vecmat(rot, vec);
}
Пример #4
0
/* NB - this is siesta specific */
void zmat_coord_print(FILE *fp, GSList *species_list, gpointer data)
{
gint i, j;
gdouble x[3];
GSList *list, *clist, *slist;
struct model_pak *model=data;
struct species_pak *species_data;
struct core_pak *core;
struct zmat_pak *zmat;

g_assert(data != NULL);

clist = g_slist_copy(model->cores);

zmat = model->zmatrix;

g_assert(zmat != NULL);

for (list=zmat->zcores ; list ; list=g_slist_next(list))
  clist = g_slist_remove(clist, list->data);

j = 1 + g_slist_length(zmat->zcores);

if (clist)
  {
  if (model->fractional)
    fprintf(fp, "fractional\n");
  else
    fprintf(fp, "cartesian\n");

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

    ARR3SET(x, core->x);

/* NB: want fractional if 3D periodic, otherwise cartesian */
    if (!model->fractional)
      vecmat(model->latmat, x);

/* find corresponding number of this element in the species block */
    i=1;
    for (slist=species_list ; slist ; slist=g_slist_next(slist))
      {
      species_data = slist->data;

      if (g_ascii_strcasecmp(core->atom_label, species_data->label) == 0)
        break;

      i++;
      }
    fprintf(fp," %d  %14.9f  %14.9f  %14.9f    1 1 1   %d\n", i, x[0], x[1], x[2], j++);
    }
  }

g_slist_free(clist);

}
Пример #5
0
gint write_dmol(gchar *filename, struct model_pak *model)
{
gint i;
gdouble x[3];
GSList *list;
struct core_pak *core;
FILE *fp;

/* checks */
g_return_val_if_fail(model != NULL, 1);
g_return_val_if_fail(filename != NULL, 2);

/* open the file */
fp = fopen(filename,"wt");
if (!fp)
  return(3);

if (model->periodic == 3)
  {
  fprintf(fp, "$cell vectors\n");

/* NB: DMOL matrices are transposed wrt gdis */
  for (i=0 ; i<3 ; i++)
    {
    fprintf(fp, "          %20.14f%20.14f%20.14f\n",
                          model->latmat[i]/AU2ANG,
                          model->latmat[i+3]/AU2ANG,
                          model->latmat[i+6]/AU2ANG);
    }
  }

fprintf(fp, "$coordinates\n");
for (list=model->cores ; list ; list=g_slist_next(list))
  {
  core = list->data;
  if (core->status & DELETED)
    continue;

/* everything is cartesian after latmat mult */
  ARR3SET(x, core->x);
  vecmat(model->latmat, x);
  fprintf(fp,"%-10s%20.14f%20.14f%20.14f%5d\n",
              elements[core->atom_code].symbol,
              x[0]/AU2ANG, x[1]/AU2ANG, x[2]/AU2ANG, core->atom_code);
  }
fprintf(fp, "$end\n");

fclose(fp);
return(0);
}
Пример #6
0
void trenchQFR(double *r,int *nn,
	 double *z,int *nnz,double *EPSL,double *y,int *fault)
{
	MATRIX b;
	VECTOR s,v;
	double logDet,_s,EPS;
	int i,n = *nn,nz = *nnz,_fault;
 
	if (n != nz)
	{
		for (i = 0; i < 2; i++)
			y[i] = 0.0;
		fault[0] = 3; 
		return;	
	}

	EPS = *EPSL;
	b = Matrix(n,n);
	v = Vector(n);

	_fault = trenchInv(r,n,b,v,EPS);

	if (_fault != 0)
	{
		for (i = 0; i < 2; i++)
			y[i] = 0.0;
		fault[0] = _fault; 
		free_matrix(b);
		free_vector(v);
		return;
	}
	else
		fault[0] = 0;

	fromWedgeStorage(n,b);
		
	logDet = trenchDet(r,n,v);

	s = Vector (n);

	vecmat(n,z,b,s);
	_s = dot(n,s,z);

	y[0] = _s;
	y[1] = logDet;
	
	free_matrix(b);
	free_vector(v);
	free_vector(s);
}
Пример #7
0
int main(int argc, char *argv[]) {
  int rank, nprocs, i, j;
  MPI_Status status;
  
  N = atoi(argv[1]);
  L = atoi(argv[2]);
  M = atoi(argv[3]);
  MPI_Init(&argc, &argv);
  MPI_Comm_rank(comm, &rank);
  MPI_Comm_size(comm, &nprocs);
  if (rank == 0) {
    double a[N][L], b[L][M], c[N][M], tmp[M];
    int count;
    
    FILE *fp =fopen("data", "r");
    for (i = 0; i < N; i++)
      for (j = 0; j < L; j++)
	fscanf(fp,"%lf", &a[i][j]);
    for (i = 0; i < L; i++)
      for (j = 0; j < M; j++)
	fscanf(fp,"%lf",&b[i][j]);
    MPI_Bcast(b, L*M, MPI_DOUBLE, 0, comm);
    for (count = 0; count < nprocs-1 && count < N; count++)
      MPI_Send(&a[count][0], L, MPI_DOUBLE, count+1, count+1, comm);
    for (i = 0; i < N; i++) {
      MPI_Recv(tmp, M, MPI_DOUBLE, MPI_ANY_SOURCE, MPI_ANY_TAG, comm, &status);
      for (j = 0; j < M; j++) c[status.MPI_TAG-1][j] = tmp[j];
      if (count < N) {
	MPI_Send(&a[count][0], L, MPI_DOUBLE, status.MPI_SOURCE, count+1, comm);
	count++;
      }
    }
    for (i = 1; i < nprocs; i++) MPI_Send(NULL, 0, MPI_INT, i, 0, comm);
    printMatrix(N, M, &c[0][0]);
    fclose(fp);
  } else {
    double b[L][M], in[L], out[M];

    MPI_Bcast(b, L*M, MPI_DOUBLE, 0, comm);
    while (1) {
      MPI_Recv(in, L, MPI_DOUBLE, 0, MPI_ANY_TAG, comm, &status);
      if (status.MPI_TAG == 0) break;
      vecmat(in, b, out);
      MPI_Send(out, M, MPI_DOUBLE, 0, status.MPI_TAG, comm);
    }
  }
  MPI_Finalize();
  return 0;
}
Пример #8
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]);

  }
}
Пример #9
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);
}
Пример #10
0
gint write_aims(gchar *filename, struct model_pak *model)
{
gint i;
gdouble x[3];
GSList *list;
struct core_pak *core;
FILE *fp;

/* checks */
g_return_val_if_fail(model != NULL, 1);
g_return_val_if_fail(filename != NULL, 2);

/* open the file */
fp = fopen(filename,"wt");
if (!fp) return(3);

if (model->periodic == 3) {

  /* TODO: check whether lattice vectors in AIMS are transposed with respect GDIS */
  for (i=0 ; i<3 ; i++) {
    fprintf(fp,"lattice_vector %14.8f %14.8f %14.8f \n", 
            model->latmat[0+i], model->latmat[3+i], model->latmat[6+i]);
  }
}

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

  core = list->data;
  if (core->status & DELETED) continue;

  /* everything is cartesian after latmat mult */
  ARR3SET(x, core->x);
  vecmat(model->latmat, x);
  fprintf(fp,"          atom %14.8f %14.8f %14.8f %3s \n",
          x[0], x[1], x[2], elements[core->atom_code].symbol);
}

fclose(fp);
return(0);
}
Пример #11
0
gint nwchem_input_export(gpointer import)
{
gint i, n;
gdouble x[3];
gchar *text;
gpointer config, value;
GList *list, *keys;
GSList *item;
GString *buffer;
struct model_pak *model;
struct nwchem_pak *nwchem;
struct core_pak *core;

model = import_object_nth_get(IMPORT_MODEL, 0, import);
if (!model)
  return(1);

config = import_config_get(NWCHEM, import);
if (!config)
  config = config_new(NWCHEM, NULL);

//nwchem = import_config_data_get(NWCHEM, import);
nwchem = config_data(config);
if (!nwchem)
  {
  printf("Error: couldn't obtain an nwchem config.\n");
  return(2);
  }

buffer = g_string_new(NULL);
g_string_append_printf(buffer, "#--- created by GDIS\n\n");

/* output start */
if (nwchem->start)
  g_string_append_printf(buffer, "%s\n", nwchem->start);

/* output charge */
if (nwchem->charge)
  g_string_append_printf(buffer, "charge %s\n\n", nwchem->charge);

/* output periodicity info */
switch (model->periodic)
  {
  case 3:
    g_string_append_printf(buffer, "system crystal\n");
    g_string_append_printf(buffer, "lat_a %f lat_b %f lat_c %f\n",
                           model->pbc[0], model->pbc[1], model->pbc[2]);
    g_string_append_printf(buffer, "alpha %f beta %f gamma %f\n",
                           R2D*model->pbc[3], R2D*model->pbc[4], R2D*model->pbc[5]);
    g_string_append_printf(buffer, "end\n");
    break;

  case 2:
    g_string_append_printf(buffer, "system surface\n");
    g_string_append_printf(buffer, "lat_a %f lat_b %f\n", model->pbc[0], model->pbc[1]);
    g_string_append_printf(buffer, "gamma %f\n", R2D*model->pbc[5]);
    g_string_append_printf(buffer, "end\n");
    break;

  case 1:
    g_string_append_printf(buffer, "system polymer\n");
    g_string_append_printf(buffer, "lat_a %f\n", model->pbc[0]);
    g_string_append_printf(buffer, "end\n");
    break;
  }

/* output geometry */
g_string_append_printf(buffer, "geometry\n");
n = zmat_entries_get(model->zmatrix);
if (n)
  {
  g_string_append_printf(buffer, "  zmatrix\n");
  text = zmatrix_connect_text(model->zmatrix);
  g_string_append(buffer, text);
  g_free(text);

  g_string_append_printf(buffer, "  constants\n");
  text = zmatrix_constants_text(model->zmatrix);
  g_string_append(buffer, text);
  g_free(text);

  g_string_append_printf(buffer, "  variables\n");
  text = zmatrix_variables_text(model->zmatrix);
  g_string_append(buffer, text);
  g_free(text);

  g_string_append_printf(buffer, "  end\n");
  }
else
  {
  for (item=model->cores ; item ; item=g_slist_next(item))
    {
    core = item->data;
/* cartesian coords */
    ARR3SET(x, core->x);
    vecmat(model->latmat, x); 
/* set fractional part */
    for (i=0 ; i<model->periodic ; i++)
      if (model->fractional)
        x[i] = core->x[i];
/* from NWCHEM manual, coords are always fractional in periodic directions, else cartesian */
    g_string_append_printf(buffer, "%s  %f %f %f\n", core->atom_label, x[0], x[1], x[2]);
    }
  }
g_string_append_printf(buffer, "end\n\n");

/* output basis library */
keys = g_hash_table_get_keys(nwchem->library);
if (g_list_length(keys))
  {
  g_string_append_printf(buffer, "basis\n");
  for (list=keys ; list ; list=g_list_next(list))
    {
    value = g_hash_table_lookup(nwchem->library, list->data);

    g_string_append_printf(buffer, "%s library %s\n", (gchar *) list->data, (gchar *) value);
    }
  g_string_append_printf(buffer, "end\n");
  }

/* unparsed */
// TODO - if it's just blank lines - skip
text = config_unparsed_get(config);
if (text)
  g_string_append_printf(buffer, "\n# --- unparsed start ---\n\n%s\n# --- unparsed stop ---\n\n", text);

/* last item is the task to be performed */
/* CURRENT - some files may not have a task? */
if (nwchem->task_operation)
  {
  g_string_append_printf(buffer, "task");
  if (nwchem->task_theory)
    g_string_append_printf(buffer, " %s", nwchem->task_theory);
  if (nwchem->task_operation)
    g_string_append_printf(buffer, " %s", nwchem->task_operation);
  }

/* all done, write to disk or preview mode? */
if (import_preview_get(import))
  {
/* preview mode only */
  import_preview_buffer_set(buffer->str, import);
  g_string_free(buffer, FALSE);
  }
else
  {
/* flush contents to disk */
  g_file_set_contents(import_fullpath(import), buffer->str, -1, NULL);
  g_string_free(buffer, TRUE);
  }

return(1);
}
Пример #12
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);
}
Пример #13
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);
}
Пример #14
0
gint write_gms(gchar *filename, struct model_pak *model)
{
gdouble x[3];
GSList *list;
struct core_pak *core;
FILE *fp;

/* checks */
g_return_val_if_fail(model != NULL, 1);
g_return_val_if_fail(filename != NULL, 2);

/* open the file */
fp = fopen(filename,"wb");
if (!fp)
  return(3);

/* TODO - enforce lines < 80 chars? */  
/* print control keywords */
fprintf(fp, " $contrl coord=unique");
write_keyword(fp, GMS_EXETYPE_TXT, model->gamess.exe_type, exe_types);
write_keyword(fp, GMS_SCFTYPE_TXT, model->gamess.scf_type, scf_types);
write_keyword(fp, GMS_RUNTYPE_TXT, model->gamess.run_type, run_types);

/* FIXME - put in to try & keep the lines below 80 chars */
fprintf(fp, "\n ");

write_keyword(fp, GMS_UNITS_TXT, model->gamess.units, units);

fprintf(fp, " %s%d", GMS_MAXIT_TXT, (gint) model->gamess.maxit);
if (model->gamess.total_charge != 0.0)
  fprintf(fp, " %s%d", GMS_TOTAL_Q_TXT, (gint) model->gamess.total_charge);
if (model->gamess.multiplicity > 1)
  fprintf(fp, " %s%d", GMS_MULT_TXT, (gint) model->gamess.multiplicity);
if (model->gamess.wide_output)
  fprintf(fp, " %s6", GMS_WIDE_OUTPUT_TXT);

fprintf(fp, " $end\n");

/* NEW - dft calc */
if (model->gamess.dft)
  {
  fprintf(fp, " $dft");
  switch (model->gamess.dft_functional)
    {
    case SVWN:
      fprintf(fp, " dfttyp=SVWN");
      break; 
    case BLYP:
      fprintf(fp, " dfttyp=BLYP");
      break; 
    case B3LYP:
      fprintf(fp, " dfttyp=B3LYP");
      break; 
    }
  fprintf(fp, " $end\n");
  }

/* TODO: electron correlation stuff */

/* print size and memory */
fprintf(fp, " $system %s%d %s%d $end\x0a", GMS_TIMLIM_TXT, (gint) model->gamess.time_limit, GMS_MWORDS_TXT, (gint) model->gamess.mwords);

/* print optimiser data */
if (model->gamess.run_type >= GMS_OPTIMIZE)
 {
  fprintf(fp, " $statpt %s%d ", GMS_NSTEP_TXT, (gint) model->gamess.nstep);
  write_keyword(fp, GMS_METHOD_TXT, model->gamess.opt_type, method_types);
  fprintf(fp, "$end\n");
  }

/* print basis set if one of the standard ones */
if (model->gamess.basis != GMS_USER)
  {
  fprintf(fp, " $basis ");
  write_keyword(fp, GMS_BASIS_TXT, model->gamess.basis, basis_types);
  if (model->gamess.ngauss)
    fprintf(fp, " %s%d", GMS_NGAUSS_TXT, model->gamess.ngauss);
  if (model->gamess.num_p)
    fprintf(fp, " %s%d", GMS_NUM_P_TXT, (gint) model->gamess.num_p);
  if (model->gamess.num_d)
    fprintf(fp, " %s%d", GMS_NUM_D_TXT, (gint) model->gamess.num_d);
  if (model->gamess.num_f)
    fprintf(fp, " %s%d", GMS_NUM_F_TXT, (gint) model->gamess.num_f);
  if (model->gamess.have_heavy_diffuse)
    fprintf(fp, " %s", GMS_DIFFSP_TXT);
  if (model->gamess.have_hydrogen_diffuse)
    fprintf(fp, " %s", GMS_DIFFS_TXT);
  fprintf(fp, " $end\n");
  }
  
/* print data */
fprintf(fp, " $DATA\n");
/* print data header */
fprintf(fp, "%s\n", model->gamess.title);
/* print symmetry */
fprintf(fp, "c1\n");

for (list=model->cores ; list ; list=g_slist_next(list))
  {
  core = list->data;
  if (core->status & DELETED)
    continue;

/* everything is cartesian after latmat mult */
  ARR3SET(x, core->x);
  vecmat(model->latmat, x);
  if (model->gamess.units == GMS_ANGS)
    fprintf(fp,"%-7s  %d  %14.9f  %14.9f  %14.9f\n",
              elements[core->atom_code].symbol, elements[core->atom_code].number, x[0], x[1], x[2]);
  else
    fprintf(fp,"%-7s  %d  %14.9f  %14.9f  %14.9f\n",
              elements[core->atom_code].symbol, elements[core->atom_code].number, x[0]/BOHR_TO_ANGS, x[1]/BOHR_TO_ANGS, x[2]/BOHR_TO_ANGS);
  }
fprintf(fp, " $END\n");

fclose(fp);
return(0);
}
Пример #15
0
gint write_cif(gchar *filename, struct model_pak *data)
{
gint flag=0;
gdouble tmat[9], x[3], depth=1.0;
GSList *list;
FILE *fp;
time_t t1;
struct core_pak *core;

/* init & checks */
g_return_val_if_fail(data != NULL, 1);
fp = fopen(filename, "wt");
g_return_val_if_fail(fp != NULL, 2);
  
/* is it a surface with negative z? */
if (data->periodic == 2)
  {
  if (g_slist_length(data->cores))
    {
    core = g_slist_nth_data(data->cores, 0);
    if (core->x[2] < 0.0)
      flag++;
    }
  }

/* rot to make z positive */
matrix_rotation(&tmat[0], PI, PITCH);

t1 = time(NULL);
fprintf(fp, "data_block_1\n");
fprintf(fp, "_audit_creation_date         '%s'\n", g_strstrip(ctime(&t1)));
fprintf(fp, "_audit_creation_method       'generated by GDIS v%4.2f'\n", VERSION);
fprintf(fp, "\n\n");
if (data->periodic)
  {
  fprintf(fp, "_cell_length_a            %8.4f\n",data->pbc[0]);
  fprintf(fp, "_cell_length_b            %8.4f\n",data->pbc[1]);

if (data->periodic == 2)
  {
/* get depth info */
  depth = (data->surface.region[0]+data->surface.region[1])*data->surface.depth;
/* no depth info - make it large enough to fit everything */
  if (depth < POSITION_TOLERANCE)
    depth = 2.0*data->rmax;
  fprintf(fp, "_cell_length_c            %8.4f\n", depth);
  }
else
  fprintf(fp, "_cell_length_c            %8.4f\n",data->pbc[2]);

  fprintf(fp, "_cell_angle_alpha       %8.2f\n",180.0*data->pbc[3]/PI);
  fprintf(fp, "_cell_angle_beta        %8.2f\n",180.0*data->pbc[4]/PI);
  fprintf(fp, "_cell_angle_gamma       %8.2f\n",180.0*data->pbc[5]/PI);
  fprintf(fp, "\n\n");
  fprintf(fp, "_symmetry_space_group_name_H-M   '%s'\n",data->sginfo.spacename);
  fprintf(fp, "_symmetry_Int_Tables_number       %d\n",data->sginfo.spacenum);
  fprintf(fp, "\n\n");
  }

/* coords - format section */
fprintf(fp, "loop_\n");
fprintf(fp, "_atom_site_label\n");
if (data->periodic)
  {
  fprintf(fp, "_atom_site_fract_x\n");
  fprintf(fp, "_atom_site_fract_y\n");
  fprintf(fp, "_atom_site_fract_z\n");
  }
else
  {
  fprintf(fp, "_atom_site_cartn_x\n");
  fprintf(fp, "_atom_site_cartn_y\n");
  fprintf(fp, "_atom_site_cartn_z\n");
  }

/* coords - data section */
for (list=data->cores ; list ; list=g_slist_next(list))
  {
  core = list->data;

/* only the asymmetric cell if periodic */
  if (data->periodic && !core->primary)
    continue;

/* NB: want fractional if 3D periodic, otherwise cartesian */
  ARR3SET(x, core->x);
/* transformation needed? */
    if (flag)
      vecmat(tmat, x);
/* make the z coordinate "fractional" for a surface */
  if (data->periodic == 2)
    x[2] /= depth;

  fprintf(fp, "%2s %10.6f %10.6f %10.6f\n",
          elements[core->atom_code].symbol, x[0], x[1], x[2]);
  }
fprintf(fp, "\n\n");

fclose(fp);
return(0);
}
Пример #16
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);
}
Пример #17
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);
}
Пример #18
0
gint write_xml(gchar *filename, struct model_pak *model)
{
gdouble vec[3];
GSList *list, *list2;
struct core_pak *core;
struct vec_pak *v;
struct spatial_pak *spatial;
FILE *fp;

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

fprintf(fp, "<system>\n");

/* periodicity */
if (model->periodic)
  {
  switch (model->periodic)
    {
    case 1:
      fprintf(fp, "  <crystal dictRef=\"gulp:polymer\">\n");
      break;

    case 2:
      fprintf(fp, "  <crystal dictRef=\"gulp:surface\">\n");
      break;

    default:
      fprintf(fp, "  <crystal dictRef=\"gulp:fullcell\">\n");
      break;
    }
  fprintf(fp, "    <cell dictRef=\"cml:a\"> %f </cell>\n", model->pbc[0]);
  fprintf(fp, "    <cell dictRef=\"cml:b\"> %f </cell>\n", model->pbc[1]);
  fprintf(fp, "    <cell dictRef=\"cml:c\"> %f </cell>\n", model->pbc[2]);
  fprintf(fp, "    <cell dictRef=\"cml:alpha\"> %f </cell>\n",
                                           R2D*model->pbc[3]);
  fprintf(fp, "    <cell dictRef=\"cml:beta\"> %f </cell>\n",
                                          R2D*model->pbc[4]);
  fprintf(fp, "    <cell dictRef=\"cml:gamma\"> %f </cell>\n",
                                           R2D*model->pbc[5]);
  fprintf(fp, "  </crystal>\n");
  }

/* cores */
for (list=model->cores ; list ; list=g_slist_next(list))
  {
  core = list->data;
  ARR3SET(vec, core->x);
  vecmat(model->latmat, vec);
/*
  fprintf(fp, "  <atom elementType=\"%s\" x3=\"%f\" y3=\"%f\" z3=\"%f\">",
          core->atom_label, vec[0], vec[1], vec[2]);
*/

  fprintf(fp, "  <atom elementType=\"%s\" x3=\"%f\" y3=\"%f\" z3=\"%f\">",
          elements[core->atom_code].symbol, vec[0], vec[1], vec[2]);


  fprintf(fp, "</atom>\n");
/* TODO - shells as particles */
  }

/* spatial data */
for (list=model->spatial ; list ; list=g_slist_next(list))
  {
  spatial = list->data;

  fprintf(fp, "<spatial Method=\"%d\" Periodic=\"%d\">\n",
                      spatial->method, spatial->periodic);

  for (list2=spatial->list ; list2 ; list2=g_slist_next(list2))
    {
    v = list2->data;

    fprintf(fp, "  <vertex red=\"%f\" green=\"%f\" blue=\"%f\"",
                 v->colour[0], v->colour[1], v->colour[2]);
 
    fprintf(fp, " x3=\"%f\" y3=\"%f\" z3=\"%f\"",
                 v->x[0], v->x[1], v->x[2]);

    fprintf(fp, " nx=\"%f\" ny=\"%f\" nz=\"%f\"></vertex>\n",
                 v->n[0], v->n[1], v->n[2]);
    }

  fprintf(fp, "</spatial>\n");
  }

/* camera waypoints */
for (list=model->waypoint_list ; list ; list=g_slist_next(list))
  {
  struct camera_pak *camera = list->data;

  fprintf(fp, "<waypoint mode=\"%d\" perspective=\"%d\" fov=\"%f\" zoom=\"%f\"\n",
              camera->mode, camera->perspective, camera->fov, camera->zoom);
  fprintf(fp, "x0=\"%f\" x1=\"%f\" x2=\"%f\"\n",camera->x[0],camera->x[1],camera->x[2]);
  fprintf(fp, "o0=\"%f\" o1=\"%f\" o2=\"%f\"\n",camera->o[0],camera->o[1],camera->o[2]);
  fprintf(fp, "v0=\"%f\" v1=\"%f\" v2=\"%f\"\n",camera->v[0],camera->v[1],camera->v[2]);
  fprintf(fp, "e0=\"%f\" e1=\"%f\" e2=\"%f\"\n",camera->e[0],camera->e[1],camera->e[2]);
  fprintf(fp, "q0=\"%f\" q1=\"%f\" q2=\"%f\" q3=\"%f\">", 
               camera->q[0], camera->q[1], camera->q[2], camera->q[3]);
  fprintf(fp, "</waypoint>\n"); 
  }

fprintf(fp, "</system>\n");

fclose(fp);
return(0);
}
Пример #19
0
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);
}
Пример #20
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);
}
Пример #21
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);
    }
  }
}
Пример #22
0
void zmat_build(void)
{
gint i, j, k, n, type;
gdouble r, a, d, x[4][3], v[3];
gdouble  zaxis[3] = {0.0, 0.0, 1.0};
gchar *line;
GSList *list, *species;
struct zmat_pak *zmat;
struct core_pak *core[4] = {NULL, NULL, NULL, NULL};
struct model_pak *model;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    default:

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

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

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

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

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

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

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

  n++;
  }

zmat_build_done:

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

free_slist(species);
}
Пример #23
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);
*/
}
Пример #24
0
GSList *get_facet_equiv(struct model_pak *data, gint *f1)
{
gint i, flag, *f2, index[3];
gdouble d1, d2, vec[3];
GSList *flist=NULL, *list=NULL;

g_return_val_if_fail(data != NULL, NULL);
g_return_val_if_fail(f1 != NULL, NULL);

/* NEW */
ARR3SET(vec, f1);
vecmat(data->rlatmat, vec);
d1 = 1.0/VEC3MAG(vec);

#if DEBUG_GET_FACET_EQUIV
printf("search for equiv faces to (%d %d %d) (Dhkl = %f)\n",
        f1[0], f1[1], f1[2], d1);
#endif

/* add the supplied face to the list (needed to eliminate repetitions) */
f2 = g_malloc(3*sizeof(gint));
ARR3SET(f2, f1);
flist = g_slist_prepend(flist, (gpointer) f2);

if (data->sginfo.spacenum)
  {
/* skip 1st (trivial) op */
  for (i=1 ; i<data->sginfo.order ; i++)
    {
/* generate new symmetry related hkl */
    ARR3SET(vec, f1);
    vecmat(*(data->sginfo.matrix+i), vec);
    ARR3SET(index, vec);

/* NEW - weed out symop generated faces with different Dhkl values */
/* FIXME - why does this happen??? */
vecmat(data->rlatmat, vec);
d2 = 1.0/VEC3MAG(vec);

#if DEBUG_GET_FACET_EQUIV
printf("candidate: (%3d %3d %3d) : (Dhkl=%7.4f)", index[0], index[1], index[2], d2);
#endif

if (fabs(d2-d1) > FRACTION_TOLERANCE)
  {
#if DEBUG_GET_FACET_EQUIV
printf("[NO : dhkl mis-match]\n");
#endif
  continue;
  }

/* add new hkl if not found in the list */
    flag = 0;
    list = flist;
    while (list != NULL)
      {
      f2 = (gint *) list->data;
      if (index[0] == f2[0] && index[1] == f2[1] && index[2] == f2[2])
        {
        flag++;
        break;
        }
      list = g_slist_next(list);
      }
    if (!flag)
      {
      f2 = g_malloc(3*sizeof(gint));
      ARR3SET(f2, index);
      flist = g_slist_prepend(flist, f2);

#if DEBUG_GET_FACET_EQUIV
printf("[YES : symop %d]\n", i);
#endif
      }
#if DEBUG_GET_FACET_EQUIV
    else
      {
printf("[NO : already exists]\n");
      }
#endif
    }
  }
else
  printf("No space group information.\n");

flist = g_slist_reverse(flist);
return(flist);
}
Пример #25
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);
}