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