Пример #1
0
gint read_about(gchar *filename, struct model_pak *model)
{
gint i, flag, frame, num_tokens, tot_tokens;
gint natom=0, ntype=0;
GString *title;
gchar **buff, **curr_token, *ptr, *tmp, line[LINELEN];
struct core_pak *core;
GSList *clist;
FILE *fp;

fp = fopen(filename, "rt");
if (!fp)
  return(1);
flag=frame=0;
while (!fgetline(fp, line))
  {
/* space group info */
  if (g_ascii_strncasecmp(" Symmetries :", line, 13) == 0)
    {
    ptr = g_strrstr(line, "(#");
    model->sginfo.spacenum = (gint) str_to_float(ptr+2);
    }

/* default cell dimensions */
/* NB: gdis wants transposed ABINIT matrix */
    if (g_ascii_strncasecmp(" Real(R)+Recip(G)", line, 17) == 0)
      {
      for (i=0; i<3; i++)
        {
        if (fgetline(fp, line))
          {
          gui_text_show(ERROR, "unexpected end of file reading cell dimensions\n");
          fclose(fp);
          return(2);
          }
        buff = tokenize(line, &num_tokens);
        model->latmat[0+i] = str_to_float(*(buff+1))*AU2ANG;
        model->latmat[3+i] = str_to_float(*(buff+2))*AU2ANG;
        model->latmat[6+i] = str_to_float(*(buff+3))*AU2ANG;
        g_strfreev(buff);
        }
      model->construct_pbc = TRUE;
      model->periodic = 3;
      /* last part of data in output file before minimisation */
      break;
      }

/* optimisation type */  
    if (g_ascii_strncasecmp("   optcell", line, 10) == 0)
      {
      buff = tokenize(line, &num_tokens);
      optcell = (gint) str_to_float(*(buff+1));
      g_strfreev(buff);
      }
/* coordinates */
    if (g_ascii_strncasecmp("     natom", line, 10) == 0)
      {
      buff = tokenize(line, &num_tokens);
      natom = (gint) str_to_float(*(buff+1));
      g_strfreev(buff);
      }
/* NEW - cope with format change and avoid false positives */
//    if (g_ascii_strncasecmp("     ntype", line, 10) == 0)
    if (g_strrstr(line, "    ntyp"))
      {
      buff = tokenize(line, &num_tokens);
      ntype = (gint) str_to_float(*(buff+1));
      g_strfreev(buff);
      }
/* NEW - cope with format change and avoid false positives */
//    if (g_ascii_strncasecmp("      type", line, 10) == 0)
    if (g_strrstr(line, "    typ"))
      {
      tot_tokens = 0;
      buff = tokenize(line, &num_tokens);
      curr_token = buff + 1;
      while (tot_tokens < natom)
        {
        if (*curr_token == NULL)
          {
          g_strfreev(buff);
          buff = get_tokenized_line(fp, &num_tokens);
          curr_token = buff;
          }

/* NB: number here is the internal reference to pseudopotential number */
        core = core_new(*curr_token, NULL, model);
        model->cores = g_slist_prepend(model->cores, core);

        tot_tokens++;
        curr_token++;
        }
      model->cores = g_slist_reverse(model->cores);
      g_strfreev(buff);
      flag++;
      }

    if (g_ascii_strncasecmp("    xangst", line, 10) == 0)
      {
      clist = model->cores;
      if (clist == NULL)
        {
        gui_text_show(ERROR, "no atoms found\n");
        fclose(fp);
        return(2);
        }
      buff = tokenize(line+10, &num_tokens);
      for (i=0; i<natom; i++)
        {
        core = clist->data;
        core->x[0] = str_to_float(*(buff+0));
        core->x[1] = str_to_float(*(buff+1));
        core->x[2] = str_to_float(*(buff+2));
        g_strfreev(buff);
        buff = get_tokenized_line(fp, &num_tokens);
        clist = g_slist_next(clist);
        }
      }

/* process the list of atom nuc charges to get atomic numbers */
    if (g_ascii_strncasecmp("     znucl", line, 10) == 0)
      {
      buff = tokenize(line, &num_tokens);
      for (clist=model->cores ; clist ; clist=g_slist_next(clist))
        {
        core = clist->data;

        if (core->atom_code > 0 && core->atom_code < num_tokens)
          {
/* assign the atomic number */
          core->atom_code = str_to_float(*(buff+core->atom_code));
/* wipe the label clean so the element symbol is used */
          g_free(core->atom_label);
          core->atom_label = NULL;
/* refresh atom's element data */
          elem_init(core, model);
          }
        }
      }

  }

/* Additional info */
while (!fgetline(fp, line))
  {
  /* energy */
/* NEW - cope with format change */
  if (g_strrstr(line, "Etotal="))
    {
    buff = g_strsplit(line, "=", 2);
    if (buff)
      {
      model->abinit.energy = str_to_float(*(buff+1));
/* display energy in properties panel */
      tmp = g_strdup_printf("%f Hartrees", model->abinit.energy);
      property_add_ranked(1, "Total energy", tmp, model);
      g_free(tmp);
      }
    g_strfreev(buff);
    }
 
  /* gradient */
  else if ((g_ascii_strncasecmp(line, " frms,max,avg=", 14) == 0) && g_strrstr(line, "h/b"))
    {
//    printf("reading gradient\n");
    buff = tokenize(line, &num_tokens);
    if (num_tokens > 2)
      {
      model->abinit.max_grad = str_to_float(*(buff+2));
      model->abinit.rms_grad = str_to_float(*(buff+1));

      property_add_ranked(1, "Gradient", *(buff+2), model);

      }
    g_strfreev(buff);
//    printf("gradient is %lf\n", model->abinit.max_grad);
    }

  /* coordinates */
  else if ((g_ascii_strncasecmp(line, " Cartesian coordinates (bohr)", 29) == 0 && optcell == 0)
       || (g_ascii_strncasecmp(line, " Unit cell characteristics :", 28) == 0 && optcell > 0))
    {
/* go through all frames to count them */
    read_about_block(fp, model);

    animate_frame_store(model);

    frame++;
    }
  }

fclose(fp);

/* done */
if (flag)
  {
  g_free(model->filename);
  model->filename = g_strdup(filename);

  g_free(model->basename);
  model->basename = parse_strip(filename);
  model->num_frames = model->cur_frame = frame;
  model->cur_frame--;

  title = g_string_new("");
  g_string_append_printf(title, "E");
  g_string_append_printf(title, " = %.4f Ha, ", model->abinit.energy);
  g_string_append_printf(title, "max grad = %.5f", model->abinit.max_grad);
  model->title = g_strdup(title->str);
  g_string_free(title, TRUE);

  model_prep(model);
  }
else
  return(2);

return(0);
}
Пример #2
0
gint read_diffax(gchar *filename, struct model_pak *model)
{
gint num_tokens, num_layer, tot_layer;
gdouble offset;
gchar **buff;
GSList *list1, *list2;
struct core_pak *core;
struct layer_pak *layer;
FILE *fp;

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

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

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

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

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

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

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

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

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

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

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

  g_strfreev(buff);
  }

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

model->pbc[2] *= tot_layer;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

fclose(fp);
return(0);
}
Пример #4
0
/* TODO - relocate */
gint siesta_phonon_calc(struct model_pak *model)
{
    gint num_tokens, num_atoms, num_lines, i, j, k, l;
    gchar ** buff;
    gchar * modelFCname, *modelFCnameCSV;
    gdouble wi, wj, value;
    gpointer bigmat, correction_mat, mini_correction_zerooooo_mat;
    GSList *list_i, *list_j;
    struct core_pak *core_i;
    struct core_pak *core_j;
    FILE *fp, *matout=NULL;

    g_assert(model != NULL);

    /* check atom labels (since we must be able to do a valid weight lookup) */
    for (list_i=model->cores ; list_i ; list_i=g_slist_next(list_i))
    {
        core_i = list_i->data;
        if (core_i->atom_code == 0)
        {
            gchar *text;

            text = g_strdup_printf("Unknown atom label: [%s]\n", core_i->atom_label);
            gui_text_show(ERROR, text);
            g_free(text);

            return(1);
        }
    }

    num_atoms = model->num_atoms;

//lines = 3 *    N * N     * 2;
//       xyz, each atom, back/forward
//
    num_lines = 3*2*num_atoms*num_atoms;

    modelFCname = g_strdup_printf("%s/%s.FC", sysenv.cwd, model->basename);
    modelFCnameCSV = g_strdup_printf("%s.csv", modelFCname);

    fp = fopen(modelFCname, "rt");

    if (siestafileWRITE)
    {
        matout = fopen(modelFCnameCSV, "w");
        if (!matout)
        {
            gui_text_show(ERROR, "bugger - no save files\n");
            return(2);
        }
    }

    if (!fp)
    {
        gchar * text;
        text = g_strdup_printf("*ERROR* - modelFCname file not opened\n");
        gui_text_show(ERROR, text);
        gui_text_show(ERROR, modelFCname);
        gui_text_show(ERROR, "\n");
        g_free(text);
        return(3);
    }

//no need for names anymore
    g_free(modelFCname);

//initalise bigmat
    bigmat = mesch_mat_new(3*num_atoms, 3*num_atoms);

//first line is crap.
    buff = get_tokenized_line(fp, &num_tokens);

//FILE reading into bigmat
    for (i = 0; i<num_lines; i++)
    {
        g_strfreev(buff);
        buff = get_tokenized_line(fp, &num_tokens);
        if (!buff)
        {
//error not enough lines in file...
//matrix_2d_free(bigmat);
        }

        if (num_tokens > 2)
        {
            if ( (i/num_atoms)%2 == 0)
            {
//first pass at row?

                mesch_me_set(bigmat, i/(2*num_atoms), (3*i)%(3*num_atoms), str_to_float(*buff));
                mesch_me_set(bigmat, i/(2*num_atoms), ((3*i)+1)%(3*num_atoms), str_to_float(*(buff+1)));
                mesch_me_set(bigmat, i/(2*num_atoms), ((3*i)+2)%(3*num_atoms), str_to_float(*(buff+2)));

            }
            else
            {
//second pass - do the average

                value = 0.5*(mesch_me_get(bigmat, i/(2*num_atoms), (3*i)%(3*num_atoms)) + str_to_float(*buff));
                mesch_me_set(bigmat, i/(2*num_atoms), (3*i)%(3*num_atoms), value);

                value = 0.5*(mesch_me_get(bigmat, i/(2*num_atoms), ((3*i)+1)%(3*num_atoms)) + str_to_float(*(buff+1)));
                mesch_me_set(bigmat, i/(2*num_atoms), ((3*i)+1)%(3*num_atoms), value);

                value = 0.5*(mesch_me_get(bigmat, i/(2*num_atoms), ((3*i)+2)%(3*num_atoms)) + str_to_float(*(buff+2)));
                mesch_me_set(bigmat, i/(2*num_atoms), ((3*i)+2)%(3*num_atoms), value);

            }
        }
        else
        {
//what happened - why is there not 3 things on the line?
//matrix_2d_free(bigmat);
        }
//next line?
    }

//Symmetricalise? -> to make symmetric
    for (i=0; i<(3*num_atoms); i++)
    {
        for (j=0; j<(3*num_atoms); j++)
        {
            value = mesch_me_get(bigmat, i, j) + mesch_me_get(bigmat, j, i);
            value *= 0.5;
            mesch_me_set(bigmat, i, j, value);
            mesch_me_set(bigmat, j, i, value);
        }
    }

    correction_mat = mesch_mat_new(3*num_atoms,3);
    mini_correction_zerooooo_mat = mesch_mat_new(3,3);

    mesch_m_zero(correction_mat);
    mesch_m_zero(mini_correction_zerooooo_mat);


//build the correction_matrix

    for (i=0; i<mesch_rows_get(bigmat); i++)
    {
        for (j=0; j<mesch_cols_get(bigmat)/3; j++)
        {
//[3n][3] -> [i][0], [i][1], [i][2]

            value = mesch_me_get(bigmat, i, 3*j);
            mesch_me_add(correction_mat, i, 0, value);

            value = mesch_me_get(bigmat, i, (3*j)+1);
            mesch_me_add(correction_mat, i, 1, value);

            value = mesch_me_get(bigmat, i, (3*j)+2);
            mesch_me_add(correction_mat, i, 2, value);
        }

//average each cell per row in the correction matrix
        value = 1.0 / (gdouble) num_atoms;

        mesch_me_mul(correction_mat, i, 0, value);
        mesch_me_mul(correction_mat, i, 1, value);
        mesch_me_mul(correction_mat, i, 2, value);
    }


//built mini matrix - [3][3]
    for (i=0; i<mesch_rows_get(correction_mat); i++)
    {
        for (j=0; j<mesch_cols_get(correction_mat); j++)
        {
            value = mesch_me_get(correction_mat, i, j);
            mesch_me_add(mini_correction_zerooooo_mat, i%3, j, value);
        }
    }

//average the cells in mini_correction_zerooooo_mat

    value = 1.0 / (gdouble) num_atoms;

    for (i=0; i<mesch_rows_get(mini_correction_zerooooo_mat); i++)
    {
        for (j=0; j<mesch_cols_get(mini_correction_zerooooo_mat); j++)
        {
            mesch_me_mul(mini_correction_zerooooo_mat, i, j, value);
        }
    }

//zero point correction
//    crappy crappy fortran loop that i dont understand
//       do i=1,natoms
//         do j=1,natoms
//           do ii=1,3
//             do ij=1,3
//               correct = (zeroo(ii,ij)+zeroo(ij,ii))/2.0d0 -
//                         (zero(ii,ij,j)+zero(ij,ii,i))
//               do lx=-lxmax,lxmax
//               do ly=-lymax,lymax
//               do lz=-lzmax,lzmax
//                 phi(ii,i,ij,j,lx,ly,lz) = phi(ii,i,ij,j,lx,ly,lz) +
//                                           correct
//               enddo
//               enddo
//               enddo
//             enddo
//           enddo
//         enddo
//       enddo

    gdouble correction;
    for (i=0; i<num_atoms; i++)
    {
        for (j=0; j<num_atoms; j++)
        {
            for (k=0; k<3; k++) //(ii)
            {
                for (l=0; l<3; l++) //(ij)
                {
// THIS WORKS - I HAVE TESTED IT - MANY TIMES......
                    correction = mesch_me_get(mini_correction_zerooooo_mat, k, l);
                    correction += mesch_me_get(mini_correction_zerooooo_mat, l, k);
                    correction *= 0.5;
                    correction -= mesch_me_get(correction_mat, 3*i+k, l);
                    correction -= mesch_me_get(correction_mat, 3*j+l, k);

                    mesch_me_add(bigmat, 3*i+k, 3*j+l, correction);
                }
            }
        }
    }

    i=j=0;

    for (list_i=model->cores ; list_i ; list_i=g_slist_next(list_i))
    {
        core_i = list_i->data;
        if (core_i->status & DELETED)
        {
            i++;
            continue;
        }

        wi = elements[core_i->atom_code].weight;
        g_assert(wi > G_MINDOUBLE);

        for (list_j=model->cores ; list_j ; list_j=g_slist_next(list_j))
        {
            core_j = list_j->data;
            if (core_j->status & DELETED)
            {
                j++;
                continue;
            }
//multi i rows.... 3 of them....

            wj = elements[core_j->atom_code].weight;
            g_assert(wj > G_MINDOUBLE);
            value  = 1.0 / sqrt(wi * wj);

            for (k=0; k<3; k++)
            {
                mesch_me_mul(bigmat, (3*i)+k, 3*j, value);
                mesch_me_mul(bigmat, (3*i)+k, (3*j)+1, value);
                mesch_me_mul(bigmat, (3*i)+k, (3*j)+2, value);
            }

            j++;
        }
        i++;
        j=0;
    }

    model->siesta.eigen_xyz_atom_mat = mesch_mat_new(3*num_atoms, 3*num_atoms);
    model->siesta.eigen_values = mesch_vec_new(3*num_atoms);

//external library call.

    mesch_sev_compute(bigmat, model->siesta.eigen_xyz_atom_mat, model->siesta.eigen_values);

// stupid sort routine -> this is going to need a rewrite - its a bubble sort - O(n^2).
    model->siesta.sorted_eig_values = g_malloc(sizeof(int[mesch_dim_get(model->siesta.eigen_values)]));

    for (i=0; i<mesch_dim_get(model->siesta.eigen_values); i++)
    {
        model->siesta.sorted_eig_values[i] = i;
    }

    gint temp_int;
    gdouble freq_i, freq_ii;

    gint sizeofeig = mesch_dim_get(model->siesta.eigen_values);

    for (j=sizeofeig-1; j>1; j--)
    {
        for (i=0; i < j; i++)
        {
            freq_i = make_eigvec_freq(mesch_ve_get(model->siesta.eigen_values, model->siesta.sorted_eig_values[i]));

            freq_ii = make_eigvec_freq(mesch_ve_get(model->siesta.eigen_values, model->siesta.sorted_eig_values[i+1]));


            if (freq_i > freq_ii )
            {
                temp_int = model->siesta.sorted_eig_values[i];
                model->siesta.sorted_eig_values[i] = model->siesta.sorted_eig_values[i+1];
                model->siesta.sorted_eig_values[i+1] = temp_int;
            }
        }
    }

//PRINT METHOD FOR UWA VISIT
    if (siestafileWRITE && matout)
    {
        fprintf(matout, "eig vectors 3N*3N\n-------------\n");
        for (j=0; j<(3*num_atoms); j++)
        {
            for (i=0; i<(3*num_atoms); i++)
            {
                fprintf(matout, "%f, ", mesch_me_get(bigmat, j, i));
            }
            fprintf(matout, "\n");
        }

        fprintf(matout, "\n\neig_vals\n-------------\n");
        for (i=0; i<mesch_dim_get(model->siesta.eigen_values); i++)
        {
            fprintf(matout, "%f, ", mesch_ve_get(model->siesta.eigen_values, i));
        }

        fprintf(matout, "\n\nfreqs\n-------------\n");
        for (i=0; i<mesch_dim_get(model->siesta.eigen_values); i++)
        {
            fprintf(matout, "%f, ", make_eigvec_freq(mesch_ve_get(model->siesta.eigen_values, i)));
        }

        fclose(matout);
    }

    fclose(fp);

    mesch_m_free(bigmat);
    mesch_m_free(correction_mat);
    mesch_m_free(mini_correction_zerooooo_mat);

    model->siesta.current_animation = 0;

//Lookup using index array.
    model->siesta.current_frequency = make_eigvec_freq(mesch_ve_get(model->siesta.eigen_values, model->siesta.sorted_eig_values[0]));
    model->siesta.freq_disp_str = g_strdup_printf("%.2f", model->siesta.current_frequency);
    model->siesta.num_animations = mesch_dim_get(model->siesta.eigen_values);
    model->siesta.vibration_calc_complete = TRUE;

    return(0);
}