1 /*   EXTRAITS DE LA LICENCE
2 	Copyright CEA, contributeurs : Damien CALISTE, laboratoire L_Sim, (2001-2011)
3 
4 	Adresse m�l :
5 	CALISTE, damien P caliste AT cea P fr.
6 
7 	Ce logiciel est un programme informatique servant � visualiser des
8 	structures atomiques dans un rendu pseudo-3D.
9 
10 	Ce logiciel est r�gi par la licence CeCILL soumise au droit fran�ais et
11 	respectant les principes de diffusion des logiciels libres. Vous pouvez
12 	utiliser, modifier et/ou redistribuer ce programme sous les conditions
13 	de la licence CeCILL telle que diffus�e par le CEA, le CNRS et l'INRIA
14 	sur le site "http://www.cecill.info".
15 
16 	Le fait que vous puissiez acc�der � cet en-t�te signifie que vous avez
17 	pris connaissance de la licence CeCILL, et que vous en avez accept� les
18 	termes (cf. le fichier Documentation/licence.fr.txt fourni avec ce logiciel).
19 */
20 
21 /*   LICENCE SUM UP
22 	Copyright CEA, contributors: Damien CALISTE, L_Sim laboratory, (2001-2011)
23 
24 	E-mail address:
25 	CALISTE, damien P caliste AT cea P fr.
26 
27 	This software is a computer program whose purpose is to visualize atomic
28 	configurations in 3D.
29 
30 	This software is governed by the CeCILL  license under French law and
31 	abiding by the rules of distribution of free software.  You can  use,
32 	modify and/ or redistribute the software under the terms of the CeCILL
33 	license as circulated by CEA, CNRS and INRIA at the following URL
34 	"http://www.cecill.info".
35 
36 	The fact that you are presently reading this means that you have had
37 	knowledge of the CeCILL license and that you accept its terms. You can
38 	find a copy of this licence shipped with this software at
39         Documentation/licence.en.txt.
40 */
41 
42 #include <visu_basic.h>
43 #include <visu_object.h>
44 #include <visu_configFile.h>
45 #include <visu_dataloader.h>
46 #include <visu_dataatomic.h>
47 #include <coreTools/toolMatrix.h>
48 #include <coreTools/toolPhysic.h>
49 
50 #include <extraFunctions/scalarFields.h>
51 #include <extraGtkFunctions/gtk_numericalEntryWidget.h>
52 #include <extraGtkFunctions/gtk_elementComboBox.h>
53 #include <panelModules/panelSurfaces.h>
54 #include <gtk_main.h>
55 #include <visu_gtk.h>
56 
57 #include <bigdft.h>
58 #include <string.h>
59 #include <glib/gstdio.h>
60 
61 #include <unistd.h>
62 #include <fcntl.h>
63 
64 #include <support.h>
65 #include <extraGtkFunctions/gtk_fieldChooser.h>
66 
67 #include "bigdftplug.h"
68 
69 #define BIGDFT_DESCRIPTION _("<span size=\"smaller\">"			\
70 			   "This plug-in adds support for specific\n"   \
71                            "capabilities of BigDFT.</span>")
72 #define BIGDFT_AUTHORS     "Caliste Damien"
73 
74 #define FLAG_PARAMETER_BIGDFT "bigdft_use_parser"
75 #define DESC_PARAMETER_BIGDFT "Use or not the BigDFT parser for known files ; a boolean (0 or 1)"
76 
77 static gboolean bigdftDensityLoad(VisuScalarFieldMethod *meth, const gchar *filename,
78                                   GList **fieldList, GError **error);
79 static gboolean bigdftTestWaveFile(const gchar *filename);
80 
81 extern void FC_FUNC_(memocc_report, MEMOCC_REPORT)();
82 
83 
84 /* Local variables */
85 static gchar *iconPath;
86 static VisuScalarFieldMethod *fmtBigDFT;
87 static VisuDataLoader *wvlLoader = NULL;
88 static gboolean isPanelInitialised;
89 static gboolean useCGrid, useFGrid, useLoadWithGrid;
90 static GtkWidget *lblCGrid, *lblFGrid;
91 static GtkTextBuffer *bufMemory;
92 static GtkWidget *entryHgrid[3], *entryCrmult, *entryFrmult, *entryIxc;
93 static GtkWidget *entryRadius[2], *cbRadEle[2];
94 enum
95   {
96     RADII_VALUE_FILE,
97     RADII_VALUE_COMPUTED,
98     RADII_VALUE_EDITED
99   };
100 static gchar *radiiIcons[3] = {GTK_STOCK_FILE, GTK_STOCK_EXECUTE, GTK_STOCK_EDIT};
101 static gboolean disableCallbacks;
102 
103 /* Local methods. */
104 static void updateGridLabels(VisuData *dataObj);
105 static void initialisePanel(VisuUiPanel *panel);
106 static gboolean loadBigDFTIn(VisuDataLoader *self, const gchar* filename,
107                              VisuData *data, guint nSet,
108                              GCancellable *cancel, GError **error);
109 static void update_memory_estimation(VisuData *data);
110 static int redirect_init(int out_pipe[2]);
111 static void redirect_dump(int out_pipe[2], int stdout_fileno_old);
112 static void exportParameters(GString *data, VisuData *dataObj);
113 
114 /* Callbacks. */
115 static gboolean onFieldChooserHook(GSignalInvocationHint *ihint, guint nvalues,
116                                    const GValue *param_values, gpointer data);
117 static void onBand(GtkSpinButton *spin, gpointer data);
118 static void onKpt(GtkSpinButton *spin, gpointer data);
119 static void onSpin(GtkComboBox *combo, gpointer data);
120 static void onSpinor(GtkComboBox *combo, gpointer data);
121 static void onDataNew(GObject *obj, VisuData *dataObj, gpointer data);
122 static void onDataReady(GObject *obj, VisuData *dataObj, gpointer data);
123 static void onFilesChanged(VisuData *dataObj, guint kind, gpointer data);
124 static void onPanelEnter(VisuUiPanel *panel, gpointer data);
125 static void onToggleGrid(GtkToggleButton *toggle, gpointer data);
126 static void onToggleLoad(GtkToggleButton *toggle, gpointer data);
127 static void onHgrid(VisuUiNumericalEntry *entry, gdouble old_value, gpointer data);
128 static void onRmult(VisuUiNumericalEntry *entry, gdouble old_value, gpointer data);
129 static void onRadius(VisuUiNumericalEntry *entry, gdouble old_value, gpointer data);
130 static void onIxc(VisuUiNumericalEntry *entry, gdouble old_value, gpointer data);
131 static void onEleChanged(GtkComboBox *combo, gpointer data);
132 static void onNproc(GtkSpinButton *spin, gpointer data);
133 
134 /* Includes. */
135 GtkWidget* bdft_run_tab(guint nEle, BigDFT_Wf *wf);
136 void bdft_run_init();
137 GtkWidget* bdft_system_tab(BigDFT_Lzd *lzd);
138 void bdft_system_init();
139 
bigdftplugInit()140 gboolean bigdftplugInit()
141 {
142   const gchar *typeBigDFT[] = {"*.etsf", "wavefunction-*", "minBasis-*", (char*)0};
143   const gchar *typeWvl[] = {"*.xyz", "*.ascii", "*.yaml", (char*)0};
144   VisuConfigFileEntry *resourceEntry;
145 
146   fmtBigDFT = visu_scalar_field_method_new(_("Wavefunction file from BigDFT"), typeBigDFT,
147                                            bigdftDensityLoad, G_PRIORITY_HIGH - 4);
148   tool_file_format_setValidator(TOOL_FILE_FORMAT(fmtBigDFT), bigdftTestWaveFile);
149 
150   wvlLoader = visu_data_loader_new(_("BigDFT wavelet boxes"), typeWvl,
151                                     FALSE, loadBigDFTIn, 22);
152   visu_data_atomic_class_addLoader(wvlLoader);
153   tool_file_format_addPropertyDouble(fmtWvl, "hx", _("Hgrid along x"), 0.45);
154   tool_file_format_addPropertyDouble(fmtWvl, "hy", _("Hgrid along y"), 0.45);
155   tool_file_format_addPropertyDouble(fmtWvl, "hz", _("Hgrid along z"), 0.45);
156   tool_file_format_addPropertyDouble(fmtWvl, "crmult", _("Coarse grid multiplier"), 5.);
157   tool_file_format_addPropertyDouble(fmtWvl, "frmult", _("Fine grid multiplier"), 8.);
158   tool_file_format_addPropertyInt(fmtWvl, "ixc", _("Exchange-correlation functional code"), 1);
159   tool_file_format_addPropertyInt(fmtWvl, "nproc", _("Number of processors for memory estimation"), 1);
160 
161   iconPath = g_build_filename(V_SIM_PIXMAPS_DIR, "bigdft.png", NULL);
162 
163   useCGrid = FALSE;
164   useFGrid = FALSE;
165   useLoadWithGrid = FALSE;
166   disableCallbacks = FALSE;
167 
168   lblCGrid = (GtkWidget*)0;
169   lblFGrid = (GtkWidget*)0;
170   entryHgrid[0] = (GtkWidget*)0;
171   entryHgrid[1] = (GtkWidget*)0;
172   entryHgrid[2] = (GtkWidget*)0;
173   entryCrmult = (GtkWidget*)0;
174   entryFrmult = (GtkWidget*)0;
175   entryRadius[0] = (GtkWidget*)0;
176   entryRadius[1] = (GtkWidget*)0;
177   cbRadEle[0] = (GtkWidget*)0;
178   cbRadEle[1] = (GtkWidget*)0;
179   entryIxc = (GtkWidget*)0;
180   bufMemory = gtk_text_buffer_new((GtkTextTagTable*)0);
181   gtk_text_buffer_create_tag(bufMemory, "typewriter", "family", "monospace",
182                              "scale", PANGO_SCALE_SMALL, NULL);
183   isPanelInitialised = FALSE;
184 
185   g_signal_connect(VISU_OBJECT_INSTANCE, "dataNew",
186                    G_CALLBACK(onDataNew), NULL);
187   g_signal_connect(VISU_OBJECT_INSTANCE, "dataRendered",
188                    G_CALLBACK(onDataReady), NULL);
189   bdft_run_init();
190   bdft_system_init();
191 
192   visu_config_file_addKnownTag("bigdft");
193   resourceEntry = visu_config_file_addBooleanEntry(VISU_CONFIG_FILE_PARAMETER,
194                                                    FLAG_PARAMETER_BIGDFT,
195                                                    DESC_PARAMETER_BIGDFT,
196                                                    &useLoadWithGrid, FALSE);
197   visu_config_file_entry_setVersion(resourceEntry, 3.7f);
198   visu_config_file_addExportFunction(VISU_CONFIG_FILE_PARAMETER,
199                                      exportParameters);
200 
201   return TRUE;
202 }
bigdftplugInitGtk()203 gboolean bigdftplugInitGtk()
204 {
205   DBG_fprintf(stderr, "BigDFT: init Gtk stuff.\n");
206 
207   panelBigDFT = visu_ui_panel_newWithIconFromPath("Panel_BigDFT", _("BigDFT settings"),
208                                               "BigDFT", "stock-bigdft_20.png");
209   visu_ui_panel_setDockable(VISU_UI_PANEL(panelBigDFT), TRUE);
210   visu_ui_panel_attach(VISU_UI_PANEL(panelBigDFT), visu_ui_panel_class_getCommandPanel());
211   g_signal_connect(G_OBJECT(panelBigDFT), "page-entered",
212 		   G_CALLBACK(onPanelEnter), (gpointer)0);
213 
214   g_signal_add_emission_hook(g_signal_lookup("validate", VISU_TYPE_UI_FIELD_CHOOSER),
215                              0, onFieldChooserHook, (gpointer)0, (GDestroyNotify)0);
216 
217   return TRUE;
218 }
219 
bigdftplugGet_description()220 const char* bigdftplugGet_description()
221 {
222   return BIGDFT_DESCRIPTION;
223 }
224 
bigdftplugGet_authors()225 const char* bigdftplugGet_authors()
226 {
227   return BIGDFT_AUTHORS;
228 }
229 
bigdftplugGet_icon()230 const char* bigdftplugGet_icon()
231 {
232   return iconPath;
233 }
234 
bigdftTestWaveFile(const gchar * filename)235 static gboolean bigdftTestWaveFile(const gchar *filename)
236 {
237   g_return_val_if_fail(filename, FALSE);
238 
239   return bigdft_read_wave_descr(filename, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
240 }
241 
initialisePanel(VisuUiPanel * panel)242 static void initialisePanel(VisuUiPanel *panel)
243 {
244   GtkWidget *vbox, *hbox, *wd, *ct, *vbox2, *ntbk;
245   VisuData *dataObj;
246   GArray *radii;
247   guint *radiiStatus;
248   guint nEle;
249   BigDFT_Wf *wf;
250 
251   g_return_if_fail(!isPanelInitialised);
252 
253   dataObj = visu_ui_panel_getData(panel);
254   if (dataObj)
255     {
256       radii = (GArray*)g_object_get_data(G_OBJECT(dataObj), "BigDFT_radii");
257       radiiStatus = (guint*)g_object_get_data(G_OBJECT(dataObj), "BigDFT_radiiStatus");
258       nEle = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(dataObj), "BigDFT_ntypes"));
259       wf = (BigDFT_Wf*)g_object_get_data(G_OBJECT(dataObj), "BigDFT_wf");
260     }
261   else
262     {
263       radii = (GArray*)0;
264       radiiStatus = (guint*)0;
265       nEle = 0;
266       wf = (BigDFT_Wf*)0;
267     }
268 
269   vbox = gtk_vbox_new(FALSE, 0);
270   gtk_container_add(GTK_CONTAINER(panel), vbox);
271 
272   wd = gtk_label_new(_("<b>BigDFT specific parameters</b>"));
273   gtk_label_set_use_markup(GTK_LABEL(wd), TRUE);
274   gtk_misc_set_alignment(GTK_MISC(wd), 0., 0.5);
275   gtk_widget_set_name(wd, "label_head");
276   gtk_box_pack_start(GTK_BOX(vbox), wd, FALSE, FALSE, 0);
277 
278   hbox = gtk_hbox_new(FALSE, 5);
279   gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 3);
280   wd = gtk_check_button_new_with_mnemonic(_("use BigDFT to load xyz and ASCII files"));
281   gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(wd), useLoadWithGrid);
282   g_signal_connect(G_OBJECT(wd), "toggled",
283                    G_CALLBACK(onToggleLoad), GINT_TO_POINTER(0));
284   gtk_box_pack_start(GTK_BOX(hbox), wd, TRUE, TRUE, 0);
285 
286   /* Hgrid and ixc line. */
287   hbox = gtk_hbox_new(FALSE, 2);
288   gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
289   wd = gtk_label_new(_("hgrids:"));
290   gtk_misc_set_alignment(GTK_MISC(wd), 1., 0.5);
291   gtk_box_pack_start(GTK_BOX(hbox), wd, TRUE, TRUE, 0);
292   entryHgrid[0] = visu_ui_numerical_entry_new(GET_OPT_DBL(fmtWvl, "hx"));
293   gtk_entry_set_width_chars(GTK_ENTRY(entryHgrid[0]), 8);
294   g_signal_connect(G_OBJECT(entryHgrid[0]), "value-changed",
295 		   G_CALLBACK(onHgrid), GINT_TO_POINTER(0));
296   gtk_box_pack_start(GTK_BOX(hbox), entryHgrid[0], FALSE, FALSE, 0);
297   entryHgrid[1] = visu_ui_numerical_entry_new(GET_OPT_DBL(fmtWvl, "hy"));
298   gtk_entry_set_width_chars(GTK_ENTRY(entryHgrid[1]), 8);
299   g_signal_connect(G_OBJECT(entryHgrid[1]), "value-changed",
300 		   G_CALLBACK(onHgrid), GINT_TO_POINTER(1));
301   gtk_box_pack_start(GTK_BOX(hbox), entryHgrid[1], FALSE, FALSE, 0);
302   entryHgrid[2] = visu_ui_numerical_entry_new(GET_OPT_DBL(fmtWvl, "hz"));
303   gtk_entry_set_width_chars(GTK_ENTRY(entryHgrid[2]), 8);
304   g_signal_connect(G_OBJECT(entryHgrid[2]), "value-changed",
305 		   G_CALLBACK(onHgrid), GINT_TO_POINTER(2));
306   gtk_box_pack_start(GTK_BOX(hbox), entryHgrid[2], FALSE, FALSE, 0);
307   wd = gtk_label_new(_("ixc:"));
308   gtk_misc_set_alignment(GTK_MISC(wd), 1., 0.5);
309   gtk_box_pack_start(GTK_BOX(hbox), wd, TRUE, TRUE, 0);
310   entryIxc = visu_ui_numerical_entry_new(GET_OPT_INT(fmtWvl, "ixc"));
311   gtk_entry_set_width_chars(GTK_ENTRY(entryIxc), 6);
312   g_signal_connect(G_OBJECT(entryIxc), "value-changed",
313 		   G_CALLBACK(onIxc), (gpointer)0);
314   gtk_box_pack_start(GTK_BOX(hbox), entryIxc, FALSE, FALSE, 0);
315 
316   /* The coarse grid parameters. */
317   hbox = gtk_hbox_new(FALSE, 5);
318   gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
319   wd = gtk_check_button_new_with_mnemonic(_("show _coarse grid"));
320   gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(wd), useCGrid);
321   g_signal_connect(G_OBJECT(wd), "toggled",
322                    G_CALLBACK(onToggleGrid), GINT_TO_POINTER(0));
323   gtk_box_pack_start(GTK_BOX(hbox), wd, TRUE, TRUE, 0);
324   lblCGrid = gtk_label_new("");
325   gtk_box_pack_end(GTK_BOX(hbox), lblCGrid, FALSE, FALSE, 0);
326   hbox = gtk_hbox_new(FALSE, 5);
327   gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
328   wd = gtk_label_new(_("radius of ele."));
329   gtk_misc_set_alignment(GTK_MISC(wd), 1., 0.5);
330   gtk_box_pack_start(GTK_BOX(hbox), wd, TRUE, TRUE, 0);
331   cbRadEle[0] = visu_ui_element_combobox_new(FALSE, FALSE, (const gchar*)0);
332   g_signal_connect(G_OBJECT(cbRadEle[0]), "changed",
333                    G_CALLBACK(onEleChanged), GINT_TO_POINTER(0));
334   gtk_box_pack_start(GTK_BOX(hbox), cbRadEle[0], FALSE, FALSE, 0);
335   if (radii && radiiStatus)
336     {
337       entryRadius[0] = visu_ui_numerical_entry_new(g_array_index(radii, double, 0));
338       gtk_entry_set_icon_from_stock(GTK_ENTRY(entryRadius[0]), GTK_ENTRY_ICON_SECONDARY,
339                                     radiiIcons[radiiStatus[0]]);
340     }
341   else
342     entryRadius[0] = visu_ui_numerical_entry_new(-1.);
343   gtk_entry_set_width_chars(GTK_ENTRY(entryRadius[0]), 10);
344   g_signal_connect(G_OBJECT(entryRadius[0]), "value-changed",
345 		   G_CALLBACK(onRadius), GINT_TO_POINTER(0));
346   gtk_box_pack_start(GTK_BOX(hbox), entryRadius[0], FALSE, FALSE, 0);
347   wd = gtk_label_new("\303\227 (crmult:");
348   gtk_box_pack_start(GTK_BOX(hbox), wd, FALSE, FALSE, 0);
349   entryCrmult = visu_ui_numerical_entry_new(GET_OPT_DBL(fmtWvl, "crmult"));
350   gtk_entry_set_width_chars(GTK_ENTRY(entryCrmult), 3);
351   g_signal_connect(G_OBJECT(entryCrmult), "value-changed",
352 		   G_CALLBACK(onRmult), GINT_TO_POINTER(0));
353   gtk_box_pack_start(GTK_BOX(hbox), entryCrmult, FALSE, FALSE, 0);
354   wd = gtk_label_new(")");
355   gtk_box_pack_start(GTK_BOX(hbox), wd, FALSE, FALSE, 0);
356 
357   /* The fine grid parameters. */
358   hbox = gtk_hbox_new(FALSE, 5);
359   gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
360   wd = gtk_check_button_new_with_mnemonic(_("show _fine grid"));
361   gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(wd), useFGrid);
362   g_signal_connect(G_OBJECT(wd), "toggled",
363                    G_CALLBACK(onToggleGrid), GINT_TO_POINTER(1));
364   gtk_box_pack_start(GTK_BOX(hbox), wd, TRUE, TRUE, 0);
365   lblFGrid = gtk_label_new("");
366   gtk_box_pack_end(GTK_BOX(hbox), lblFGrid, FALSE, FALSE, 0);
367   updateGridLabels(visu_ui_panel_getData(panel));
368   hbox = gtk_hbox_new(FALSE, 5);
369   gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
370   wd = gtk_label_new(_("radius of ele."));
371   gtk_misc_set_alignment(GTK_MISC(wd), 1., 0.5);
372   gtk_box_pack_start(GTK_BOX(hbox), wd, TRUE, TRUE, 0);
373   cbRadEle[1] = visu_ui_element_combobox_new(FALSE, FALSE, (const gchar*)0);
374   g_signal_connect(G_OBJECT(cbRadEle[1]), "changed",
375                    G_CALLBACK(onEleChanged), GINT_TO_POINTER(1));
376   gtk_box_pack_start(GTK_BOX(hbox), cbRadEle[1], FALSE, FALSE, 0);
377   if (radii && radiiStatus)
378     {
379       entryRadius[1] = visu_ui_numerical_entry_new(g_array_index(radii, double, nEle));
380       gtk_entry_set_icon_from_stock(GTK_ENTRY(entryRadius[1]), GTK_ENTRY_ICON_SECONDARY,
381                                     radiiIcons[radiiStatus[nEle]]);
382     }
383   else
384     entryRadius[1] = visu_ui_numerical_entry_new(-1.);
385   gtk_entry_set_width_chars(GTK_ENTRY(entryRadius[1]), 10);
386   g_signal_connect(G_OBJECT(entryRadius[1]), "value-changed",
387 		   G_CALLBACK(onRadius), GINT_TO_POINTER(1));
388   gtk_box_pack_start(GTK_BOX(hbox), entryRadius[1], FALSE, FALSE, 0);
389   wd = gtk_label_new("\303\227 (frmult:");
390   gtk_box_pack_start(GTK_BOX(hbox), wd, FALSE, FALSE, 0);
391   entryFrmult = visu_ui_numerical_entry_new(GET_OPT_DBL(fmtWvl, "frmult"));
392   gtk_entry_set_width_chars(GTK_ENTRY(entryFrmult), 3);
393   g_signal_connect(G_OBJECT(entryFrmult), "value-changed",
394 		   G_CALLBACK(onRmult), GINT_TO_POINTER(1));
395   gtk_box_pack_start(GTK_BOX(hbox), entryFrmult, FALSE, FALSE, 0);
396   wd = gtk_label_new(")");
397   gtk_box_pack_start(GTK_BOX(hbox), wd, FALSE, FALSE, 0);
398 
399   wd = gtk_label_new("<span size=\"smaller\">Powered by BigDFT "
400                      BIGDFT_STRING_VERSION "</span>");
401   gtk_misc_set_alignment(GTK_MISC(wd), 1., 0.5);
402   gtk_label_set_use_markup(GTK_LABEL(wd), TRUE);
403   gtk_box_pack_end(GTK_BOX(vbox), wd, FALSE, FALSE, 0);
404 
405   /* The BigDFT tab. */
406   ntbk = gtk_notebook_new();
407   gtk_box_pack_start(GTK_BOX(vbox), ntbk, TRUE, TRUE, 0);
408 
409   /* The memory estimation. */
410   vbox2 = gtk_vbox_new(FALSE, 2);
411   gtk_notebook_append_page(GTK_NOTEBOOK(ntbk), vbox2,
412                            gtk_label_new(_("Memory estimation")));
413   hbox = gtk_hbox_new(FALSE, 2);
414   gtk_box_pack_start(GTK_BOX(vbox2), hbox, FALSE, FALSE, 0);
415   wd = gtk_label_new(_("Memory estimation for"));
416   gtk_misc_set_alignment(GTK_MISC(wd), 0., 0.5);
417   gtk_box_pack_start(GTK_BOX(hbox), wd, TRUE, TRUE, 0);
418   wd = gtk_spin_button_new_with_range(1, 4096, 1);
419   g_signal_connect(G_OBJECT(wd), "value-changed",
420 		   G_CALLBACK(onNproc), (gpointer)0);
421   gtk_box_pack_start(GTK_BOX(hbox), wd, FALSE, FALSE, 0);
422   wd = gtk_label_new(_("core(s)"));
423   gtk_box_pack_start(GTK_BOX(hbox), wd, FALSE, FALSE, 0);
424   ct = gtk_scrolled_window_new((GtkAdjustment*)0, (GtkAdjustment*)0);
425   gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(ct),
426                                  GTK_POLICY_AUTOMATIC, GTK_POLICY_NEVER);
427   gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(ct),
428 				      GTK_SHADOW_ETCHED_IN);
429   gtk_box_pack_start(GTK_BOX(vbox2), ct, TRUE, TRUE, 0);
430   wd = gtk_text_view_new_with_buffer(bufMemory);
431   gtk_text_view_set_editable(GTK_TEXT_VIEW(wd), FALSE);
432   gtk_text_view_set_cursor_visible(GTK_TEXT_VIEW(wd), FALSE);
433   gtk_container_add(GTK_CONTAINER(ct), wd);
434 
435   /* The system tab. */
436   vbox2 = bdft_system_tab((wf)?wf->lzd:NULL);
437   gtk_notebook_append_page(GTK_NOTEBOOK(ntbk), vbox2,
438                            gtk_label_new(_("Basis set")));
439 
440   /* The run tab. */
441   vbox2 = bdft_run_tab(nEle, wf);
442   gtk_notebook_append_page(GTK_NOTEBOOK(ntbk), vbox2,
443                            gtk_label_new(_("Running BigDFT")));
444 
445   gtk_widget_show_all(vbox);
446 
447   isPanelInitialised = TRUE;
448 }
onPanelEnter(VisuUiPanel * panel,gpointer data _U_)449 static void onPanelEnter(VisuUiPanel *panel, gpointer data _U_)
450 {
451   DBG_fprintf(stderr, "Panel BigDFT: caught the 'page-entered' signal %d.\n",
452 	      isPanelInitialised);
453   if (!isPanelInitialised)
454     initialisePanel(panel);
455 }
loadGrids(gpointer data)456 static gboolean loadGrids(gpointer data)
457 {
458   VisuData *dataObj;
459   VisuGlView *view;
460   GArray *grid;
461   const gchar *gridNames[] = {"BigDFT_coarse_grid", "BigDFT_fine_grid"};
462   const gchar *eleNames[] = {"g", "G"};
463   guint iGrid = GPOINTER_TO_INT(data);
464   gboolean* usage[] = {&useCGrid, &useFGrid};
465 
466   dataObj = visu_ui_panel_getData(VISU_UI_PANEL(panelBigDFT));
467   view = visu_ui_panel_getView(VISU_UI_PANEL(panelBigDFT));
468   if (!dataObj || !view)
469     return FALSE;
470   DBG_fprintf(stderr, "Panel BigDFT: load grid for object %p.\n", (gpointer)dataObj);
471 
472   grid = (GArray*)g_object_get_data(G_OBJECT(dataObj), gridNames[iGrid]);
473 
474   bigdft_show_grid(dataObj, (*(usage[iGrid]))?grid:(GArray*)0, eleNames[iGrid], 0);
475 
476   VISU_REDRAW_ADD;
477 
478   return FALSE;
479 }
onToggleGrid(GtkToggleButton * toggle,gpointer data)480 static void onToggleGrid(GtkToggleButton *toggle, gpointer data)
481 {
482   gboolean* usage[] = {&useCGrid, &useFGrid};
483   guint iGrid = GPOINTER_TO_INT(data);
484 
485   DBG_fprintf(stderr, "Panel BigDFT: toggle grid.\n");
486   *(usage[iGrid]) = gtk_toggle_button_get_active(toggle);
487 
488   g_idle_add(loadGrids, data);
489 }
490 
bigdftDensityLoad(VisuScalarFieldMethod * meth,const gchar * filename,GList ** fieldList,GError ** error)491 static gboolean bigdftDensityLoad(VisuScalarFieldMethod *meth, const gchar *filename,
492                                   GList **fieldList, GError **error)
493 {
494   int norbu, norbd, nkpt, nspinor, iorbp;
495   int iorbf, ispinf, ikptf, ispinorf;
496   int ntot, i, iorb, ispin, ikpt, ispinor;
497   guint n[3];
498   VisuScalarField *field;
499   ToolOption *opt;
500   double h[3];
501   double box[3][3];
502   double *data;
503   f90_pointer_double_4D *psiscf;
504   GArray *wrap;
505   VisuBox *boxObj;
506 
507   g_return_val_if_fail(filename, FALSE);
508   g_return_val_if_fail(*fieldList == (GList*)0, FALSE);
509   g_return_val_if_fail(error && (*error == (GError*)0), FALSE);
510 
511   DBG_fprintf(stderr, "BigDFT: test file '%s' as a BigDFT wavefunction file.\n", filename);
512   if (!bigdft_read_wave_descr(filename, &norbu, &norbd, &nkpt, &nspinor,
513                               &iorbf, &ispinf, &ikptf, &ispinorf))
514     /* The file is not a BigDFT file. */
515     return FALSE;
516 
517   /* Get orbital from option table if the file contains several. */
518   if (norbu > 0 || norbd > 0)
519     {
520       iorb = norbu;
521       ispin = 1;
522       ikpt = 1;
523       ispinorf = 0;
524       opt = tool_file_format_getPropertyByName(TOOL_FILE_FORMAT(meth), "i-band");
525       if (opt)
526         iorb = g_value_get_int(tool_option_getValue(opt));
527       opt = tool_file_format_getPropertyByName(TOOL_FILE_FORMAT(meth), "i-spin");
528       if (opt)
529         ispin = g_value_get_int(tool_option_getValue(opt));
530       opt = tool_file_format_getPropertyByName(TOOL_FILE_FORMAT(meth), "i-kpt");
531       if (opt)
532         ikpt = g_value_get_int(tool_option_getValue(opt));
533       ispin   = CLAMP(ispin, 1, (norbd > 0)?2:1);
534       iorb    = CLAMP(iorb, 1, (ispin == 1)?norbu:norbd);
535       ikpt    = CLAMP(ikpt, 1, nkpt);
536     }
537   else
538     {
539       iorb = iorbf;
540       ispin = ispinf;
541       ikpt = ikptf;
542     }
543   /* Build the iorbp value from this. */
544   iorbp = (ikpt - 1) * (norbu + norbd) + (ispin - 1) * norbu + iorb;
545   /* Special treatment for i-complex. */
546   opt = tool_file_format_getPropertyByName(TOOL_FILE_FORMAT(meth), "i-complex");
547   if (opt)
548     ispinor = g_value_get_int(tool_option_getValue(opt));
549   else
550     ispinor = ispinorf;
551   ispinor = CLAMP(ispinor, 0, nspinor);
552 
553   /* We read the wavefunction. */
554   psiscf = bigdft_read_wave_to_isf(filename, iorbp, h, (int*)n, &nspinor);
555   if (!psiscf)
556     {
557       g_set_error(error, TOOL_FILE_FORMAT_ERROR, TOOL_FILE_FORMAT_ERROR_FORMAT,
558                   _("Can't read wavefunction %d from file '%s'."), iorbp, filename);
559       return TRUE;
560     }
561   /* Choose the real, imag or partial density values. */
562   ntot = n[0] * n[1] * n[2];
563   if (ispinor == 0)
564     {
565       data = g_malloc(sizeof(double) * ntot);
566       for (i = 0; i < ntot; i++)
567         data[i] = psiscf->data[i] * psiscf->data[i];
568       if (nspinor == 2)
569         for (i = 0; i < ntot; i++)
570           data[i] += psiscf->data[i + ntot] * psiscf->data[i + ntot];
571     }
572   else if (ispinor == 2 && nspinor == 2)
573     data = psiscf->data + ntot;
574   else
575     data = psiscf->data;
576 
577   /* Create the scalar field. */
578   field = visu_scalar_field_new(filename);
579   if (!field)
580     g_warning("impossible to create a VisuScalarField object.");
581   else
582     {
583       memset(box, 0, sizeof(double) * 9);
584       box[0][0] = h[0] * n[0];
585       box[1][1] = h[1] * n[1];
586       box[2][2] = h[2] * n[2];
587       boxObj = visu_box_new_full(box, VISU_BOX_PERIODIC);
588       visu_boxed_setBox(VISU_BOXED(field), VISU_BOXED(boxObj));
589       g_object_unref(boxObj);
590       visu_scalar_field_setGridSize(field, n);
591       DBG_fprintf(stderr, "BigDFT: transfer density into field object.\n");
592       wrap = g_array_new(FALSE, FALSE, sizeof(double));
593       wrap->data = (gchar*)data;
594       wrap->len = ntot;
595       visu_scalar_field_setData(field, wrap, TRUE);
596       g_array_free(wrap, FALSE);
597       /* Add options to the field. */
598       opt = tool_option_new("i-band", _("orbital id"), G_TYPE_INT);
599       g_value_set_int(tool_option_getValue(opt), iorb);
600       visu_scalar_field_addOption(field, opt);
601       opt = tool_option_new("i-spin", _("spin id"), G_TYPE_STRING);
602       if (ispin == 2)
603         g_value_set_string(tool_option_getValue(opt), "down");
604       else if (ispin == 1 && norbd > 0)
605         g_value_set_string(tool_option_getValue(opt), "up");
606       else
607         g_value_set_string(tool_option_getValue(opt), "none");
608       visu_scalar_field_addOption(field, opt);
609       opt = tool_option_new("i-kpt", _("k-point id"), G_TYPE_INT);
610       g_value_set_int(tool_option_getValue(opt), ikpt);
611       visu_scalar_field_addOption(field, opt);
612       opt = tool_option_new("i-complex", _("real/imag or partial density"), G_TYPE_STRING);
613       if (ispinor == 2)
614         g_value_set_string(tool_option_getValue(opt), "imag");
615       else if (ispinor == 1)
616         g_value_set_string(tool_option_getValue(opt), "real");
617       else
618         g_value_set_string(tool_option_getValue(opt), "partial density");
619       visu_scalar_field_addOption(field, opt);
620       *fieldList = g_list_append(*fieldList, (gpointer)field);
621     }
622 
623   if (ispinor == 0)
624     g_free(data);
625 
626   bigdft_free_wave_to_isf(psiscf);
627 
628   *error = (GError*)0;
629   return TRUE;
630 }
631 
onFieldChooserHook(GSignalInvocationHint * ihint _U_,guint nvalues _U_,const GValue * param_values,gpointer data _U_)632 static gboolean onFieldChooserHook(GSignalInvocationHint *ihint _U_, guint nvalues _U_,
633                                    const GValue *param_values, gpointer data _U_)
634 {
635   GtkWidget *hbox, *lbl, *sp, *cb;
636   int norbu, norbd, nkpt, nspinor;
637   int iorbf, ispinf, ikptf, ispinorf;
638   gchar *filename;
639 
640   if (g_value_get_object(param_values + 1) != G_OBJECT(fmtBigDFT))
641     return FALSE;
642   DBG_fprintf(stderr, "BigDFT: hook on wavefunction selection.\n");
643   filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(g_value_get_object(param_values)));
644   if (!bigdft_read_wave_descr(filename, &norbu, &norbd, &nkpt, &nspinor,
645                               &iorbf, &ispinf, &ikptf, &ispinorf))
646     {
647       g_warning("Can't read file '%s'.", filename);
648       g_free(filename);
649       return TRUE;
650     }
651   g_free(filename);
652 
653   /* Build the widgets. */
654   hbox = gtk_hbox_new(FALSE, 0);
655   lbl = gtk_label_new(_("Choose orbital:"));
656   gtk_misc_set_alignment(GTK_MISC(lbl), 0., 0.5);
657   gtk_box_pack_start(GTK_BOX(hbox), lbl, TRUE, TRUE, 0);
658 
659   lbl = gtk_label_new(_("band id:"));
660   gtk_box_pack_start(GTK_BOX(hbox), lbl, TRUE, TRUE, 0);
661   gtk_misc_set_alignment(GTK_MISC(lbl), 1., 0.5);
662   if (norbu > 0)
663     sp = gtk_spin_button_new_with_range(1, norbu, 1);
664   else
665     sp = gtk_spin_button_new_with_range(iorbf, iorbf, 1);
666   g_signal_connect(G_OBJECT(sp), "value-changed",
667                    G_CALLBACK(onBand), (gpointer)0);
668   gtk_box_pack_start(GTK_BOX(hbox), sp, FALSE, FALSE, 0);
669 
670   lbl = gtk_label_new(_("spin:"));
671   gtk_misc_set_alignment(GTK_MISC(lbl), 1., 0.5);
672   gtk_box_pack_start(GTK_BOX(hbox), lbl, TRUE, TRUE, 0);
673   cb = gtk_combo_box_text_new();
674   if ((norbu > 0 || norbd > 0) && norbu == norbd)
675     gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(cb), _("none"));
676   else
677     {
678       gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(cb), _("up"));
679       gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(cb), _("down"));
680     }
681   gtk_combo_box_set_active(GTK_COMBO_BOX(cb), ispinf - 1);
682   g_signal_connect(G_OBJECT(cb), "changed",
683                    G_CALLBACK(onSpin), (gpointer)sp);
684   g_object_set_data(G_OBJECT(cb), "norbu", GINT_TO_POINTER(norbu));
685   g_object_set_data(G_OBJECT(cb), "norbd", GINT_TO_POINTER(norbd));
686   gtk_box_pack_start(GTK_BOX(hbox), cb, FALSE, FALSE, 0);
687 
688   lbl = gtk_label_new(_("k-point:"));
689   gtk_misc_set_alignment(GTK_MISC(lbl), 1., 0.5);
690   gtk_box_pack_start(GTK_BOX(hbox), lbl, TRUE, TRUE, 0);
691   if (nkpt > 0)
692     sp = gtk_spin_button_new_with_range(1, nkpt, 1);
693   else
694     sp = gtk_spin_button_new_with_range(ikptf, ikptf, 1);
695   g_signal_connect(G_OBJECT(sp), "value-changed",
696                    G_CALLBACK(onKpt), (gpointer)0);
697   gtk_box_pack_start(GTK_BOX(hbox), sp, FALSE, FALSE, 0);
698 
699   lbl = gtk_label_new(_("representation:"));
700   gtk_misc_set_alignment(GTK_MISC(lbl), 1., 0.5);
701   gtk_box_pack_start(GTK_BOX(hbox), lbl, TRUE, TRUE, 0);
702   cb = gtk_combo_box_text_new();
703   gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(cb), _("partial density"));
704   gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(cb), _("real part"));
705   if (nspinor > 1)
706     gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(cb), _("imaginary part"));
707   g_signal_connect(G_OBJECT(cb), "changed",
708                    G_CALLBACK(onSpinor), (gpointer)0);
709   gtk_combo_box_set_active(GTK_COMBO_BOX(cb), ispinorf);
710   gtk_box_pack_start(GTK_BOX(hbox), cb, FALSE, FALSE, 0);
711 
712   visu_ui_field_chooser_setOptions(VISU_UI_FIELD_CHOOSER(g_value_get_object(param_values)),
713                                    hbox);
714 
715   return TRUE;
716 }
onBand(GtkSpinButton * spin,gpointer data _U_)717 static void onBand(GtkSpinButton *spin, gpointer data _U_)
718 {
719   tool_file_format_addPropertyInt(TOOL_FILE_FORMAT(fmtBigDFT), "i-band",
720                                   _("orbital id"), (int)gtk_spin_button_get_value(spin));
721 }
onKpt(GtkSpinButton * spin,gpointer data _U_)722 static void onKpt(GtkSpinButton *spin, gpointer data _U_)
723 {
724   tool_file_format_addPropertyInt(TOOL_FILE_FORMAT(fmtBigDFT), "i-kpt",
725                                   _("k-point id"), (int)gtk_spin_button_get_value(spin));
726 }
onSpin(GtkComboBox * combo,gpointer data)727 static void onSpin(GtkComboBox *combo, gpointer data)
728 {
729   gint ispin;
730 
731   ispin = gtk_combo_box_get_active(combo) + 1;
732   tool_file_format_addPropertyInt(TOOL_FILE_FORMAT(fmtBigDFT), "i-spin",
733                                   _("spin id"), ispin);
734 
735   if (ispin == 1)
736     gtk_spin_button_set_range(GTK_SPIN_BUTTON(data), 1,
737                               GPOINTER_TO_INT(g_object_get_data(G_OBJECT(combo), "norbu")));
738   else
739     gtk_spin_button_set_range(GTK_SPIN_BUTTON(data), 1,
740                               GPOINTER_TO_INT(g_object_get_data(G_OBJECT(combo), "norbd")));
741 }
onSpinor(GtkComboBox * combo,gpointer data _U_)742 static void onSpinor(GtkComboBox *combo, gpointer data _U_)
743 {
744   tool_file_format_addPropertyInt(TOOL_FILE_FORMAT(fmtBigDFT), "i-complex",
745                                   _("real/imag or partial density"),
746                                   gtk_combo_box_get_active(combo));
747 }
748 
onDataNew(GObject * obj _U_,VisuData * dataObj,gpointer data _U_)749 static void onDataNew(GObject *obj _U_, VisuData *dataObj, gpointer data _U_)
750 {
751   g_signal_connect(G_OBJECT(dataObj), "FilesChanged",
752                    G_CALLBACK(onFilesChanged), (gpointer)0);
753 }
onDataReady(GObject * obj _U_,VisuData * dataObj,gpointer data _U_)754 static void onDataReady(GObject *obj _U_, VisuData *dataObj, gpointer data _U_)
755 {
756   GArray *radii;
757   guint *radiiStatus;
758   guint nEle;
759   gint iEle;
760   BigDFT_Wf *wf;
761   BigDFT_Inputs *in;
762 
763   DBG_fprintf(stderr, "Panel BigDFT: caught 'dataRendered' signal.\n");
764   if (isPanelInitialised)
765     {
766       updateGridLabels(dataObj);
767 
768       if (dataObj)
769         {
770           radii = (GArray*)g_object_get_data(G_OBJECT(dataObj), "BigDFT_radii");
771           radiiStatus = (guint*)g_object_get_data(G_OBJECT(dataObj), "BigDFT_radiiStatus");
772         }
773       else
774         {
775           radii = (GArray*)0;
776           radiiStatus = (guint*)0;
777         }
778       disableCallbacks = TRUE;
779       visu_ui_numerical_entry_setValue(VISU_UI_NUMERICAL_ENTRY(entryHgrid[0]), GET_OPT_DBL(fmtWvl, "hx"));
780       visu_ui_numerical_entry_setValue(VISU_UI_NUMERICAL_ENTRY(entryHgrid[1]), GET_OPT_DBL(fmtWvl, "hy"));
781       visu_ui_numerical_entry_setValue(VISU_UI_NUMERICAL_ENTRY(entryHgrid[2]), GET_OPT_DBL(fmtWvl, "hz"));
782       visu_ui_numerical_entry_setValue(VISU_UI_NUMERICAL_ENTRY(entryCrmult), GET_OPT_DBL(fmtWvl, "crmult"));
783       visu_ui_numerical_entry_setValue(VISU_UI_NUMERICAL_ENTRY(entryFrmult), GET_OPT_DBL(fmtWvl, "frmult"));
784       visu_ui_numerical_entry_setValue(VISU_UI_NUMERICAL_ENTRY(entryIxc), GET_OPT_INT(fmtWvl, "ixc"));
785       if (radii && radiiStatus)
786         {
787           nEle = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(dataObj), "BigDFT_ntypes"));
788           DBG_fprintf(stderr, "Panel BigDFT: setup radius combo for %d elements.\n", nEle);
789           iEle = gtk_combo_box_get_active(GTK_COMBO_BOX(cbRadEle[0]));
790           DBG_fprintf(stderr, " | %d element (coarse).\n", iEle);
791           if (iEle >= 0)
792             {
793               visu_ui_numerical_entry_setValue(VISU_UI_NUMERICAL_ENTRY(entryRadius[0]),
794                                                g_array_index(radii, double, iEle));
795               gtk_entry_set_icon_from_stock(GTK_ENTRY(entryRadius[0]),
796                                             GTK_ENTRY_ICON_SECONDARY,
797                                             radiiIcons[radiiStatus[iEle]]);
798             }
799           iEle = gtk_combo_box_get_active(GTK_COMBO_BOX(cbRadEle[1]));
800           DBG_fprintf(stderr, " | %d element (fine).\n", iEle);
801           if (iEle >= 0)
802             {
803               visu_ui_numerical_entry_setValue(VISU_UI_NUMERICAL_ENTRY(entryRadius[1]),
804                                                g_array_index(radii, double, nEle + iEle));
805               gtk_entry_set_icon_from_stock(GTK_ENTRY(entryRadius[1]),
806                                             GTK_ENTRY_ICON_SECONDARY,
807                                             radiiIcons[radiiStatus[nEle + iEle]]);
808             }
809         }
810       disableCallbacks = FALSE;
811     }
812 
813   if (dataObj)
814     {
815       wf = (BigDFT_Wf*)g_object_get_data(G_OBJECT(dataObj), "BigDFT_wf");
816       in = (BigDFT_Inputs*)g_object_get_data(G_OBJECT(dataObj), "BigDFT_inputs");
817       if (wf && in)
818         {
819           /* We create the orbital descriptors here already for memory
820              estimation or later run. */
821           DBG_fprintf(stderr, "Panel BigDFT: set-up Lzd.\n");
822           bigdft_wf_define(wf, in, 0, 1);
823 
824           /* We do the memory estimation for this run. */
825           DBG_fprintf(stderr, "Panel BigDFT: do memory estimation.\n");
826           update_memory_estimation(dataObj);
827         }
828     }
829 
830   DBG_fprintf(stderr, "Panel BigDFT: 'DataReady' signal OK.\n");
831 }
832 
updateGridLabels(VisuData * dataObj)833 static void updateGridLabels(VisuData *dataObj)
834 {
835   GArray *grid;
836   guint cgrid, fgrid;
837   gchar *cgridText, *fgridText;
838 
839   DBG_fprintf(stderr, "Panel BigDFT: update grid labels.\n");
840   cgrid = 0;
841   fgrid = 0;
842   if (dataObj)
843     {
844       grid = (GArray*)g_object_get_data(G_OBJECT(dataObj), "BigDFT_coarse_grid");
845       cgrid = (grid)?grid->len:0;
846       grid = (GArray*)g_object_get_data(G_OBJECT(dataObj), "BigDFT_fine_grid");
847       fgrid = (grid)?grid->len:0;
848     }
849 
850   if (cgrid)
851     cgridText = g_strdup_printf(_("%d grid points"), cgrid);
852   else
853     cgridText = g_strdup(_("no grid"));
854   gtk_label_set_text(GTK_LABEL(lblCGrid), cgridText);
855   g_free(cgridText);
856 
857   if (fgrid)
858     fgridText = g_strdup_printf(_("%d grid points"), fgrid);
859   else
860     fgridText = g_strdup(_("no grid"));
861   gtk_label_set_text(GTK_LABEL(lblFGrid), fgridText);
862   g_free(fgridText);
863 }
864 /* Grid related routines. */
bigdft_show_grid(VisuData * dataObj,GArray * grid,const gchar * gG,guint id)865 void bigdft_show_grid(VisuData *dataObj, GArray *grid, const gchar *gG, guint id)
866 {
867   VisuElement *ele;
868   guint i;
869   GArray *eleArr, *nEleArr;
870   gboolean newEle;
871   gchar *lbl;
872   float rgba_y[4] = {1.000, 0.750, 0.040, 1.000};
873   float rgba_b[4] = {0.600, 0.600, 1.000, 1.000};
874 
875   /* We check that gG is not currently used by dataObj. */
876   lbl = (id)?g_strdup_printf("%%%s_%d", gG, id):g_strdup(gG);
877   DBG_fprintf(stderr, "BigDFT: show/hide grid '%s' with %d elements on object %p.\n",
878               lbl, (grid)?grid->len:0, (gpointer)dataObj);
879   ele = visu_element_retrieveFromName(lbl, &newEle);
880   g_free(lbl);
881   if (newEle)
882     {
883       visu_rendering_atomic_setRadius(ele, (gG[0] == 'g')?0.5:1.);
884       visu_rendering_atomic_setShape(ele, VISU_RENDERING_ATOMIC_POINT);
885       if (!strcmp(gG, "g"))
886         visu_element_setAllRGBValues(ele, rgba_y);
887       else if (!strcmp(gG, "G"))
888         visu_element_setAllRGBValues(ele, rgba_b);
889       else
890         visu_element_setAllRGBValues(ele, (float*)tool_color_new_bright(id - 1)->rgba);
891     }
892 
893   /* Remove possible old gG nodes. */
894   visu_node_array_removeNodesOfElement(VISU_NODE_ARRAY(dataObj), ele);
895 
896   /* Allocate space for new gG element. */
897   if (grid && grid->len > 0)
898     {
899       eleArr  = g_array_sized_new(FALSE, FALSE, sizeof(VisuElement*), 1);
900       g_array_append_val(eleArr, ele);
901       nEleArr = g_array_sized_new(FALSE, FALSE, sizeof(guint), 1);
902       g_array_append_val(nEleArr, grid->len);
903 
904       visu_node_array_allocate(VISU_NODE_ARRAY(dataObj), eleArr, nEleArr);
905 
906       g_array_free(eleArr, TRUE);
907       g_array_free(nEleArr, TRUE);
908 
909       /* Add the coordinates. */
910       for (i = 0; i < grid->len; i++)
911         visu_data_addNodeFromElement(dataObj, ele, ((float*)grid->data) + (3 * i),
912                                      TRUE, (i == (grid->len - 1)));
913     }
914 }
915 
916 /* Structural loading. */
loadBigDFTIn(VisuDataLoader * self,const gchar * filename,VisuData * data,guint nSet _U_,GCancellable * cancel _U_,GError ** error)917 static gboolean loadBigDFTIn(VisuDataLoader *self, const gchar* filename,
918                              VisuData *data, guint nSet _U_,
919                              GCancellable *cancel _U_, GError **error)
920 {
921   BigDFT_Locreg *glr;
922   BigDFT_Atoms *atoms;
923   BigDFT_Inputs *in;
924   BigDFT_Wf *wf;
925   GArray *eles, *nEle, *gcoord_c, *gcoord_f;
926   double box[6], h[3], crmult, frmult;
927   GArray *radii;
928   guint i, j, k, grid[3], iGrid, nbGrid;
929   VisuElement *ele;
930   float xyz[3], vect[3];
931   gboolean *cgrid, *fgrid;
932   guint *radiiStatus;
933   int ixc;
934   gchar *dirname, *cwd;
935   gboolean newAt;
936   VisuBox *boxObj;
937   VisuNodeValuesString *labels;
938 
939   /* gboolean valid; */
940   /* BigDFT_LocregIter iter; */
941 
942   g_return_val_if_fail(error && *error == (GError*)0, FALSE);
943   g_return_val_if_fail(data && filename, FALSE);
944 
945   if (!useLoadWithGrid)
946     {
947       DBG_fprintf(stderr, "BigDFT: format disabled.\n");
948       return FALSE;
949     }
950 
951   /* We change the current working dir to allow BigDFT to look for
952      input files and pseudos. */
953   dirname = g_path_get_dirname(filename);
954   cwd     = g_get_current_dir();
955   g_chdir(dirname);
956   g_free(dirname);
957 
958   /* Get the input parameters. */
959   in = g_object_get_data(G_OBJECT(data), "BigDFT_inputs");
960   if (!in)
961     {
962       g_chdir(cwd);
963       g_free(cwd);
964 
965       return FALSE;
966     }
967 
968   /* See If we have a atoms in cache. */
969   newAt = FALSE;
970   wf = (BigDFT_Wf*)g_object_get_data(G_OBJECT(data), "BigDFT_wf");
971   if (!wf)
972     {
973       wf = bigdft_wf_new(in->inputPsiId);
974       if (!bigdft_atoms_set_structure_from_file(BIGDFT_ATOMS(wf->lzd), filename))
975         {
976           DBG_fprintf(stderr, "BigDFT: '%s' is not a BigDFT file.\n", filename);
977           g_object_unref(G_OBJECT(wf));
978           wf = (BigDFT_Wf*)0;
979         }
980       else
981         g_object_set_data_full(G_OBJECT(data), "BigDFT_wf", wf,
982                                (GDestroyNotify)g_object_unref);
983       newAt = TRUE;
984     }
985   if (!wf)
986     {
987       g_chdir(cwd);
988       g_free(cwd);
989 
990       return FALSE;
991     }
992   atoms = BIGDFT_ATOMS(wf->lzd);
993 
994   /* We get the symmetries and the atom displacements, if any. */
995   if (newAt)
996     {
997       bigdft_atoms_set_displacement(atoms, in->randdis);
998       bigdft_atoms_set_symmetries(atoms, !in->disableSym, -1., in->elecfield);
999       bigdft_inputs_parse_additional(in, atoms);
1000     }
1001 
1002   /* We get some input parameters. */
1003   ixc = GET_OPT_INT(self, "ixc");
1004   h[0] = GET_OPT_DBL(self, "hx");
1005   h[1] = GET_OPT_DBL(self, "hy");
1006   h[2] = GET_OPT_DBL(self, "hz");
1007   crmult = GET_OPT_DBL(self, "crmult");
1008   frmult = GET_OPT_DBL(self, "frmult");
1009 
1010   /* We set up the population. */
1011   eles = g_array_sized_new(FALSE, FALSE, sizeof(VisuElement*), atoms->ntypes);
1012   for (i = 0; i < atoms->ntypes; i++)
1013     {
1014       ele = visu_element_retrieveFromName(atoms->atomnames[i], (gboolean*)0);
1015       g_array_insert_val(eles, i, ele);
1016     }
1017   nEle = g_array_sized_new(FALSE, TRUE, sizeof(guint), atoms->ntypes);
1018   g_array_set_size(nEle, atoms->ntypes);
1019   for (i = 0; i < atoms->nat;  i++)
1020     *(&g_array_index(nEle, guint, atoms->iatype[i] - 1)) += 1;
1021   visu_node_array_allocate(VISU_NODE_ARRAY(data), eles, nEle);
1022   g_array_free(eles, TRUE);
1023   g_array_free(nEle, TRUE);
1024 
1025   /* Radii may already been set for this dataObj. */
1026   radii = (GArray*)g_object_get_data(G_OBJECT(data), "BigDFT_radii");
1027 
1028   /* We compute the localisation region and the new coordinates. */
1029   if (newAt)
1030     bigdft_atoms_set_psp(atoms, ixc, in->nspin, (const gchar*)0);
1031   if (!radii)
1032     {
1033       radii = bigdft_atoms_get_radii(atoms, crmult, frmult, 0.);
1034       g_array_ref(radii);
1035       g_object_set_data_full(G_OBJECT(data), "BigDFT_radii",
1036                              radii, (GDestroyNotify)g_array_unref);
1037       radiiStatus = g_malloc0(sizeof(guint) * atoms->ntypes * 3);
1038       for (i = 0; i < atoms->ntypes; i++)
1039         {
1040           radiiStatus[i] = (g_array_index(radii, double, i) == atoms->radii_cf[i])?
1041             RADII_VALUE_FILE:RADII_VALUE_COMPUTED;
1042           radiiStatus[atoms->ntypes + i] =
1043             (g_array_index(radii, double, atoms->ntypes + i) ==
1044              atoms->radii_cf[atoms->ntypes + i])?
1045             RADII_VALUE_FILE:RADII_VALUE_COMPUTED;
1046         }
1047       g_object_set_data_full(G_OBJECT(data), "BigDFT_radiiStatus", radiiStatus, g_free);
1048       g_object_set_data(G_OBJECT(data), "BigDFT_ntypes", GINT_TO_POINTER(atoms->ntypes));
1049     }
1050   bigdft_locreg_set_radii(BIGDFT_LOCREG(wf->lzd), radii);
1051   bigdft_locreg_set_size(BIGDFT_LOCREG(wf->lzd), h, crmult, frmult);
1052   bigdft_lzd_init_d(wf->lzd);
1053   bigdft_lzd_set_irreductible_zone(wf->lzd, in->nspin);
1054   bigdft_locreg_init_wfd(BIGDFT_LOCREG(wf->lzd));
1055   glr = BIGDFT_LOCREG(wf->lzd);
1056 
1057   /* We have finished here with BigDFT, we set back the current
1058      working dir. */
1059   g_chdir(cwd);
1060   g_free(cwd);
1061 
1062   for (i = 0; i < atoms->nat; i++)
1063     {
1064       xyz[0] = atoms->rxyz.data[3 * i + 0];
1065       xyz[1] = atoms->rxyz.data[3 * i + 1];
1066       xyz[2] = atoms->rxyz.data[3 * i + 2];
1067       visu_data_addNodeFromIndex(data, atoms->iatype[i] - 1, xyz, FALSE, FALSE);
1068     }
1069 
1070   /* We finish with the box geometry. */
1071   box[0] = atoms->alat[0];
1072   box[1] = 0.;
1073   box[2] = atoms->alat[1];
1074   box[3] = 0.;
1075   box[4] = 0.;
1076   box[5] = atoms->alat[2];
1077   switch (atoms->geocode)
1078     {
1079     case 'P':
1080       boxObj = visu_box_new(box, VISU_BOX_PERIODIC);
1081       grid[0] = glr->n[0] + 1;
1082       grid[1] = glr->n[1] + 1;
1083       grid[2] = glr->n[2] + 1;
1084       break;
1085     case 'S':
1086       boxObj = visu_box_new(box, VISU_BOX_SURFACE_ZX);
1087       grid[0] = glr->n[0] + 1;
1088       grid[1] = glr->n[1];
1089       grid[2] = glr->n[2] + 1;
1090       break;
1091     case 'F':
1092       boxObj = visu_box_new(box, VISU_BOX_FREE);
1093       grid[0] = glr->n[0];
1094       grid[1] = glr->n[1];
1095       grid[2] = glr->n[2];
1096       break;
1097     default:
1098       g_warning("Unknown geocode.");
1099       boxObj = visu_box_new(box, VISU_BOX_PERIODIC);
1100       grid[0] = glr->n[0] + 1;
1101       grid[1] = glr->n[1] + 1;
1102       grid[2] = glr->n[2] + 1;
1103     }
1104   visu_boxed_setBox(VISU_BOXED(data), VISU_BOXED(boxObj));
1105   g_object_unref(boxObj);
1106   visu_box_setMargin(boxObj, visu_node_array_getMaxElementSize(VISU_NODE_ARRAY(data)) +
1107                      visu_data_getAllNodeExtens(data, boxObj), TRUE);
1108   visu_box_setUnit(boxObj, TOOL_UNITS_BOHR);
1109   /* Update h values with the possibly computed values of glr. */
1110   SET_OPT_DBL(format, "hx", glr->h[0]);
1111   SET_OPT_DBL(format, "hy", glr->h[1]);
1112   SET_OPT_DBL(format, "hz", glr->h[2]);
1113 
1114   /* Additional data. */
1115   nbGrid = (glr->n[0] + 1) * (glr->n[1] + 1) * (glr->n[2] + 1);
1116   cgrid = bigdft_locreg_get_grid(glr, GRID_COARSE);
1117   gcoord_c = g_array_sized_new(FALSE, FALSE, sizeof(gfloat) * 3, nbGrid);
1118   iGrid = 0;
1119   for (k = 0; k <= glr->n[2]; k++)
1120     for (j = 0; j <= glr->n[1]; j++)
1121       for (i = 0; i <= glr->n[0]; i++)
1122         {
1123           if (cgrid[iGrid] != 0)
1124             {
1125               vect[0] = (float)i / (float)grid[0];
1126               vect[1] = (float)j / (float)grid[1];
1127               vect[2] = (float)k / (float)grid[2];
1128               g_array_append_val(gcoord_c, vect);
1129             }
1130           iGrid += 1;
1131         }
1132   /* gcoord_c = g_array_sized_new(FALSE, FALSE, sizeof(gfloat) * 3, glr->nseg_f); */
1133   /* for (valid = bigdft_locreg_iter_new(glr, &iter, GRID_FINE); valid; */
1134   /*      valid = bigdft_locreg_iter_next(&iter)) */
1135   /*   { */
1136   /*     vect[0] = iter.x0; */
1137   /*     vect[1] = iter.y; */
1138   /*     vect[2] = iter.z; */
1139   /*     g_array_append_val(gcoord_c, vect); */
1140   /*     if (iter.x1 != iter.x0) */
1141   /*       { */
1142   /*         vect[0] = iter.x1; */
1143   /*         vect[1] = iter.y; */
1144   /*         vect[2] = iter.z; */
1145   /*         g_array_append_val(gcoord_c, vect); */
1146   /*       } */
1147   /*   } */
1148   DBG_fprintf(stderr, "BigDFT: have %d coarse grid points.\n", gcoord_c->len);
1149   g_object_set_data_full(G_OBJECT(data), "BigDFT_coarse_grid",
1150                          (gpointer)gcoord_c, (GDestroyNotify)g_array_unref);
1151   g_free(cgrid);
1152   if (gcoord_c->len > 0 && useCGrid)
1153     bigdft_show_grid(data, gcoord_c, "g", 0);
1154 
1155   fgrid = bigdft_locreg_get_grid(glr, GRID_FINE);
1156   gcoord_f = g_array_sized_new(FALSE, FALSE, sizeof(gfloat) * 3, nbGrid);
1157   iGrid = 0;
1158   for (k = 0; k <= glr->n[2]; k++)
1159     for (j = 0; j <= glr->n[1]; j++)
1160       for (i = 0; i <= glr->n[0]; i++)
1161         {
1162           if (fgrid[iGrid] != 0)
1163             {
1164               vect[0] = (float)i / (float)grid[0];
1165               vect[1] = (float)j / (float)grid[1];
1166               vect[2] = (float)k / (float)grid[2];
1167               g_array_append_val(gcoord_f, vect);
1168             }
1169           iGrid += 1;
1170         }
1171   DBG_fprintf(stderr, "BigDFT: have %d fine grid points.\n", gcoord_f->len);
1172   if (gcoord_f->len > 0)
1173     g_object_set_data_full(G_OBJECT(data), "BigDFT_fine_grid",
1174                            (gpointer)gcoord_f, (GDestroyNotify)g_array_unref);
1175   else
1176     g_array_free(gcoord_f, TRUE);
1177   if (gcoord_f->len > 0 && useFGrid)
1178     bigdft_show_grid(data, gcoord_f, "G", 0);
1179   g_free(fgrid);
1180 
1181   /* Possible label. */
1182   labels = visu_data_getNodeLabels(data);
1183   for (i = 0; i < atoms->nat; i++)
1184     visu_node_values_string_setAt
1185       (labels, visu_node_array_getFromId(VISU_NODE_ARRAY(data), i),
1186        bigdft_atoms_get_extra_as_label(BIGDFT_ATOMS(wf->lzd), i));
1187 
1188   return TRUE;
1189 }
1190 
onToggleLoad(GtkToggleButton * toggle,gpointer data _U_)1191 static void onToggleLoad(GtkToggleButton *toggle, gpointer data _U_)
1192 {
1193   VisuData *dataObj;
1194 
1195   useLoadWithGrid = gtk_toggle_button_get_active(toggle);
1196 
1197   dataObj = visu_ui_panel_getData(VISU_UI_PANEL(panelBigDFT));
1198   if (!dataObj)
1199     return;
1200 
1201   visu_ui_rendering_window_reload(visu_ui_main_class_getDefaultRendering());
1202 }
1203 
onHgrid(VisuUiNumericalEntry * entry,gdouble old_value _U_,gpointer data)1204 static void onHgrid(VisuUiNumericalEntry *entry, gdouble old_value _U_, gpointer data)
1205 {
1206   gdouble value;
1207   const gchar *hgrid[] = {"hx", "hy", "hz"};
1208   VisuBox *boxObj;
1209 
1210   if (disableCallbacks)
1211     return;
1212   boxObj = visu_boxed_getBox(visu_ui_panel_getFocused(VISU_UI_PANEL(panelBigDFT)));
1213   if (!boxObj)
1214     return;
1215 
1216   value = CLAMP(visu_ui_numerical_entry_getValue(entry), 0.1, 1.);
1217   disableCallbacks = TRUE;
1218   if (visu_box_getBoundary(boxObj) == VISU_BOX_FREE)
1219     {
1220       visu_ui_numerical_entry_setValue(VISU_UI_NUMERICAL_ENTRY(entryHgrid[0]), value);
1221       visu_ui_numerical_entry_setValue(VISU_UI_NUMERICAL_ENTRY(entryHgrid[1]), value);
1222       visu_ui_numerical_entry_setValue(VISU_UI_NUMERICAL_ENTRY(entryHgrid[2]), value);
1223     }
1224   else
1225     visu_ui_numerical_entry_setValue(entry, value);
1226   disableCallbacks = FALSE;
1227 
1228   if (visu_box_getBoundary(boxObj) == VISU_BOX_FREE)
1229     {
1230       SET_OPT_DBL(fmtWvl, hgrid[0], value);
1231       SET_OPT_DBL(fmtWvl, hgrid[1], value);
1232       SET_OPT_DBL(fmtWvl, hgrid[2], value);
1233     }
1234   else
1235     SET_OPT_DBL(fmtWvl, hgrid[GPOINTER_TO_INT(data)], value);
1236 
1237   if (useLoadWithGrid)
1238     visu_ui_rendering_window_reload(visu_ui_main_class_getDefaultRendering());
1239 }
onRmult(VisuUiNumericalEntry * entry,gdouble old_value _U_,gpointer data)1240 static void onRmult(VisuUiNumericalEntry *entry, gdouble old_value _U_, gpointer data)
1241 {
1242   gdouble value;
1243   const gchar *mult[] = {"crmult", "frmult"};
1244 
1245   if (disableCallbacks)
1246     return;
1247 
1248   value = CLAMP(visu_ui_numerical_entry_getValue(entry), 1., 20.);
1249   disableCallbacks = TRUE;
1250   visu_ui_numerical_entry_setValue(entry, value);
1251   disableCallbacks = FALSE;
1252 
1253   SET_OPT_DBL(fmtWvl, mult[GPOINTER_TO_INT(data)], value);
1254 
1255   if (useLoadWithGrid && visu_ui_panel_getData(VISU_UI_PANEL(panelBigDFT)))
1256     visu_ui_rendering_window_reload(visu_ui_main_class_getDefaultRendering());
1257 }
onRadius(VisuUiNumericalEntry * entry,gdouble old_value _U_,gpointer data)1258 static void onRadius(VisuUiNumericalEntry *entry, gdouble old_value _U_, gpointer data)
1259 {
1260   GArray *radii;
1261   double value;
1262   guint nEle, iEle;
1263   guint *radiiStatus;
1264   VisuData *dataObj;
1265 
1266   if (disableCallbacks)
1267     return;
1268   dataObj = visu_ui_panel_getData(VISU_UI_PANEL(panelBigDFT));
1269 
1270   value = CLAMP(visu_ui_numerical_entry_getValue(entry), 0., 15.);
1271   disableCallbacks = TRUE;
1272   visu_ui_numerical_entry_setValue(entry, value);
1273   disableCallbacks = FALSE;
1274 
1275   if (!dataObj)
1276     return;
1277 
1278   radii = (GArray*)g_object_get_data(G_OBJECT(dataObj), "BigDFT_radii");
1279   radiiStatus = (guint*)g_object_get_data(G_OBJECT(dataObj), "BigDFT_radiiStatus");
1280   g_return_if_fail(radii && radiiStatus);
1281 
1282   nEle = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(dataObj), "BigDFT_ntypes"));
1283   iEle = gtk_combo_box_get_active(GTK_COMBO_BOX(cbRadEle[GPOINTER_TO_INT(data)]));
1284   g_array_insert_val(radii, nEle * GPOINTER_TO_INT(data) + iEle, value);
1285   radiiStatus[nEle * GPOINTER_TO_INT(data) + iEle] = RADII_VALUE_EDITED;
1286   gtk_entry_set_icon_from_stock(GTK_ENTRY(entry), GTK_ENTRY_ICON_SECONDARY,
1287                                 radiiIcons[RADII_VALUE_EDITED]);
1288 
1289   if (useLoadWithGrid)
1290     visu_ui_rendering_window_reload(visu_ui_main_class_getDefaultRendering());
1291 }
onEleChanged(GtkComboBox * combo,gpointer data)1292 static void onEleChanged(GtkComboBox *combo, gpointer data)
1293 {
1294   GArray *radii;
1295   guint nEle, iEle;
1296   guint *radiiStatus;
1297   VisuData *dataObj;
1298 
1299   disableCallbacks = TRUE;
1300 
1301   dataObj = visu_ui_panel_getData(VISU_UI_PANEL(panelBigDFT));
1302   if (!dataObj)
1303     return;
1304 
1305   radii = (GArray*)g_object_get_data(G_OBJECT(dataObj), "BigDFT_radii");
1306   radiiStatus = (guint*)g_object_get_data(G_OBJECT(dataObj), "BigDFT_radiiStatus");
1307   if (!radii || !radiiStatus)
1308     return;
1309 
1310   nEle = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(dataObj), "BigDFT_ntypes"));
1311   iEle = gtk_combo_box_get_active(combo);
1312   if (iEle >= nEle)
1313     gtk_combo_box_set_active(combo, nEle - 1);
1314   else
1315     {
1316       visu_ui_numerical_entry_setValue
1317         (VISU_UI_NUMERICAL_ENTRY(entryRadius[GPOINTER_TO_INT(data)]),
1318          g_array_index(radii, double, nEle * GPOINTER_TO_INT(data) + iEle));
1319       gtk_entry_set_icon_from_stock(GTK_ENTRY(entryRadius[GPOINTER_TO_INT(data)]),
1320                                     GTK_ENTRY_ICON_SECONDARY,
1321                                     radiiIcons[radiiStatus[nEle * GPOINTER_TO_INT(data) +
1322                                                            iEle]]);
1323     }
1324 
1325   disableCallbacks = FALSE;
1326 }
onIxc(VisuUiNumericalEntry * entry,gdouble old_value _U_,gpointer data _U_)1327 static void onIxc(VisuUiNumericalEntry *entry, gdouble old_value _U_, gpointer data _U_)
1328 {
1329   if (disableCallbacks)
1330     return;
1331 
1332   SET_OPT_INT(fmtWvl, "ixc", visu_ui_numerical_entry_getValue(entry));
1333 
1334   if (useLoadWithGrid && visu_ui_panel_getData(VISU_UI_PANEL(panelBigDFT)))
1335     visu_ui_rendering_window_reload(visu_ui_main_class_getDefaultRendering());
1336 }
onFilesChanged(VisuData * dataObj,guint kind,gpointer data _U_)1337 static void onFilesChanged(VisuData *dataObj, guint kind, gpointer data _U_)
1338 {
1339   BigDFT_Inputs *in;
1340   gchar *basename, *ptr, *dirname, *cwd;
1341 
1342   DBG_fprintf(stderr, "Panel BigDFT: test input from (%d) '%s'.\n",
1343               kind, visu_data_getFile(dataObj, 0, (ToolFileFormat**)0));
1344   if (kind != 0 || !useLoadWithGrid ||
1345       !tool_file_format_match(fmtWvl, visu_data_getFile(dataObj, 0, (ToolFileFormat**)0)))
1346     return;
1347 
1348   /* We change the current working dir to allow BigDFT to look for
1349      input files and pseudos. */
1350   dirname = g_path_get_dirname(visu_data_getFile(dataObj, 0, (ToolFileFormat**)0));
1351   cwd     = g_get_current_dir();
1352   g_chdir(dirname);
1353   g_free(dirname);
1354 
1355   basename = g_path_get_basename(visu_data_getFile(dataObj, 0, (ToolFileFormat**)0));
1356   ptr = strrchr(basename, '.');
1357   if (ptr)
1358     *ptr = '\0';
1359   DBG_fprintf(stderr, "Panel BigDFT: read input files for '%s'.\n", basename);
1360   if (strcmp(basename, "posinp"))
1361     in = bigdft_inputs_new(basename);
1362   else
1363     in = bigdft_inputs_new((const gchar*)0);
1364   g_free(basename);
1365   /* We store the input parameters for future use with this dataObj. */
1366   g_object_set_data_full(G_OBJECT(dataObj), "BigDFT_inputs", in,
1367                          (GDestroyNotify)bigdft_inputs_free);
1368   if (in->files & BIGDFT_INPUTS_DFT)
1369     {
1370       SET_OPT_DBL(fmtWvl, "hx", in->h[0]);
1371       SET_OPT_DBL(fmtWvl, "hy", in->h[1]);
1372       SET_OPT_DBL(fmtWvl, "hz", in->h[2]);
1373       SET_OPT_DBL(fmtWvl, "crmult", in->crmult);
1374       SET_OPT_DBL(fmtWvl, "frmult", in->frmult);
1375       SET_OPT_INT(fmtWvl, "ixc", in->ixc);
1376     }
1377 
1378   /* We have finished here with BigDFT, we set back the current
1379      working dir. */
1380   g_chdir(cwd);
1381   g_free(cwd);
1382 }
onNproc(GtkSpinButton * spin,gpointer data _U_)1383 static void onNproc(GtkSpinButton *spin, gpointer data _U_)
1384 {
1385   SET_OPT_INT(fmtWvl, "nproc", gtk_spin_button_get_value(spin));
1386 
1387   update_memory_estimation(visu_ui_panel_getData(VISU_UI_PANEL(panelBigDFT)));
1388 }
1389 
update_memory_estimation(VisuData * data)1390 static void update_memory_estimation(VisuData *data)
1391 {
1392   BigDFT_Inputs *in;
1393   BigDFT_Wf *wf;
1394   BigDFT_Proj *proj;
1395   double frmult;
1396   int out_pipe[2], stdout_fileno_old;
1397 
1398   if (!data)
1399     return;
1400   wf = (BigDFT_Wf*)g_object_get_data(G_OBJECT(data), "BigDFT_wf");
1401   in = (BigDFT_Inputs*)g_object_get_data(G_OBJECT(data), "BigDFT_inputs");
1402   if (!in || !wf)
1403     return;
1404 
1405   frmult = GET_OPT_DBL(fmtWvl, "frmult");
1406 
1407   proj = bigdft_proj_new(BIGDFT_LOCREG(wf->lzd), BIGDFT_ORBS(wf), frmult);
1408 
1409   stdout_fileno_old = redirect_init(out_pipe);
1410   bigdft_memory_get_peak(GET_OPT_INT(fmtWvl, "nproc"), BIGDFT_LOCREG(wf->lzd), in,
1411                          BIGDFT_ORBS(wf), proj);
1412   redirect_dump(out_pipe, stdout_fileno_old);
1413 
1414   bigdft_proj_free(proj);
1415 }
redirect_init(int out_pipe[2])1416 static int redirect_init(int out_pipe[2])
1417 {
1418   int stdout_fileno_old;
1419 
1420   /* Flush before redirecting. */
1421   fflush(stdout);
1422 
1423   /* Make a pipe to redirect stdout. */
1424   stdout_fileno_old = dup(STDOUT_FILENO);
1425 #ifndef _WIN32
1426   g_return_val_if_fail((pipe(out_pipe) == 0), stdout_fileno_old);
1427   dup2(out_pipe[1], STDOUT_FILENO);
1428 #endif
1429 
1430   return stdout_fileno_old;
1431 }
1432 
1433 #define MAX_FORTRAN_OUTPUT 4096
redirect_dump(int out_pipe[2],int stdout_fileno_old)1434 static void redirect_dump(int out_pipe[2], int stdout_fileno_old)
1435 {
1436   gchar foutput[MAX_FORTRAN_OUTPUT];
1437   ssize_t ncount;
1438   long flags;
1439   GtkTextIter startIter;
1440 
1441   /* Flush before reconnecting. */
1442   fflush(stdout);
1443   /* Reconnect stdout. */
1444   dup2(stdout_fileno_old, STDOUT_FILENO);
1445 
1446 #ifndef _WIN32
1447   /* Make the reading pipe non blocking. */
1448   flags = fcntl(out_pipe[0], F_GETFL);
1449   flags |= O_NONBLOCK;
1450   fcntl(out_pipe[0], F_SETFL, flags);
1451 
1452   /* Write Fortran output with prefix... */
1453   foutput[0] = '\0';
1454   ncount = read(out_pipe[0], foutput, MAX_FORTRAN_OUTPUT);
1455   foutput[ncount] = '\0';
1456   gtk_text_buffer_set_text(bufMemory, "", -1);
1457   gtk_text_buffer_get_start_iter(bufMemory, &startIter);
1458   gtk_text_buffer_insert_with_tags_by_name(bufMemory, &startIter, foutput, -1,
1459                                            "typewriter", NULL);
1460 
1461   /* Close the pipes. */
1462   close(out_pipe[0]);
1463   close(out_pipe[1]);
1464 #endif
1465 }
1466 
exportParameters(GString * data,VisuData * dataObj _U_)1467 static void exportParameters(GString *data, VisuData *dataObj _U_)
1468 {
1469   g_string_append_printf(data, "# %s\n", DESC_PARAMETER_BIGDFT);
1470   g_string_append_printf(data, "%s[bigdft]: %d\n\n", FLAG_PARAMETER_BIGDFT,
1471 			 useLoadWithGrid);
1472 }
1473