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); }
void gui_phonon_cleanup(struct model_pak *model) { GSList *list; struct core_pak *core; g_assert(model != NULL); /* reset offsets */ for (list=model->cores ; list; list=g_slist_next(list)) { core = list->data; VEC3SET(core->offset, 0.0, 0.0, 0.0); } model->animating = FALSE; /* recalc coords and adjust bond orientations */ coords_compute(model); connect_midpoints(model); redraw_canvas(SINGLE); }
void cb_make_asymmetric(GtkWidget *w, gpointer dummy) { GSList *list; struct core_pak *core; struct shel_pak *shel; struct model_pak *model; model = sysenv.active_model; g_assert(model != NULL); if (model->periodic) { for (list=model->cores ; list ; list=g_slist_next(list)) { core = list->data; if (core->primary) continue; if (model->asym_on) core->status |= HIDDEN; else core->status &= ~HIDDEN; } for (list=model->shels ; list ; list=g_slist_next(list)) { shel = list->data; if (shel->primary) continue; if (model->asym_on) shel->status |= HIDDEN; else shel->status &= ~HIDDEN; } } /* update */ coords_compute(model); redraw_canvas(SINGLE); }
// 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); }
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); }
gint read_frame(FILE *fp, gint n, struct model_pak *model) { gint status; gdouble rmax, v1[3], v2[3]; gpointer camera=NULL; GString *err_text; g_assert(model != NULL); rmax = model->rmax; /* conventional or transformation style animation */ if (model->transform_list) { /* NEW - process transformation list as an animation */ status = read_transform(n, model); } else { g_assert(fp != NULL); ARR3SET(v1, model->centroid); ARR3SET(v2, model->offset); status = read_raw_frame(fp, n, model); if (status) { err_text = g_string_new(""); g_string_printf(err_text, "Error reading frame: %d\n", n); gui_text_show(ERROR, err_text->str); g_string_free(err_text, TRUE); return(1); } /* setup (have to save camera) */ camera = camera_dup(model->camera); model_prep(model); model->camera = camera; g_free(model->camera_default); model->camera_default = camera; ARR3SET(model->centroid, v1); ARR3SET(model->offset, v2); } /* apply desired constraint */ if (model->periodic && !model->anim_fix) { switch (model->anim_confine) { case PBC_CONFINE_ATOMS: coords_confine_cores(model->cores, model); case PBC_CONFINE_MOLS: coords_compute(model); connect_bonds(model); connect_molecules(model); break; } } if (model->anim_noscale) model->rmax = rmax; return(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); }