/*
Copyright (C) 2003 by Sean David Fleming
sean@ivec.org
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
The GNU GPL can also be found at http://www.gnu.org
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <math.h>
#include <sys/stat.h>
#include <sys/types.h>
#include "gdis.h"
#include "coords.h"
#include "model.h"
#include "file.h"
#include "matrix.h"
#include "module.h"
#include "parse.h"
#include "project.h"
#include "spatial.h"
#include "quaternion.h"
#include "task.h"
#include "interface.h"
#include "dialog.h"
#include "shortcuts.h"
/*
#include "meschach/matrix-meschach.h"
*/
#include "mesch.h"
#include "gui_siesta.h"
extern struct sysenv_pak sysenv;
extern struct elem_pak elements[];
static gboolean siestafileWRITE;
/*************************/
/* main SIESTA interface */
/*************************/
void gui_siesta_dialog(void)
{
GtkWidget *window;
gpointer dialog;
struct model_pak *model;
siestafileWRITE = FALSE;
model = sysenv.active_model;
if (!model)
//bugger
return;
/* request a dialog */
dialog = dialog_request(200, "Siesta Setup", NULL, NULL, model);
if (!dialog)
return;
window = dialog_window(dialog);
file_handler_page_generator(dialog, window, model);
siesta_gui_page_generator(dialog, window, model);
gui_button("Animation", siesta_animation_dialog, model->filename, GTK_DIALOG(window)->action_area, TT);
gui_button("FileGenerate", siesta_file_dialog, model, GTK_DIALOG(window)->action_area, TT);
gui_stock_button(GTK_STOCK_CLOSE, dialog_destroy, dialog,
GTK_DIALOG(window)->action_area);
gtk_widget_show_all(window);
}
void file_handler_page_generator(gpointer * dialog, GtkWidget * window, struct model_pak *model)
{
GtkWidget *frame, *vbox;
vbox = gtk_vbox_new(FALSE,0);
gtk_box_pack_start(GTK_BOX(GTK_DIALOG(window)->vbox), vbox, TRUE, TRUE, 10);
gui_direct_check("Write csv", &siestafileWRITE, random_action, NULL, vbox);
frame = gtk_frame_new(" File Specifics " );
gtk_box_pack_start(GTK_BOX(vbox), frame, FALSE, FALSE, 0);
vbox = gtk_vbox_new(FALSE,0);
gtk_container_add(GTK_CONTAINER(frame), vbox);
gui_text_entry("Filename ", &model->siesta.modelfilename, TRUE, TRUE, vbox);
}
void siesta_gui_page_generator(gpointer * dialog, GtkWidget * window, struct model_pak *model)
{
GtkWidget *frame, *radio_vbox, *vbox, *vbox1, *hbox, *label, *notebook;
GtkWidget *geomhbox, *geomhbox2, *geomvbox, *geombook, *combo;
GtkWidget *page, *geompage, *button, *vbox2;
//more sensitive boxes
GtkWidget *target_pressure_sens_box, *zeta_sensitive_box, *sensitive_box;
GList *list;
/* create notebook */
hbox = gtk_hbox_new(FALSE,0);
gtk_box_pack_start(GTK_BOX(GTK_DIALOG(window)->vbox), hbox, TRUE, TRUE, 10);
vbox = gtk_vbox_new(FALSE, 0);
gtk_box_pack_start (GTK_BOX(hbox), vbox, FALSE, FALSE, 0);
// Specifics Page
frame = gtk_frame_new(" System Params " );
gtk_box_pack_start(GTK_BOX(hbox), frame, FALSE, FALSE, 0);
vbox = gtk_vbox_new(FALSE, 0);
gtk_container_add(GTK_CONTAINER(frame), vbox);
hbox = gtk_hbox_new (FALSE, 0);
gtk_box_pack_start(GTK_BOX(vbox),hbox,TRUE,TRUE,0);
notebook = gtk_notebook_new();
gtk_widget_show (notebook);
gtk_container_add(GTK_CONTAINER(hbox), notebook);
page = gtk_vbox_new(FALSE, 0);
label = gtk_label_new (" Electronic Structure ");
gtk_notebook_append_page(GTK_NOTEBOOK(notebook), page, label);
/* title display */
frame = gtk_frame_new(" Basis Set ");
gtk_box_pack_start(GTK_BOX(page), frame, FALSE, FALSE, 0);
radio_vbox = gtk_vbox_new(FALSE, 0);
gtk_container_add(GTK_CONTAINER(frame), radio_vbox);
/* do the radio buttons */
new_radio_group(0, radio_vbox, TT);
button = add_radio_button("Single zeta", (gpointer) set_basis_set_sz, model);
if (model->siesta.basis_set == SZ_ZETA)
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button), TRUE);
button = add_radio_button("Double zeta", (gpointer) set_basis_set_dz, model);
if (model->siesta.basis_set == DZ_ZETA)
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button), TRUE);
button = add_radio_button("Single zeta polarised", (gpointer) set_basis_set_szp, model);
if (model->siesta.basis_set == SZP_ZETA)
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button), TRUE);
button = add_radio_button("Double zeta polarised", (gpointer) set_basis_set_dzp, model);
if (model->siesta.basis_set == DZP_ZETA)
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button), TRUE);
/*
* Redundant code.
button = add_radio_button("Triple zeta", (gpointer) set_basis_set_tz, model);
if (model->siesta.basis_set == TZ)
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button), TRUE);
button = add_radio_button("Triple zeta polarised", (gpointer) set_basis_set_tzp, model);
if (model->siesta.basis_set == TZP)
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button), TRUE);
*/
button = add_radio_button("Custom Zeta", (gpointer) set_basis_set_custom, model);
// Set sensitive frame? how do i do that?
frame = gtk_frame_new(" Custom Zeta Config ");
gtk_box_pack_start(GTK_BOX(radio_vbox), frame, FALSE, FALSE, 0);
zeta_sensitive_box = gtk_vbox_new(FALSE, 0);
model->siesta.custom_zeta_frame = zeta_sensitive_box;
gtk_container_add(GTK_CONTAINER(frame), zeta_sensitive_box);
gui_direct_spin("Zeta level ",
&model->siesta.custom_zeta, 1, 5, 1,
zeta_warning, model, zeta_sensitive_box);
gui_direct_spin("Polarisation level ",
&model->siesta.custom_zeta_polarisation, 0, 5, 1,
zeta_warning, model, zeta_sensitive_box);
if (model->siesta.basis_set != CUSTOM_ZETA)
{
gtk_widget_set_sensitive(GTK_WIDGET(model->siesta.custom_zeta_frame), FALSE);
}
else
{
gtk_widget_set_sensitive(GTK_WIDGET(model->siesta.custom_zeta_frame), TRUE);
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button), TRUE);
}
frame = gtk_frame_new("Special inputs");
gtk_box_pack_start(GTK_BOX(page), frame, FALSE, FALSE, 0);
vbox = gtk_vbox_new(FALSE, 0);
gtk_container_add(GTK_CONTAINER(frame), vbox);
gui_direct_spin("Split Zeta norm ",
&model->siesta.split_zeta_norm, 0.01, 1.00, 0.01,
dud_action, model, vbox);
gui_direct_spin("Energy Shift (Ryd) ",
&model->siesta.energy_shift, 0.001, 0.05, 0.001,
dud_action, model, vbox);
gui_direct_spin("Mesh Cutoff (Ryd) ",
&model->siesta.mesh_cutoff, 40.0, 1000.0, 5,
dud_action, model, vbox);
gui_direct_spin("Electronic temp (K) ",
&model->siesta.electronic_temperature, 0.0,
500.0, 1.0, dud_action, model,
vbox);
gui_direct_check("Spin Polarised",
&model->siesta.spin_polarised,
random_action, page, vbox);
/*
* Periodic model checking....
*/
if (model->periodic == TRUE)
{
gui_direct_check("Is it Periodic?",
&model->siesta.is_periodic,
kgrid_action, page, vbox);
frame = gtk_frame_new("Periodic");
gtk_box_pack_start(GTK_BOX(page), frame, FALSE, FALSE, 0);
vbox1 = gtk_vbox_new(FALSE, 0);
gtk_container_add(GTK_CONTAINER(frame), vbox1);
gui_direct_spin("kgrid Cutoff ",
&model->siesta.kgrid_cutoff, 1.0,
50.0, 1.0, dud_action, model, vbox1);
}
//Next Page
page = gtk_vbox_new(FALSE, 0);
label = gtk_label_new (" SCF ");
gtk_notebook_append_page(GTK_NOTEBOOK(notebook), page, label);
frame = gtk_frame_new("Method");
gtk_box_pack_start(GTK_BOX(page), frame, FALSE, FALSE, 0);
vbox = gtk_vbox_new(FALSE, 0);
gtk_container_add(GTK_CONTAINER(frame), vbox);
//Common to both
gui_direct_spin("Number of Cycles ",
&model->siesta.no_of_cycles, 1.0, 100.0, 1.0,
dud_action, model, vbox);
gui_direct_spin("Mixing Weight ",
&model->siesta.mixing_weight, 0.01, 0.5, 0.01,
dud_action, model, vbox);
sensitive_box = gtk_vbox_new(TRUE, 0);
gui_direct_check("Pulay Mixing", &model->siesta.pulay_mixing,
set_pulay_sensitive, sensitive_box, vbox);
gtk_box_pack_end(GTK_BOX(vbox), sensitive_box, TRUE, TRUE, 0);
/* sensitive box */
vbox = gtk_vbox_new(FALSE,0);
gtk_box_pack_start(GTK_BOX(sensitive_box), vbox, TRUE, TRUE, 0);
gtk_container_set_border_width(GTK_CONTAINER(vbox), PANEL_SPACING);
gui_direct_spin("Number of Pulay Matrices ",
&model->siesta.no_of_pulay_matrices,
1.0, 1000.0, 5, dud_action, model,
vbox);
//inital call to set sensitive.
set_pulay_sensitive(vbox, sensitive_box);
frame = gtk_frame_new("Speed Hacks?");
gtk_box_pack_start(GTK_BOX(page), frame, FALSE, FALSE, 0);
vbox = gtk_vbox_new(FALSE, 0);
gtk_container_add(GTK_CONTAINER(frame), vbox);
gui_direct_check("Divide and Conquer", &model->siesta.diag_divide_and_conquer,
random_action, vbox, vbox);
//Next Page
page = gtk_vbox_new(FALSE, 0);
label = gtk_label_new (" Geometry ");
gtk_notebook_append_page(GTK_NOTEBOOK(notebook), page, label);
frame = gtk_frame_new("Method");
gtk_box_pack_start(GTK_BOX(page), frame, FALSE, FALSE, 0);
vbox = gtk_vbox_new(FALSE, 0);
gtk_container_add(GTK_CONTAINER(frame), vbox);
/* do the radio buttons */
new_radio_group(0, vbox, TT);
button = add_radio_button("Single Point", (gpointer) set_geom_runtype_sp, model);
if (model->siesta.run_type == SINGLE_POINT)
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button), TRUE);
button = add_radio_button("Optimisation", (gpointer) set_geom_runtype_opt, model);
if (model->siesta.run_type == OPTIMISATION)
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button), TRUE);
button = add_radio_button("Molecular Dynamics", (gpointer) set_geom_runtype_md, model);
if (model->siesta.run_type == MOLECULAR_DYNAMICS)
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button), TRUE);
button = add_radio_button("Phonon Calculation", (gpointer) set_geom_runtype_pc, model);
if (model->siesta.run_type == PHONON_CALCULATION)
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button), TRUE);
//options frame
frame = gtk_frame_new("Options");
gtk_box_pack_start(GTK_BOX(page), frame, FALSE, FALSE, 0);
vbox = gtk_vbox_new(FALSE, 0);
gtk_container_add(GTK_CONTAINER(frame), vbox);
geombook = gtk_notebook_new();
gtk_container_add(GTK_CONTAINER(vbox), geombook);
//HACK HACK HACK
model->siesta.geom_notebook_hack = geombook;
// Single Point Page
geompage = gtk_vbox_new(FALSE, 0);
label = gtk_label_new (" Single Point ");
gtk_notebook_append_page(GTK_NOTEBOOK(geombook), geompage, label);
// Single Point Options
label = gtk_label_new("Number of Steps - locked to Zero\n");
gtk_box_pack_start(GTK_BOX(geompage), label, FALSE, FALSE, 0);
label = gtk_label_new("(single point)\n");
gtk_box_pack_start(GTK_BOX(geompage), label, FALSE, FALSE, 0);
geompage = gtk_vbox_new(FALSE, 0);
label = gtk_label_new (" Optimisation ");
gtk_notebook_append_page(GTK_NOTEBOOK(geombook), geompage, label);
vbox = gtk_vbox_new(FALSE,0);
gtk_box_pack_start(GTK_BOX(geompage), vbox, FALSE, FALSE, 0);
gui_direct_check("Optimise cell",
&model->siesta.md_variable_cell,
optimise_cell_action, model, vbox);
gui_direct_spin("Number of Steps ",
&model->siesta.number_of_steps, 2.0, 1000.0, 1.0,
dud_action, NULL, vbox);
//Target pressure - only if optimise cell
//meant to be sensitive
target_pressure_sens_box = gtk_vbox_new(FALSE,0);
gtk_box_pack_start(GTK_BOX(geompage), target_pressure_sens_box, FALSE, FALSE, 0);
gui_direct_spin("Target Pressure",
&model->siesta.md_target_pressure, -5.0, 5.0, 0.1,
dud_action, NULL, vbox);
//Target stress
frame = gtk_frame_new("Stress Tensors");
gtk_box_pack_start(GTK_BOX(geompage), frame, FALSE, FALSE, 0);
//int labled stress vectors.
geomvbox = gtk_hbox_new(FALSE, 0);
gtk_container_add(GTK_CONTAINER(frame), geomvbox);
geomhbox = gtk_vbox_new(FALSE, 0);
gtk_container_add(GTK_CONTAINER(geomvbox), geomhbox);
geomhbox2 = gtk_vbox_new(FALSE, 0);
gtk_container_add(GTK_CONTAINER(geomvbox), geomhbox2);
gui_direct_spin(" xx =",
&model->siesta.md_target_stress_xx, -5.0, 5.0, 0.1,
dud_action, model, geomhbox);
gui_direct_spin(" yy =",
&model->siesta.md_target_stress_yy, -5.0, 5.0, 0.1,
dud_action, model, geomhbox);
gui_direct_spin(" zz =",
&model->siesta.md_target_stress_zz, -5.0, 5.0, 0.1,
dud_action, model, geomhbox);
gui_direct_spin(" xy =",
&model->siesta.md_target_stress_xy, -5.0, 5.0, 0.1,
dud_action, model, geomhbox2);
gui_direct_spin(" xz =",
&model->siesta.md_target_stress_xz, -5.0, 5.0, 0.1,
dud_action, model, geomhbox2);
gui_direct_spin(" yz =",
&model->siesta.md_target_stress_yz, -5.0, 5.0, 0.1,
dud_action, model, geomhbox2);
frame = gtk_frame_new("Termination Options");
gtk_box_pack_start(GTK_BOX(geompage), frame, FALSE, FALSE, 0);
vbox = gtk_vbox_new(FALSE, 0);
gtk_container_add(GTK_CONTAINER(frame), vbox);
gui_direct_spin("Max CG displacement",
&model->siesta.md_max_cg_displacement, 0.0, 2.0, 0.01,
dud_action, NULL, vbox);
gui_direct_spin("Max Force Tolerance",
&model->siesta.md_max_force_tol, 0.0, 2.0, 0.01,
dud_action, NULL, vbox);
gui_direct_spin("Max Stress Tolerance",
&model->siesta.md_max_stress_tol, 0.0, 2.0, 0.1,
dud_action, NULL, vbox);
frame = gtk_frame_new("Job Options");
gtk_box_pack_start(GTK_BOX(geompage), frame, FALSE, FALSE, 0);
vbox = gtk_vbox_new(FALSE, 0);
gtk_container_add(GTK_CONTAINER(frame), vbox);
gui_direct_check("Restart (Use saved data)",
&model->siesta.use_saved_data,
random_action, page, vbox);
geompage = gtk_vbox_new(FALSE, 0);
label = gtk_label_new (" Molecular Dynamics ");
gtk_notebook_append_page(GTK_NOTEBOOK(geombook), geompage, label);
frame = gtk_frame_new("Run Type");
gtk_box_pack_start(GTK_BOX(geompage), frame, FALSE, FALSE, 0);
vbox = gtk_vbox_new(FALSE, 0);
gtk_container_add(GTK_CONTAINER(frame), vbox);
list = NULL;
list = g_list_append(list, "Verlet");
list = g_list_append(list, "Nose");
list = g_list_append(list, "Parrinello-Rahman");
list = g_list_append(list, "Nose-Parrinello-Rahman");
list = g_list_append(list, "Anneal");
list = g_list_append(list, "Phonon");
combo = gtk_combo_new();
gtk_entry_set_editable(GTK_ENTRY(GTK_COMBO(combo)->entry), FALSE);
gtk_combo_set_popdown_strings(GTK_COMBO(combo), list);
gtk_box_pack_end(GTK_BOX(vbox), combo, FALSE, FALSE, 0);
g_signal_connect(GTK_OBJECT(GTK_COMBO(combo)->entry), "changed",
GTK_SIGNAL_FUNC(set_md_run_type), (gpointer *) combo);
frame = gtk_frame_new("Temperature");
gtk_box_pack_start(GTK_BOX(geompage), frame, FALSE, FALSE, 0);
vbox = gtk_vbox_new(FALSE, 0);
gtk_container_add(GTK_CONTAINER(frame), vbox);
gui_direct_spin("Inital Temperature ",
&model->siesta.md_inital_temperature, 0.0, 500.0, 1.0,
dud_action, NULL, vbox);
gui_direct_spin("Target Temperature ",
&model->siesta.md_target_temperature, 0.0, 500.0, 1.0,
dud_action, NULL, vbox);
frame = gtk_frame_new("Pressure");
gtk_box_pack_start(GTK_BOX(geompage), frame, FALSE, FALSE, 0);
vbox = gtk_vbox_new(FALSE, 0);
gtk_container_add(GTK_CONTAINER(frame), vbox);
gui_direct_spin("Target Pressure ",
&model->siesta.pressure, -10.0, 10.0, 0.01,
dud_action, model, vbox);
frame = gtk_frame_new("Time");
gtk_box_pack_start(GTK_BOX(geompage), frame, FALSE, FALSE, 0);
vbox = gtk_vbox_new(FALSE, 0);
gtk_container_add(GTK_CONTAINER(frame), vbox);
gui_direct_spin("Initial Timestep ",
&model->siesta.md_inital_time_step, 0.0, 500.0, 1.0,
dud_action, NULL, vbox);
gui_direct_spin("Final Timestep ",
&model->siesta.md_final_time_step, 0.0, 500.0, 1.0,
dud_action, NULL, vbox);
gui_direct_spin("Length of Timestep ",
&model->siesta.md_length_time_step, 0.1, 200.0, 0.1,
dud_action, NULL, vbox);
frame = gtk_frame_new("Job Options");
gtk_box_pack_start(GTK_BOX(geompage), frame, FALSE, FALSE, 0);
vbox = gtk_vbox_new(FALSE, 0);
gtk_container_add(GTK_CONTAINER(frame), vbox);
gui_direct_check("Restart (Use saved data)",
&model->siesta.use_saved_data,
random_action, page, vbox);
geompage = gtk_vbox_new(FALSE, 0);
label = gtk_label_new (" Phonon ");
gtk_notebook_append_page(GTK_NOTEBOOK(geombook), geompage, label);
frame = gtk_frame_new("Differencing");
gtk_box_pack_start(GTK_BOX(geompage), frame, FALSE, FALSE, 0);
vbox = gtk_vbox_new(FALSE, 0);
gtk_container_add(GTK_CONTAINER(frame), vbox);
gui_direct_spin("Finite Difference step size ",
&model->siesta.finite_diff_step_size, 0.1, 10.0, 0.1,
dud_action, NULL, vbox);
frame = gtk_frame_new("Job Options");
gtk_box_pack_start(GTK_BOX(geompage), frame, FALSE, FALSE, 0);
vbox = gtk_vbox_new(FALSE, 0);
gtk_container_add(GTK_CONTAINER(frame), vbox);
gui_direct_check("Restart (Use saved data)",
&model->siesta.use_saved_data,
random_action, page, vbox);
gtk_notebook_set_current_page (GTK_NOTEBOOK(geombook), 3); // BROKEN
gtk_notebook_set_show_tabs (GTK_NOTEBOOK(geombook), FALSE);
gtk_notebook_set_show_border (GTK_NOTEBOOK(geombook), FALSE);
//Next Page
page = gtk_vbox_new(FALSE, 0);
label = gtk_label_new (" File I/O ");
gtk_notebook_append_page(GTK_NOTEBOOK(notebook), page, label);
frame = gtk_frame_new("Files");
gtk_box_pack_start(GTK_BOX(page), frame, FALSE, FALSE, 0);
vbox = gtk_vbox_new(FALSE, 0);
gtk_container_add(GTK_CONTAINER(frame), vbox);
gui_direct_check("Long output ",
&model->siesta.long_output,
long_output_click, model, vbox);
frame = gtk_frame_new("Mesh potential");
gtk_box_pack_start(GTK_BOX(page), frame, FALSE, FALSE, 0);
vbox = gtk_vbox_new(FALSE, 0);
gtk_container_add(GTK_CONTAINER(frame), vbox);
gui_direct_spin("Density of states ",
&model->siesta.density_of_states, 0.1, 10.0, 0.1,
dud_action, model, vbox);
gui_direct_spin("Density on mesh ",
&model->siesta.density_on_mesh, 0.1, 10.0, 0.1,
dud_action, model, vbox);
gui_direct_spin("Electrostatic pot on mesh ",
&model->siesta.electrostatic_pot_on_mesh, 0.1, 10.0, 0.1,
dud_action, model, vbox);
frame = gtk_frame_new("Output Options");
gtk_box_pack_start(GTK_BOX(page), frame, FALSE, FALSE, 0);
hbox = gtk_hbox_new(FALSE, 0);
gtk_container_add(GTK_CONTAINER(frame), hbox);
vbox = gtk_vbox_new(FALSE, 0);
vbox2 = gtk_vbox_new(FALSE, 0);
gtk_box_pack_start(GTK_BOX(hbox), vbox, FALSE, FALSE, 0);
gtk_box_pack_start(GTK_BOX(hbox), vbox2, FALSE, FALSE, 0);
model->siesta.long_output_widget = hbox;
gui_direct_check("WriteCoorStep ",
&model->siesta.file_output_write_coor_step,
random_action, page, vbox);
gui_direct_check("WriteForces ",
&model->siesta.file_output_write_forces,
random_action, page, vbox);
gui_direct_check("WriteKpoints ",
&model->siesta.file_output_write_kpoints,
random_action, page, vbox);
gui_direct_check("WriteEigenvalues ",
&model->siesta.file_output_write_eigenvalues,
random_action, page, vbox);
gui_direct_check("WriteKbands ",
&model->siesta.file_output_write_kbands,
random_action, page, vbox2);
gui_direct_check("WriteBands ",
&model->siesta.file_output_write_bands,
random_action, page, vbox2);
gui_direct_check("WriteWaveFunctions ",
&model->siesta.file_output_write_wavefunctions,
random_action, page, vbox2);
gui_direct_spin("WriteMullikenPop",
&model->siesta.file_output_write_mullikenpop, 0.0, 3.0, 1.0,
dud_action, page, vbox2);
frame = gtk_frame_new("Extra Output Options");
gtk_box_pack_start(GTK_BOX(page), frame, FALSE, FALSE, 0);
vbox = gtk_vbox_new(FALSE, 0);
gtk_container_add(GTK_CONTAINER(frame), vbox);
gui_direct_check("Write density matrix",
&model->siesta.file_output_write_dm,
random_action, page, vbox);
gui_direct_check("Write Xmol coordinates",
&model->siesta.file_output_write_coor_xmol,
random_action, page, vbox);
gui_direct_check("Write cerius coordinates",
&model->siesta.file_output_write_coor_cerius,
random_action, page, vbox);
gui_direct_check("Write MD xmol",
&model->siesta.file_output_write_md_xmol,
random_action, page, vbox);
gui_direct_check("Write MD history",
&model->siesta.file_output_write_md_history,
random_action, page, vbox);
gui_relation_update(NULL);
g_list_free(list);
}
/*-------------------
* Modifiers for the radio buttons
* Electronic Structure PAGE
*-------------------
*/
void set_basis_set_sz(struct model_pak * model)
{
model->siesta.basis_set = SZ_ZETA;
gtk_widget_set_sensitive(GTK_WIDGET(model->siesta.custom_zeta_frame), FALSE);
}
void set_basis_set_dz(struct model_pak * model)
{
model->siesta.basis_set = DZ_ZETA;
gtk_widget_set_sensitive(GTK_WIDGET(model->siesta.custom_zeta_frame), FALSE);
}
void set_basis_set_szp(struct model_pak * model)
{
model->siesta.basis_set = SZP_ZETA;
gtk_widget_set_sensitive(GTK_WIDGET(model->siesta.custom_zeta_frame), FALSE);
}
void set_basis_set_dzp(struct model_pak * model)
{
model->siesta.basis_set = DZP_ZETA;
gtk_widget_set_sensitive(GTK_WIDGET(model->siesta.custom_zeta_frame), FALSE);
}
void set_basis_set_custom(struct model_pak * model)
{
model->siesta.basis_set = CUSTOM_ZETA;
gtk_widget_set_sensitive(GTK_WIDGET(model->siesta.custom_zeta_frame), TRUE);
}
/*-----------------------------
* More radio buttons - GEOM PAGE
*/
void set_geom_runtype_sp(struct model_pak * data)
{
data->siesta.run_type = SINGLE_POINT;
//change the notebook - HACK HACK HACK
gtk_notebook_set_current_page(GTK_NOTEBOOK(data->siesta.geom_notebook_hack), 0);
}
void set_geom_runtype_opt(struct model_pak * data)
{
data->siesta.run_type = OPTIMISATION;
//change the notebook - HACK HACK HACK
gtk_notebook_set_current_page(GTK_NOTEBOOK(data->siesta.geom_notebook_hack), 1);
}
void set_geom_runtype_md(struct model_pak * data)
{
data->siesta.run_type = MOLECULAR_DYNAMICS;
//change the notebook - HACK HACK HACK
gtk_notebook_set_current_page( GTK_NOTEBOOK(data->siesta.geom_notebook_hack), 2);
}
void set_geom_runtype_pc(struct model_pak * data)
{
data->siesta.run_type = PHONON_CALCULATION;
data->siesta.md_type_of_run = FC_MDRUN;
//change the notebook - HACK HACK HACK
gtk_notebook_set_current_page( GTK_NOTEBOOK(data->siesta.geom_notebook_hack), 3);
}
void set_geom_constantcomp_cp(struct model_pak * data)
{
data->siesta.constant_component = CONSTANT_PRESSURE;
}
void set_geom_constantcomp_cv(struct model_pak * data)
{
data->siesta.constant_component = CONSTANT_VOLUME;
}
void kgrid_action (GtkWidget * mywidget, gboolean checkit)
{
if (checkit == TRUE)
{
gtk_widget_set_sensitive(mywidget, TRUE);
}
else
{
gtk_widget_set_sensitive(mywidget, FALSE);
}
}
void dud_action(GtkWidget *w, struct model_pak * data)
{
//Do i need this?
//maybe i dooo
}
void set_pulay_sensitive(GtkWidget *w, GtkWidget *a_frame)
{
struct model_pak * model;
model = sysenv.active_model;
if (model->siesta.pulay_mixing)
gtk_widget_set_sensitive(GTK_WIDGET(a_frame), TRUE);
else
gtk_widget_set_sensitive(GTK_WIDGET(a_frame), FALSE);
}
void random_action(GtkWidget *w, GtkWidget *box)
{
/* do nothing
*/
}
void optimise_cell_action(GtkWidget *w, struct model_pak * model)
{
// Must set it to constant pressure if volume is changing?
}
void long_output_click(GtkWidget *w, struct model_pak * model)
{
if (model->siesta.long_output)
{
model->siesta.file_output_write_coor_step = TRUE;
model->siesta.file_output_write_forces = TRUE;
model->siesta.file_output_write_kpoints = TRUE;
model->siesta.file_output_write_eigenvalues = TRUE;
model->siesta.file_output_write_bands = TRUE;
model->siesta.file_output_write_kbands = TRUE;
model->siesta.file_output_write_wavefunctions = TRUE;
model->siesta.file_output_write_mullikenpop = 1;
gui_relation_update(NULL);
}
else
{
model->siesta.file_output_write_coor_step = FALSE;
model->siesta.file_output_write_forces = FALSE;
model->siesta.file_output_write_kpoints = FALSE;
model->siesta.file_output_write_eigenvalues = FALSE;
model->siesta.file_output_write_bands = FALSE;
model->siesta.file_output_write_kbands = FALSE;
model->siesta.file_output_write_wavefunctions = FALSE;
model->siesta.file_output_write_mullikenpop = 0;
gui_relation_update(NULL);
}
}
void zeta_warning (GtkWidget *w, struct model_pak * model)
{
if ((int) model->siesta.custom_zeta > 4)
{
gchar * message;
message = g_strdup("What are you doing?\nMore than 4 zeta levels\nGrind Grind Grind?");
gui_text_show(ERROR, message);
g_free(message);
}
if ((int) model->siesta.custom_zeta_polarisation > 3)
{
gchar * message;
message = g_strdup("What are you doing?\nMore than 3 polarisations?");
gui_text_show(ERROR, message);
g_free(message);
}
}
void siesta_animation_dialog(GtkWidget *w, gchar *message)
{
gint num_tokens, num_atoms, num_lines, i, j, k, l;
gchar ** buff;
gdouble wi, wj, value;
gpointer bigmat, correction_mat, mini_correction_zerooooo_mat;
GSList *list_i, *list_j;
struct model_pak * model;
struct core_pak *core_i;
struct core_pak *core_j;
GtkWidget *hbox, *vbox, *vbox2, *window;
GtkWidget *dialog, *frame;
model = sysenv.active_model;
g_assert(model != NULL);
/* NEW - check (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;
}
}
num_atoms = model->num_atoms;
//lines = 3 * N * N * 2;
// xyz, each atom, back/forward
num_lines = 3*2*num_atoms*num_atoms;
/* Create the widgets */
/* request a dialog */
dialog = dialog_request(100, "Vibrational viewer", NULL, NULL, model);
if (!dialog)
return;
window = dialog_window(dialog);
if (!model->siesta.vibration_calc_complete)
{
FILE *fp, *matout;
gchar * modelFCname, *modelFCnameCSV;
gdouble correction;
gint temp_int;
gdouble freq_i, freq_ii;
gint sizeofeig;
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;
}
}
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;
}
//no need for names anymore
g_free(modelFCname);
/* FIXME - wtf am I going to do about this crap Terry? */
/*
MAT * bigmat;
*/
//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)));
/*
bigmat->me[i/(2*num_atoms)][(3*i)%(3*num_atoms)] = str_to_float (*buff);
bigmat->me[i/(2*num_atoms)][((3*i)+1)%(3*num_atoms)] = str_to_float (*(buff+1));
bigmat->me[i/(2*num_atoms)][((3*i)+2)%(3*num_atoms)] = str_to_float (*(buff+2));
*/
}
else
{
//second pass - do the average
/*
bigmat->me[i/(2*num_atoms)][(3*i)%(3*num_atoms)] =
( bigmat->me[i/(2*num_atoms)][(3*i)%(3*num_atoms)] + (str_to_float (*buff))) / 2.0;
bigmat->me[i/(2*num_atoms)][((3*i)+1)%(3*num_atoms)] =
( bigmat->me[i/(2*num_atoms)][((3*i)+1)%(3*num_atoms)] + (str_to_float (*(buff+1)))) / 2.0;
bigmat->me[i/(2*num_atoms)][((3*i)+2)%(3*num_atoms)] =
( bigmat->me[i/(2*num_atoms)][((3*i)+2)%(3*num_atoms)] + (str_to_float (*(buff+2)))) / 2.0;
*/
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);
/*
bigmat->me[i][j] = (bigmat->me[i][j] + bigmat->me[j][i]) / 2;
bigmat->me[j][i] = bigmat->me[i][j];
*/
}
}
/* FIXME - wtf am I going to do about this crap Terry? */
/*
MAT * correction_mat, * mini_correction_zerooooo_mat;
*/
/*
correction_mat = m_get(3*num_atoms,3);
mini_correction_zerooooo_mat = m_get(3,3);
*/
correction_mat = mesch_mat_new(3*num_atoms,3);
mini_correction_zerooooo_mat = mesch_mat_new(3,3);
/*
correction_mat = m_zero(correction_mat);
mini_correction_zerooooo_mat = m_zero(mini_correction_zerooooo_mat);
*/
mesch_m_zero(correction_mat);
mesch_m_zero(mini_correction_zerooooo_mat);
//build the correction_matrix
/*
for (i=0; i<(bigmat->m); i++)
*/
for (i=0; i<mesch_rows_get(bigmat); i++)
{
/*
for (j=0; j<((bigmat->n)/3); j++)
*/
for (j=0; j<mesch_cols_get(bigmat)/3; j++)
{
//[3n][3] -> [i][0], [i][1], [i][2]
/*
correction_mat->me[i][0] = bigmat->me[i][(3*j)] + correction_mat->me[i][0];
correction_mat->me[i][1] = bigmat->me[i][(3*j)+1] + correction_mat->me[i][1];
correction_mat->me[i][2] = bigmat->me[i][(3*j)+2] + correction_mat->me[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);
/*
correction_mat->me[i][0] = correction_mat->me[i][0] / num_atoms;
correction_mat->me[i][1] = correction_mat->me[i][1] / num_atoms;
correction_mat->me[i][2] = correction_mat->me[i][2] / num_atoms;
*/
}
//built mini matrix - [3][3]
/*
for (i=0; i<(correction_mat->m); i++)
*/
for (i=0; i<mesch_rows_get(correction_mat); i++)
{
/*
for (j=0; j<((correction_mat->n)); j++)
*/
for (j=0; j<mesch_cols_get(correction_mat); j++)
{
/*
mini_correction_zerooooo_mat->me[i%3][j] = correction_mat->me[i][j] + mini_correction_zerooooo_mat->me[i%3][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 (i=0; i<(mini_correction_zerooooo_mat->m); i++)
*/
{
for (j=0; j<mesch_cols_get(mini_correction_zerooooo_mat); j++)
/*
for (j=0; j<((mini_correction_zerooooo_mat->n)); j++)
*/
{
mesch_me_mul(mini_correction_zerooooo_mat, i, j, value);
/*
mini_correction_zerooooo_mat->me[i][j] = mini_correction_zerooooo_mat->me[i][j]/num_atoms;
*/
}
}
//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
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 = ((mini_correction_zerooooo_mat->me[k][l]
+ mini_correction_zerooooo_mat->me[l][k]) / 2)
- correction_mat->me[3*i+k][l]
- correction_mat->me[3*j+l][k];
*/
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);
/*
bigmat->me[3*i+k][(3*j+l)] = bigmat->me[3*i+k][(3*j+l)] + correction;
*/
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++)
{
/*
value = 1.0 / sqrt(elements[core_i->atom_code].weight * elements[core_j->atom_code].weight);
*/
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);
/*
bigmat->me[(3*i)+k][(3*j)] = (bigmat->me[(3*i)+k][(3*j)]) / (sqrt(elements[core_i->atom_code].weight * elements[core_j->atom_code].weight));
bigmat->me[(3*i)+k][(3*j)+1] = (bigmat->me[(3*i)+k][(3*j)+1]) / (sqrt(elements[core_i->atom_code].weight * elements[core_j->atom_code].weight));
bigmat->me[(3*i)+k][(3*j)+2] = (bigmat->me[(3*i)+k][(3*j)+2]) / (sqrt(elements[core_i->atom_code].weight * elements[core_j->atom_code].weight));
*/
}
j++;
}
i++;
j=0;
}
/*
model->siesta.eigen_xyz_atom_mat = m_get(3*num_atoms, 3*num_atoms);
model->siesta.eigen_values = v_get(3*num_atoms);
*/
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[(model->siesta.eigen_values->dim)]));
*/
model->siesta.sorted_eig_values = g_malloc(sizeof(int[mesch_dim_get(model->siesta.eigen_values)]));
/*
for (i=0; i<(model->siesta.eigen_values->dim); i++)
*/
for (i=0; i<mesch_dim_get(model->siesta.eigen_values); i++)
{
model->siesta.sorted_eig_values[i] = i;
}
/*
gint sizeofeig = model->siesta.eigen_values->dim;
*/
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(model->siesta.eigen_values->ve[model->siesta.sorted_eig_values[i]]);
freq_ii= make_eigvec_freq(model->siesta.eigen_values->ve[model->siesta.sorted_eig_values[i+1]]);
*/
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)
{
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);
}
//stop it having to recalc vib modesfds.
model->siesta.vibration_calc_complete = TRUE;
vbox = gtk_vbox_new(TRUE,1);
gtk_container_add (GTK_CONTAINER (GTK_DIALOG(window)->vbox), vbox);
frame = gtk_frame_new(" Scaling options ");
gtk_box_pack_start(GTK_BOX(vbox), frame, TRUE, FALSE, 1);
hbox = gtk_vbox_new(TRUE, 1);
gtk_container_add(GTK_CONTAINER(frame), hbox);
gui_direct_spin("Scaling Factor ", &model->siesta.custom_scaler, 0.0, 0.4, 0.01, dud_action, model, hbox);
frame = gtk_frame_new(" Frequencies ");
gtk_box_pack_start(GTK_BOX(hbox), frame, TRUE, TRUE, 1);
hbox = gtk_vbox_new(TRUE, 1);
gtk_container_add(GTK_CONTAINER(frame), hbox);
model->siesta.freq_text_box = gui_text_entry("Frequency", &model->siesta.freq_disp_str, TRUE, TRUE, hbox);
gtk_editable_set_editable((GtkEditable*) model->siesta.freq_text_box, FALSE);
model->siesta.siesta_phonon_slider = gui_direct_hscale(0.0, model->siesta.num_animations-1.0, 1.0, &model->siesta.current_animation, siesta_load_animation, model, hbox);
frame = gtk_frame_new(" Animation ");
gtk_box_pack_start(GTK_BOX(vbox), frame, TRUE, TRUE, 0);
hbox = gtk_hbox_new(TRUE, 0);
gtk_container_add(GTK_CONTAINER(frame), hbox);
vbox = gtk_vbox_new(TRUE, 0);
vbox2 = gtk_vbox_new(TRUE, 0);
gtk_box_pack_start(GTK_BOX(hbox), vbox, TRUE, TRUE, 0);
gtk_box_pack_start(GTK_BOX(hbox), vbox2, TRUE, TRUE, 0);
gui_stock_button(GTK_STOCK_CLOSE, siesta_animation_dialog_destroy, dialog, GTK_DIALOG(window)->action_area);
gui_button("Toggle Animate", set_animate, model, vbox, TT);
gui_button("Pause Animate", siesta_toggle_paused, model, vbox, TT);
gui_button("Show Vectors", siesta_show_vect, model, vbox, TT);
gui_button("Show Freq", siesta_showfreq, model, vbox2, TT);
gui_button("Next Freq", siesta_nextfreq, model, vbox2, TT);
gui_button("Prev Freq", siesta_prevfreq, model, vbox2, TT);
gtk_widget_show_all (window);
}
void set_md_run_type(GtkWidget *w, gpointer *data)
{
//evil active model call - evil evil evil
struct model_pak *model;
gchar *buff;
model = sysenv.active_model;
buff = g_strdup(gtk_entry_get_text(GTK_ENTRY(GTK_COMBO(data)->entry)));
if (g_ascii_strncasecmp("Verlet", buff, 6) == 0)
model->siesta.md_type_of_run = VERLET_MDRUN;
else if (g_ascii_strncasecmp("Nose", buff, 4) == 0)
model->siesta.md_type_of_run = NOSE_MDRUN;
else if (g_ascii_strncasecmp("Parrinello-Rahman", buff, 17) == 0)
model->siesta.md_type_of_run = PARRINELLOPAHMAN_MDRUN;
else if (g_ascii_strncasecmp("Nose-Parrinello-Rahman", buff, 22) == 0)
model->siesta.md_type_of_run = NOSEPARRINELLOPAHMAN_MDRUN;
else if (g_ascii_strncasecmp("Anneal", buff, 6) == 0)
model->siesta.md_type_of_run = ANNEAL_MDRUN;
g_free(buff);
}
void siesta_prevfreq(GtkWidget *w, struct model_pak *model)
{
//~ gchar * text;
if (!model->siesta.eigen_values)
return;
model->siesta.current_animation = model->siesta.current_animation - 1;
if (0>model->siesta.current_animation)
model->siesta.current_animation = model->siesta.current_animation + model->siesta.num_animations;
//set slider - stupid slider
gtk_range_set_value((GtkRange*) model->siesta.siesta_phonon_slider, model->siesta.current_animation);
//Lookup and set freq-> using index array.
model->siesta.current_frequency = make_eigvec_freq(mesch_ve_get(model->siesta.eigen_values, model->siesta.sorted_eig_values[model->siesta.current_animation]));
g_free(model->siesta.freq_disp_str);
model->siesta.freq_disp_str = g_strdup_printf("%.2f", model->siesta.current_frequency);
gtk_entry_set_text((GtkEntry *) model->siesta.freq_text_box, model->siesta.freq_disp_str);
/* text = g_strdup_printf("Animating freq %d, at %f Hz\n", model->siesta.current_animation, model->siesta.current_frequency );
gui_text_show(ERROR, text);
g_free(text); */
}
void siesta_nextfreq(GtkWidget *w, struct model_pak *model)
{
//gchar * text;
if (!model->siesta.eigen_values)
return;
model->siesta.current_animation = model->siesta.current_animation + 1;
if ( model->siesta.num_animations<=model->siesta.current_animation)
model->siesta.current_animation = model->siesta.current_animation - model->siesta.num_animations;
//set slider - stupid slider
gtk_range_set_value((GtkRange*) model->siesta.siesta_phonon_slider, model->siesta.current_animation);
//Lookup and set freq-> using index array.
/*
model->siesta.current_frequency = make_eigvec_freq(model->siesta.eigen_values->ve[model->siesta.sorted_eig_values[model->siesta.current_animation]]);
*/
model->siesta.current_frequency = make_eigvec_freq(mesch_ve_get(model->siesta.eigen_values, model->siesta.sorted_eig_values[model->siesta.current_animation]));
g_free(model->siesta.freq_disp_str);
model->siesta.freq_disp_str = g_strdup_printf("%.2f", model->siesta.current_frequency);
gtk_entry_set_text((GtkEntry *) model->siesta.freq_text_box, model->siesta.freq_disp_str);
/* text = g_strdup_printf("Animating freq %d, at %f Hz - string %s\n", model->siesta.current_animation, model->siesta.current_frequency, model->siesta.freq_disp_str );
gui_text_show(ERROR, text);
g_free(text); */
}
void siesta_showfreq(GtkWidget *w, struct model_pak *model)
{
gtk_range_set_value((GtkRange*) model->siesta.siesta_phonon_slider, model->siesta.current_animation);
g_free(model->siesta.freq_disp_str);
model->siesta.freq_disp_str = g_strdup_printf("%.2f", model->siesta.current_frequency);
gtk_entry_set_text((GtkEntry *) model->siesta.freq_text_box, model->siesta.freq_disp_str);
/* gchar * text;
text = g_strdup_printf("Frequency is at %f Hz\n", model->siesta.current_frequency );
gui_text_show(ERROR, text);
g_free(text); */
}
gdouble make_eigvec_freq(gdouble value)
{
gdouble xmagic;
xmagic = 519.6;
if (value > 0.0)
{
return sqrt(xmagic*xmagic*value);
}
else // fake number!
{
return -sqrt(-xmagic*xmagic*value);
}
}
void siesta_show_vect(GtkWidget *w, struct model_pak *model)
{
gint i;
gdouble x1[3], x2[3], colour[3];
GSList *list;
struct spatial_pak *spatial;
struct core_pak *core;
gint atom;
if (!model->siesta.eigen_xyz_atom_mat)
return;
/* get rid of previous phonon objects */
spatial_destroy_by_label("phonons", model);
VEC3SET(colour, 0.0, 1.0, 0.0);
if (model->siesta.show_vect == TRUE)
{
model->siesta.show_vect = FALSE;
coords_compute(model);
redraw_canvas(SINGLE);
return;
}
else
{
model->siesta.show_vect = TRUE;
}
/* create & init the spatial object */
spatial = spatial_new("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 */
/*
x2[0] = model->siesta.eigen_xyz_atom_mat->me[3*atom][model->siesta.sorted_eig_values[model->siesta.current_animation]];
x2[1] = model->siesta.eigen_xyz_atom_mat->me[3*atom+1][model->siesta.sorted_eig_values[model->siesta.current_animation]];
x2[2] = model->siesta.eigen_xyz_atom_mat->me[3*atom+2][model->siesta.sorted_eig_values[model->siesta.current_animation]];
*/
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++;
#if DEBUG_PHONON_DISPLAY
P3VEC("vec: ", x2);
#endif
/* compute coords */
VEC3MUL(x2, sysenv.render.phonon_scaling);
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);
}
gint siesta_timed_animate(struct model_pak *model)
{
//successful -> 0, fail = 1;
int MAX_PULSE_COUNT = 10.0;
int atom;
struct core_pak *core;
gdouble x1[3], f;
GSList *list;
if (!model->siesta.eigen_xyz_atom_mat)
return(FALSE);
//stop conditions
if (!model->pulse_direction)
return (FALSE);
if (!model->siesta.animation_paused)
{
/* setup scaling for this step */
model->pulse_count += model->pulse_direction;
if (model->pulse_count <= -MAX_PULSE_COUNT)
{
model->pulse_count = -MAX_PULSE_COUNT;
model->pulse_direction = 1;
}
if (model->pulse_count >= MAX_PULSE_COUNT)
{
model->pulse_count = MAX_PULSE_COUNT;
model->pulse_direction = -1;
}
f = sysenv.render.phonon_scaling;
f *= (gdouble) model->pulse_count;
f /= MAX_PULSE_COUNT;
atom = 0;
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] = model->siesta.eigen_xyz_atom_mat->me[3*atom][model->siesta.sorted_eig_values[model->siesta.current_animation]];
core->offset[1] = model->siesta.eigen_xyz_atom_mat->me[3*atom+1][model->siesta.sorted_eig_values[model->siesta.current_animation]];
core->offset[2] = model->siesta.eigen_xyz_atom_mat->me[3*atom+2][model->siesta.sorted_eig_values[model->siesta.current_animation]];
*/
core->offset[0] = mesch_me_get(model->siesta.eigen_xyz_atom_mat, 3*atom, model->siesta.sorted_eig_values[model->siesta.current_animation]);
core->offset[1] = mesch_me_get(model->siesta.eigen_xyz_atom_mat, 3*atom+1, model->siesta.sorted_eig_values[model->siesta.current_animation]);
core->offset[2] = mesch_me_get(model->siesta.eigen_xyz_atom_mat, 3*atom+2, model->siesta.sorted_eig_values[model->siesta.current_animation]);
atom++;
VEC3MUL(core->offset, f);
VEC3MUL(core->offset, model->siesta.custom_scaler);
vecmat(model->ilatmat, core->offset);
}
/* drawing update */
coords_compute(model);
redraw_canvas(SINGLE);
}
return (TRUE);
}
void set_animate(GtkWidget *w, struct model_pak *model)
{
if (model->animating)
{
//stop animation
model->animating = FALSE;
//cleanup
siesta_destroy_timer(model);
}
else
{
//create timer
siesta_create_timer(model);
model->animating = TRUE;
model->siesta.animation_paused = FALSE;
}
}
void siesta_create_timer(struct model_pak *model)
{
//create timer callback
g_assert(model != NULL);
model->pulse_count = 0;
model->pulse_direction = 1;
g_timeout_add(25, (GSourceFunc) siesta_timed_animate, model);
}
void siesta_destroy_timer( struct model_pak * model)
{
/* reset */
model->pulse_direction = 0;
model->pulse_count = 0;
siesta_timeout_cleanup(model);
/* redraw */
coords_compute(model);
redraw_canvas(SINGLE);
}
void siesta_toggle_paused(GtkWidget *w, struct model_pak *model)
{
if (model->siesta.animation_paused)
{
model->siesta.animation_paused = FALSE;
}
else
{
model->siesta.animation_paused = TRUE;
}
}
void siesta_timeout_cleanup(struct model_pak *model)
{
GSList *list;
struct core_pak *core;
g_assert(model != NULL);
for (list=model->cores ; list; list=g_slist_next(list))
{
core = list->data;
VEC3SET(core->offset, 0.0, 0.0, 0.0);
}
}
void siesta_file_dialog(GtkWidget *w, struct model_pak * model)
{
GtkWidget *hbox, *vbox, *vbox2, *window;
GtkWidget *dialog, *frame, *label;
/* Create the widgets */
/* request a dialog */
dialog = dialog_request(100, "Multi File Writer", NULL, NULL, model);
if (!dialog)
return;
window = dialog_window(dialog);
vbox = gtk_vbox_new(TRUE,5);
gtk_container_add (GTK_CONTAINER (GTK_DIALOG(window)->vbox), vbox);
frame = gtk_frame_new(" Atoms in system ");
gtk_box_pack_start(GTK_BOX(vbox), frame, TRUE, FALSE, 0);
hbox = gtk_vbox_new(TRUE, 0);
gtk_container_add(GTK_CONTAINER(frame), hbox);
label = gtk_label_new(g_strdup_printf("Atoms seen by GDIS = %d\n", model->num_atoms));
gtk_box_pack_start(GTK_BOX(hbox), label, TRUE, FALSE, 0);
//how to round it?
model->siesta.atoms_per_job = (gdouble) ((int) 100/(model->num_atoms));
label = gtk_label_new(g_strdup_printf("Recommended atoms per job = %d\n", (int) 100/(model->num_atoms)));
gtk_box_pack_start(GTK_BOX(hbox), label, TRUE, FALSE, 0);
frame = gtk_frame_new(" Job Totals ");
gtk_box_pack_start(GTK_BOX(vbox), frame, TRUE, FALSE, 0);
hbox = gtk_hbox_new(TRUE, 0);
gtk_container_add(GTK_CONTAINER(frame), hbox);
vbox2 = gtk_vbox_new(TRUE, 0);
gtk_box_pack_start(GTK_BOX(hbox), vbox2, TRUE, FALSE, 0);
gui_direct_spin("Atoms per Job ", &model->siesta.atoms_per_job, 1.0, model->num_atoms, 1.0, dud_action, model, vbox2);
frame = gtk_frame_new(" Job Setup ");
gtk_box_pack_start(GTK_BOX(vbox), frame, TRUE, FALSE, 0);
hbox = gtk_hbox_new(TRUE, 0);
gtk_container_add(GTK_CONTAINER(frame), hbox);
vbox = gtk_vbox_new(TRUE, 0);
gtk_box_pack_start(GTK_BOX(hbox), vbox, TRUE, FALSE, 0);
// file location
gui_stock_button(GTK_STOCK_SAVE, siesta_file_save_loop, model, GTK_DIALOG(window)->action_area);
gui_button("Save and Queue", siesta_save_n_queue, model, GTK_DIALOG(window)->action_area, TT);
gui_stock_button(GTK_STOCK_CLOSE, dialog_destroy, dialog, GTK_DIALOG(window)->action_area);
gtk_widget_show_all (window);
}
void siesta_file_save_loop(GtkWidget *w, struct model_pak * model)
{
int i;
int total_files;
gchar * filename, * orig_basename;
total_files = model->num_atoms / model->siesta.atoms_per_job +1;
orig_basename = g_strdup(model->basename);
for (i=0; i<total_files; i++)
{
//grab current grid_config_pak
struct grid_config_pak * grid_pak;
//set the range for md_fc_first, and md_fc_last
model->siesta.md_fc_first = i* model->siesta.atoms_per_job + 1;
model->siesta.md_fc_last = i * model->siesta.atoms_per_job + model->siesta.atoms_per_job;
filename = g_strdup_printf("%s.%d.%d", orig_basename, i+1, total_files);
if (model->siesta.md_fc_last >= model->num_atoms)
{
i++;
model->siesta.md_fc_last = model->num_atoms;
}
model->basename = g_strdup(filename);
filename = g_strdup_printf("%s.fdf", filename);
// call the fdf save bit....
file_save_as(filename, model);
//get job directory
siesta_make_runscript(model->basename, sysenv.cwd, grid_pak);
gui_text_show(OUTPUT, g_strdup_printf("fc-first:\t%d\tfc-last:\t%d\t\t", model->siesta.md_fc_first, model->siesta.md_fc_last));
gui_text_show(OUTPUT, model->basename);
gui_text_show(OUTPUT, "\n");
g_free(filename);
}
model->basename = g_strdup(orig_basename);
}
void siesta_make_runscript(gchar * model_name, gchar * directory, struct grid_config_pak * grid)
{
FILE *script;
gchar *script_name;
script_name = g_strdup_printf("run.script.%s", model_name);
g_build_filename(directory, script_name, NULL);
script = fopen (script_name, "w");
if (!script_name)
return;
fprintf(script, "#!/bin/bash\n");
fprintf(script, "#PBS -P d64\n");
fprintf(script, "#PBS -l ncpus=8\n");
fprintf(script, "#PBS -l vmem=2800mb\n");
fprintf(script, "#PBS -l walltime=2:00:00\n");
fprintf(script, "#PBS -l software=siesta\n");
fprintf(script, "#PBS -l other=mpi\n");
fprintf(script, "#PBS -wd\n");
fprintf(script, "module load siesta\n");
fprintf(script, "mpirun siesta < %s.fdf > %s.sot\n", model_name, model_name);
fclose (script);
g_free (script_name);
}
void siesta_load_animation(GtkWidget *w, struct model_pak *model)
{
//change the current animation to the slider value
//slider value auto updated due to shortcut.
if (!model->siesta.eigen_values)
return;
g_free(model->siesta.freq_disp_str);
/*
model->siesta.current_frequency = make_eigvec_freq(model->siesta.eigen_values->ve[model->siesta.sorted_eig_values[model->siesta.current_animation]]);
*/
model->siesta.current_frequency = make_eigvec_freq(mesch_ve_get(model->siesta.eigen_values, model->siesta.sorted_eig_values[model->siesta.current_animation]));
model->siesta.freq_disp_str = g_strdup_printf("%.2f", model->siesta.current_frequency);
gtk_entry_set_text((GtkEntry *) model->siesta.freq_text_box, model->siesta.freq_disp_str);
}
void siesta_animation_dialog_destroy(GtkWidget *w, gpointer *dialog)
{
struct model_pak * model;
model = sysenv.active_model;
//stop the animation timer
siesta_destroy_timer(model);
//kill the dialog
dialog_destroy(w, dialog);
}
void siesta_save_n_queue(GtkWidget *w, struct model_pak * model)
{
int i, jobID;
int total_files;
gchar * filename, * orig_basename, *queuepath, *jobID_string;
struct grid_config_pak * grid_pak;
total_files = model->num_atoms / model->siesta.atoms_per_job +1;
orig_basename = g_strdup(model->basename);
//default jobstorage dir??
//"$homedir/.gdis_jobs/ ?
queuepath = g_build_filename(g_get_home_dir(), ".gdis_jobman", NULL);
jobID_string = g_strdup_printf("%d", jobID);
if (g_file_test (queuepath, G_FILE_TEST_IS_DIR))
{
// yay - it exists.
// make new directory
// grid_new_job();
//change to dir.
for (i=0; i<total_files; i++)
{
//set the range for md_fc_first, and md_fc_last
model->siesta.md_fc_first = i * model->siesta.atoms_per_job + 1;
model->siesta.md_fc_last = i * model->siesta.atoms_per_job + model->siesta.atoms_per_job;
filename = g_strdup_printf("%s.%d.%d", orig_basename, i+1, total_files);
if (model->siesta.md_fc_last >= model->num_atoms)
{
i++;
model->siesta.md_fc_last = model->num_atoms;
}
model->basename = g_strdup(filename);
filename = g_strdup_printf("%s.fdf", filename);
// call the fdf save bit....
file_save_as(filename, model);
//grab current grid_config_pak
//get job directory
siesta_make_runscript(model->basename, sysenv.cwd, grid_pak);
gui_text_show(OUTPUT, g_strdup_printf("fc-first:\t%d\tfc-last:\t%d\t\t", model->siesta.md_fc_first, model->siesta.md_fc_last));
gui_text_show(OUTPUT, model->basename);
gui_text_show(OUTPUT, "\n");
g_free(filename);
}
model->basename = g_strdup(orig_basename);
}
else
{
//no queue directory
}
}
syntax highlighted by Code2HTML, v. 0.9.1