1 /* NWChemMolecule.c */
2 /**********************************************************************************************************
3 Copyright (c) 2002-2013 Abdul-Rahman Allouche. All rights reserved
4
5 Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
6 documentation files (the Gabedit), to deal in the Software without restriction, including without limitation
7 the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software,
8 and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
9
10 The above copyright notice and this permission notice shall be included in all copies or substantial portions
11 of the Software.
12
13 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
14 TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
15 THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
16 CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
17 DEALINGS IN THE SOFTWARE.
18 ************************************************************************************************************/
19
20 #include <stdlib.h>
21 #include <ctype.h>
22 #include <math.h>
23
24 #include "../../Config.h"
25 #include "../Common/Global.h"
26 #include "../NWChem/NWChemTypes.h"
27 #include "../NWChem/NWChemGlobal.h"
28 #include "../NWChem/NWChemKeywords.h"
29 #include "../Geometry/GeomGlobal.h"
30 #include "../Geometry/GeomConversion.h"
31 #include "../Geometry/GeomXYZ.h"
32 #include "../Geometry/Fragments.h"
33 #include "../Geometry/DrawGeom.h"
34 #include "../Utils/Utils.h"
35 #include "../Utils/UtilsInterface.h"
36 #include "../Utils/Constants.h"
37 #include "../Utils/GabeditTextEdit.h"
38 #include "../Geometry/InterfaceGeom.h"
39 #include "../Common/Windows.h"
40 #include "../Utils/Constants.h"
41 #include "../Utils/AtomsProp.h"
42 #include "../Symmetry/MoleculeSymmetry.h"
43 #include "../Symmetry/MoleculeSymmetryInterface.h"
44
45 /************************************************************************************************************/
46 static gint totalCharge = 0;
47 static gint spinMultiplicity=1;
48 /************************************************************************************************************/
getNWChemMultiplicity()49 gint getNWChemMultiplicity()
50 {
51 return spinMultiplicity;
52 }
53 /************************************************************************************************************/
initNWChemMoleculeButtons()54 void initNWChemMoleculeButtons()
55 {
56 }
57 /************************************************************************************************************/
initNWChemMolecule()58 void initNWChemMolecule()
59 {
60 nwchemMolecule.listOfAtoms = NULL;
61 nwchemMolecule.totalNumberOfElectrons = 0;
62 nwchemMolecule.numberOfValenceElectrons = 0;
63 nwchemMolecule.numberOfAtoms = 0;
64 }
65 /************************************************************************************************************/
freeNWChemMolecule()66 void freeNWChemMolecule()
67 {
68 static gboolean first = TRUE;
69
70 if(first)
71 {
72 initNWChemMolecule();
73 first = FALSE;
74 return;
75 }
76
77 if(nwchemMolecule.listOfAtoms) g_free(nwchemMolecule.listOfAtoms);
78 initNWChemMolecule();
79 }
80 /************************************************************************************************************/
setNWChemMoleculeFromSXYZ(gint nAtoms,gchar ** symbols,gdouble * X,gdouble * Y,gdouble * Z)81 static gint setNWChemMoleculeFromSXYZ(gint nAtoms, gchar** symbols, gdouble* X, gdouble* Y, gdouble* Z)
82 {
83 gint n;
84 NWChemAtom* atomList = NULL;
85
86 nwchemMolecule.listOfAtoms = NULL;
87 nwchemMolecule.numberOfAtoms = 0;
88 if(nAtoms<1) return 1;
89
90 nwchemMolecule.listOfAtoms = (NWChemAtom*)g_malloc(sizeof(NWChemAtom)*(nAtoms));
91 if(nwchemMolecule.listOfAtoms==NULL) return -1;
92
93 nwchemMolecule.numberOfAtoms = nAtoms;
94
95 atomList = nwchemMolecule.listOfAtoms;
96 for(n=0; n<nwchemMolecule.numberOfAtoms; n++)
97 {
98 atomList->position[0] = X[n];
99 atomList->position[1] = Y[n];
100 atomList->position[2] = Z[n];
101 atomList->symbol = g_strdup(symbols[n]);
102 atomList++;
103 }
104
105 return 0;
106 }
107 /************************************************************************************************************/
setXYZFromGeomXYZ(gint i,gdouble * x,gdouble * y,gdouble * z)108 static void setXYZFromGeomXYZ(gint i, gdouble* x, gdouble* y, gdouble *z)
109 {
110 if(!test(GeomXYZ[i].X))
111 *x = get_value_variableXYZ(GeomXYZ[i].X);
112 else
113 *x = atof(GeomXYZ[i].X);
114 if(!test(GeomXYZ[i].Y))
115 *y = get_value_variableXYZ(GeomXYZ[i].Y);
116 else
117 *y = atof(GeomXYZ[i].Y);
118 if(!test(GeomXYZ[i].Z))
119 *z = get_value_variableXYZ(GeomXYZ[i].Z);
120 else
121 *z = atof(GeomXYZ[i].Z);
122
123 if(Units==0)
124 {
125 *x *= BOHR_TO_ANG;
126 *y *= BOHR_TO_ANG;
127 *z *= BOHR_TO_ANG;
128 }
129 }
130 /************************************************************************************************************/
setNWChemMoleculeFromGeomXYZ()131 static gboolean setNWChemMoleculeFromGeomXYZ()
132 {
133 gint i;
134 gchar** symbols = NULL;
135 gdouble* X = NULL;
136 gdouble* Y = NULL;
137 gdouble* Z = NULL;
138 gint numberOfAtoms = NcentersXYZ;
139
140 if(numberOfAtoms<1) return FALSE;
141
142 symbols = (gchar**)g_malloc(sizeof(gchar*)*(numberOfAtoms));
143
144 if(symbols == NULL) return FALSE;
145
146 X = (gdouble*)g_malloc(sizeof(gdouble)*(numberOfAtoms));
147 if(X == NULL) return FALSE;
148 Y = (gdouble*)g_malloc(sizeof(gdouble)*(numberOfAtoms));
149 if(Y == NULL) return FALSE;
150 Z = (gdouble*)g_malloc(sizeof(gdouble)*(numberOfAtoms));
151 if(Z == NULL) return FALSE;
152
153 nwchemMolecule.totalNumberOfElectrons = 0;
154 for(i=0; i<numberOfAtoms; i++)
155 {
156 SAtomsProp prop = prop_atom_get(GeomXYZ[i].Symb);
157
158 symbols[i] = g_strdup(GeomXYZ[i].Symb);
159 setXYZFromGeomXYZ(i, &X[i] , &Y[i] , &Z[i]);
160 nwchemMolecule.totalNumberOfElectrons += prop.atomicNumber;
161 }
162 nwchemMolecule.numberOfValenceElectrons = nwchemMolecule.totalNumberOfElectrons;
163 setNWChemMoleculeFromSXYZ(numberOfAtoms, symbols, X, Y, Z);
164
165 for (i=0;i<(gint)NcentersXYZ;i++) g_free( symbols[i]);
166 g_free( symbols);
167 g_free(X);
168 g_free(Y);
169 g_free(Z);
170 return TRUE;
171 }
172 /************************************************************************************************************/
setNWChemMoleculeFromGeomZMatrix()173 static gboolean setNWChemMoleculeFromGeomZMatrix()
174 {
175 iprogram=PROG_IS_NWCHEM;
176 if(!zmat_to_xyz()) return FALSE;
177 delete_dummy_atoms();
178 /* conversion_zmat_to_xyz();*/
179 return setNWChemMoleculeFromGeomXYZ();
180 }
181 /************************************************************************************************************/
setNWChemMolecule()182 gboolean setNWChemMolecule()
183 {
184 freeNWChemMolecule();
185 if(MethodeGeom==GEOM_IS_XYZ && setNWChemMoleculeFromGeomXYZ()) return TRUE;
186 if(setNWChemMoleculeFromGeomZMatrix()) return TRUE;
187 return FALSE;
188 }
189 /************************************************************************************************************/
setNWChemGeometryFromInputFile(gchar * fileName)190 void setNWChemGeometryFromInputFile(gchar* fileName)
191 {
192 read_XYZ_from_nwchem_input_file(fileName);
193 setNWChemMolecule();
194 }
195 /************************************************************************************************************/
testAbelianGroup()196 static gboolean testAbelianGroup()
197 {
198 gint i;
199 gchar** symbols = NULL;
200 gdouble* X = NULL;
201 gdouble* Y = NULL;
202 gdouble* Z = NULL;
203 gint numberOfAtoms = nwchemMolecule.numberOfAtoms;
204 gchar pointGroupSymbol[BSIZE];
205 gchar abelianPointGroupSymbol[BSIZE];
206 gchar message[BSIZE];
207 gint maximalOrder = 20;
208 gint nGenerators;
209 gint nMolcas = 0;
210 gint nElements;
211 gchar* generators[3];
212 gchar* molcasGenerators[3];
213 gchar* elements[8];
214 gdouble principalAxisTolerance = getTolerancePrincipalAxis();
215 gdouble positionTolerance = getTolerancePosition();
216
217 if(numberOfAtoms<1) return FALSE;
218
219 for(i=0;i<3;i++)
220 {
221 generators[i] = g_malloc(100*sizeof(gchar));
222 molcasGenerators[i] = g_malloc(100*sizeof(gchar));
223 }
224 for(i=0;i<8;i++) elements[i] = g_malloc(100*sizeof(gchar));
225
226 symbols = (gchar**)g_malloc(sizeof(gchar*)*(numberOfAtoms));
227 if(symbols == NULL) return FALSE;
228
229 X = (gdouble*)g_malloc(sizeof(gdouble)*(numberOfAtoms));
230 if(X == NULL) return FALSE;
231 Y = (gdouble*)g_malloc(sizeof(gdouble)*(numberOfAtoms));
232 if(Y == NULL) return FALSE;
233 Z = (gdouble*)g_malloc(sizeof(gdouble)*(numberOfAtoms));
234 if(Z == NULL) return FALSE;
235
236 for(i=0; i<numberOfAtoms; i++)
237 {
238 symbols[i] = g_strdup(nwchemMolecule.listOfAtoms[i].symbol);
239 X[i] = nwchemMolecule.listOfAtoms[i].position[0];
240 Y[i] = nwchemMolecule.listOfAtoms[i].position[1];
241 Z[i] = nwchemMolecule.listOfAtoms[i].position[2];
242 }
243 computeAbelianGroup(principalAxisTolerance, pointGroupSymbol, abelianPointGroupSymbol, maximalOrder, TRUE,
244 &numberOfAtoms, symbols, X, Y, Z,
245 &nGenerators, generators, &nMolcas, molcasGenerators, &nElements, elements, &positionTolerance, message);
246
247 for(i=0;i<3;i++)
248 {
249 g_free(generators[i]);
250 g_free(molcasGenerators[i]);
251 }
252 for(i=0;i<8;i++) g_free(elements[i]);
253
254 for (i=0;i<(gint)numberOfAtoms;i++) g_free( symbols[i]);
255 g_free( symbols);
256 g_free(X);
257 g_free(Y);
258 g_free(Z);
259 if(!strcmp( pointGroupSymbol,abelianPointGroupSymbol))return TRUE;
260 return FALSE;
261 }
262 /*************************************************************************************************************/
263 /*
264 static gdouble getMinDistance()
265 {
266 gdouble d=0;
267 gint i;
268 gint k;
269 NWChemAtom* atomList = nwchemMolecule.listOfAtoms;
270 for(i=0; i<nwchemMolecule.numberOfAtoms-1; i++)
271 {
272 gdouble dd = 0;
273 for(k=0;k<3;k++)
274 {
275 gdouble xx = atomList->position[k]-atomList->position[k+1];
276 dd += xx*xx;
277 }
278 if(i==0) d = dd;
279 else if(d>dd) d= dd;
280 atomList++;
281 }
282 d = sqrt(d);
283
284 return d;
285 }
286 */
287 /*************************************************************************************************************/
288 /*
289 static void setFirstAtomToXAxis(gint numberOfAtoms, gdouble* X, gdouble* Y, gdouble*Z)
290 {
291 gdouble d;
292 gdouble s;
293 gdouble c;
294 gint i;
295 gdouble positionTolerance = -1;
296
297 if(numberOfAtoms<1) return;
298 d = X[0]*X[0]+Y[0]*Y[0];
299 if(d<1e-10) return;
300 d = sqrt(d);
301 if(positionTolerance<0) positionTolerance= getMinDistance()/50;
302
303 s = -Y[0]/d;
304 c = +X[0]/d;
305
306 for (i=0;i<numberOfAtoms;i++)
307 {
308 gdouble x = X[i];
309 gdouble y = Y[i];
310 X[i] = c*x - s*y;
311 Y[i] = s*x + c*y;
312 if(fabs(Y[i])<positionTolerance) Y[i]=0.0;
313 }
314
315 }
316 */
317 /*************************************************************************************************************/
318 /*
319 static gint getRealNumberXYZVariables()
320 {
321 gint k=0;
322 gint i;
323 for(i=0;i<NcentersXYZ;i++)
324 {
325 if(test(GeomXYZ[i].X))k++;
326 if(test(GeomXYZ[i].Y))k++;
327 if(test(GeomXYZ[i].Z))k++;
328 }
329 return k;
330 }
331 */
332 /*************************************************************************************************************/
putNWChemMoleculeInTextEditor()333 static void putNWChemMoleculeInTextEditor()
334 {
335 gchar buffer[BSIZE];
336 gint i;
337 gint nV = 0;
338 gdouble x,y,z;
339
340 if(nwchemMolecule.numberOfAtoms<1) return;
341
342 if(MethodeGeom==GEOM_IS_XYZ)
343 {
344 sprintf(buffer,"\ncharge %d\n",totalCharge);
345 gabedit_text_insert (GABEDIT_TEXT(text), NULL, &nwchemColorFore.keyWord, &nwchemColorBack.keyWord, buffer, -1);
346 sprintf(buffer,"\ngeometry\n");
347 gabedit_text_insert (GABEDIT_TEXT(text), NULL, &nwchemColorFore.keyWord, &nwchemColorBack.keyWord, buffer, -1);
348 for (i=0;i<nwchemMolecule.numberOfAtoms;i++)
349 {
350 gchar X[100];
351 gchar Y[100];
352 gchar Z[100];
353 setXYZFromGeomXYZ(i, &x, &y, &z);
354 sprintf(X,"%f",x);
355 sprintf(Y,"%f",y);
356 sprintf(Z,"%f",z);
357 sprintf(buffer," %s %s %s %s\n",nwchemMolecule.listOfAtoms[i].symbol, X,Y,Z);
358 gabedit_text_insert (GABEDIT_TEXT(text), NULL, NULL, NULL, buffer, -1);
359 }
360 if(strstr(getNWChemExcitedMethod(),"CIS")||strstr(getNWChemExcitedMethod(),"TDDFT") || strstr(getNWChemTypeMethod(),"HL-"))
361 {
362 if(!testAbelianGroup())
363 gabedit_text_insert (GABEDIT_TEXT(text), NULL, NULL, NULL, " symmetry C1\n", -1);
364 }
365 sprintf(buffer,"end\n");
366 gabedit_text_insert (GABEDIT_TEXT(text), NULL, &nwchemColorFore.keyWord, &nwchemColorBack.keyWord, buffer, -1);
367 nV = 0;
368 if(NVariablesXYZ>0)
369 for(i=0;i<NVariablesXYZ;i++)
370 {
371 if(VariablesXYZ[i].Used) nV++;
372 }
373 if(nV>0 && nV!= 3*nwchemMolecule.numberOfAtoms)
374 {
375 sprintf(buffer,"\nconstraints\n");
376 gabedit_text_insert (GABEDIT_TEXT(text), NULL, &nwchemColorFore.keyWord, &nwchemColorBack.keyWord, buffer, -1);
377 for (i=0;i<nwchemMolecule.numberOfAtoms;i++)
378 {
379 if(!(!test(GeomXYZ[i].X) || !test(GeomXYZ[i].Y) || !test(GeomXYZ[i].Z)))
380 {
381 sprintf(buffer," fix atom %d\n",i+1);
382 gabedit_text_insert (GABEDIT_TEXT(text), NULL, NULL, NULL,buffer,-1);
383 }
384 }
385 gabedit_text_insert (GABEDIT_TEXT(text), NULL, &nwchemColorFore.keyWord, &nwchemColorBack.keyWord, "end\n", -1);
386 }
387 }
388 else
389 {
390 sprintf(buffer,"\ncharge %d\n",totalCharge);
391 gabedit_text_insert (GABEDIT_TEXT(text), NULL, &nwchemColorFore.keyWord, &nwchemColorBack.keyWord, buffer, -1);
392 sprintf(buffer,"\ngeometry\n");
393 gabedit_text_insert (GABEDIT_TEXT(text), NULL, &nwchemColorFore.keyWord, &nwchemColorBack.keyWord, buffer, -1);
394 gabedit_text_insert (GABEDIT_TEXT(text), NULL, NULL, NULL,"\t",-1);
395 sprintf(buffer,"zmatrix\n");
396 gabedit_text_insert (GABEDIT_TEXT(text), NULL, &nwchemColorFore.keyWord, &nwchemColorBack.keyWord, buffer, -1);
397 for(i=0;i<NcentersZmat;i++)
398 {
399 SAtomsProp prop = prop_atom_get(Geom[i].Symb);
400 gchar *line;
401 gabedit_text_insert (GABEDIT_TEXT(text), NULL, NULL, NULL,"\t",-1);
402 line=g_strdup_printf("%s",Geom[i].Symb);
403 if(Geom[i].Nentry>NUMBER_ENTRY_0) line=g_strdup_printf("%s\t%s\t%s",line,Geom[i].NR,Geom[i].R);
404 if(Geom[i].Nentry>NUMBER_ENTRY_R) line=g_strdup_printf("%s\t%s\t%s",line,Geom[i].NAngle,Geom[i].Angle);
405 if(Geom[i].Nentry>NUMBER_ENTRY_ANGLE) line=g_strdup_printf("%s\t%s\t%s",line,Geom[i].NDihedral,Geom[i].Dihedral);
406 line=g_strdup_printf("%s\n",line);
407 prop = prop_atom_get(Geom[i].Symb);
408 gabedit_text_insert (GABEDIT_TEXT(text), NULL,NULL, &prop.color,line,-1);
409 g_free(line);
410 }
411 if(NVariables>0)
412 {
413 gint nV = 0;
414 for(i=0;i<NVariables;i++)
415 {
416 if(Variables[i].Used)
417 {
418 gabedit_text_insert (GABEDIT_TEXT(text), NULL, NULL, NULL,"\tvariables\n",-1);
419 nV++;
420 break;
421 }
422 }
423 for(i=0;i<NVariables;i++)
424 {
425 if(Variables[i].Used)
426 {
427 gchar* line=g_strdup_printf("\t%s\t%s\n",Variables[i].Name,Variables[i].Value);
428 gabedit_text_insert (GABEDIT_TEXT(text), NULL, NULL, NULL,line,-1);
429 g_free(line);
430 }
431 }
432 if(nV>0)
433 {
434 gabedit_text_insert (GABEDIT_TEXT(text), NULL, NULL, NULL,"\t",-1);
435 gabedit_text_insert (GABEDIT_TEXT(text), NULL, &nwchemColorFore.keyWord, &nwchemColorBack.keyWord,"end\n",-1);
436 }
437
438 }
439 gabedit_text_insert (GABEDIT_TEXT(text), NULL, &nwchemColorFore.keyWord, &nwchemColorBack.keyWord,"end\n",-1);
440 }
441
442 }
443 /************************************************************************************************************/
putNWChemMoleculeInfoInTextEditor()444 void putNWChemMoleculeInfoInTextEditor()
445 {
446 putNWChemMoleculeInTextEditor();
447 }
448 /************************************************************************************************************/
449 /*
450 static GtkWidget* addRadioButtonToATable(GtkWidget* table, GtkWidget* friendButton, gchar* label, gint i, gint j, gint k)
451 {
452 GtkWidget *newButton;
453
454 if(friendButton)
455 newButton = gtk_radio_button_new_with_label( gtk_radio_button_get_group (GTK_RADIO_BUTTON (friendButton)), label);
456 else
457 newButton = gtk_radio_button_new_with_label( NULL, label);
458
459 gtk_table_attach(GTK_TABLE(table),newButton,j,j+k,i,i+1,
460 (GtkAttachOptions) (GTK_FILL | GTK_EXPAND),
461 (GtkAttachOptions) (GTK_FILL | GTK_EXPAND),
462 2,2);
463
464 g_object_set_data(G_OBJECT (newButton), "Label",NULL);
465 g_object_set_data(G_OBJECT (newButton), "Type",NULL);
466 return newButton;
467 }
468 */
469 /********************************************************************************/
setSpinMultiplicityComboSpinMultiplicity(GtkWidget * comboSpinMultiplicity,gint spin)470 static void setSpinMultiplicityComboSpinMultiplicity(GtkWidget *comboSpinMultiplicity, gint spin)
471 {
472 GtkWidget *entry = NULL;
473 gchar* t = NULL;
474 if(!comboSpinMultiplicity) return;
475 entry = GTK_BIN (comboSpinMultiplicity)->child;
476 t = g_strdup_printf("%d",spin);
477 gtk_entry_set_text(GTK_ENTRY(entry),t);
478 g_free(t);
479 }
480 /************************************************************************************************************/
setComboSpinMultiplicity(GtkWidget * comboSpinMultiplicity)481 static void setComboSpinMultiplicity(GtkWidget *comboSpinMultiplicity)
482 {
483 GList *glist = NULL;
484 gint i;
485 gint nlist = 0;
486 gchar** list = NULL;
487 gint k;
488 gint kinc;
489 gint ne = nwchemMolecule.numberOfValenceElectrons - totalCharge;
490
491 if(ne%2==0) nlist = ne/2+1;
492 else nlist = (ne+1)/2;
493
494 if(nlist<1) return;
495 list = g_malloc(nlist*sizeof(gchar*));
496 if(!list) return;
497 for(i=0;i<nlist;i++)
498 list[i] = g_malloc(10*sizeof(gchar));
499
500
501 if(GTK_IS_WIDGET(comboSpinMultiplicity)) gtk_widget_set_sensitive(comboSpinMultiplicity, TRUE);
502 if(ne%2==0) k = 1;
503 else k = 2;
504
505 kinc = 2;
506 for(i=0;i<nlist;i++)
507 {
508 sprintf(list[i],"%d",k);
509 k+=kinc;
510 }
511
512 for(i=0;i<nlist;i++) glist = g_list_append(glist,list[i]);
513
514 gtk_combo_box_entry_set_popdown_strings( comboSpinMultiplicity, glist) ;
515 g_list_free(glist);
516 if( SpinMultiplicities[0]%2 == atoi(list[0])%2) setSpinMultiplicityComboSpinMultiplicity(comboSpinMultiplicity, SpinMultiplicities[0]);
517 else SpinMultiplicities[0] = atoi(list[0]);
518 if(list)
519 {
520 for(i=0;i<nlist;i++) if(list[i]) g_free(list[i]);
521 g_free(list);
522 }
523 }
524 /********************************************************************************/
setChargeComboCharge(GtkWidget * comboCharge,gint charge)525 static void setChargeComboCharge(GtkWidget *comboCharge, gint charge)
526 {
527 GtkWidget *entry = NULL;
528 gchar* t = NULL;
529 if(!comboCharge) return;
530 entry = GTK_BIN (comboCharge)->child;
531 t = g_strdup_printf("%d",charge);
532 gtk_entry_set_text(GTK_ENTRY(entry),t);
533 g_free(t);
534 }
535 /********************************************************************************/
setComboCharge(GtkWidget * comboCharge)536 static void setComboCharge(GtkWidget *comboCharge)
537 {
538 GList *glist = NULL;
539 gint i;
540 gint nlist;
541 gchar** list = NULL;
542 gint k;
543
544 nlist = nwchemMolecule.numberOfValenceElectrons*2-2+1;
545
546 if(nlist<1) return;
547 list = g_malloc(nlist*sizeof(gchar*));
548 if(!list) return;
549 for(i=0;i<nlist;i++)
550 list[i] = g_malloc(10*sizeof(gchar));
551
552
553 sprintf(list[0],"0");
554 k = 1;
555 for(i=1;i<nlist-1;i+=2)
556 {
557 sprintf(list[i],"+%d",k);
558 sprintf(list[i+1],"%d",-k);
559 k += 1;
560 }
561
562 for(i=0;i<nlist;i++) glist = g_list_append(glist,list[i]);
563
564 gtk_combo_box_entry_set_popdown_strings( comboCharge, glist) ;
565 g_list_free(glist);
566 if(list)
567 {
568 for(i=0;i<nlist;i++) if(list[i]) g_free(list[i]);
569 g_free(list);
570 }
571 setChargeComboCharge(comboCharge, totalCharge);
572 }
573 /**********************************************************************/
changedEntrySpinMultiplicity(GtkWidget * entry,gpointer data)574 static void changedEntrySpinMultiplicity(GtkWidget *entry, gpointer data)
575 {
576 G_CONST_RETURN gchar* entryText = NULL;
577
578 if(!GTK_IS_WIDGET(entry)) return;
579
580 entryText = gtk_entry_get_text(GTK_ENTRY(entry));
581 if(strlen(entryText)<1)return;
582
583 spinMultiplicity=atoi(entryText);
584 if(spinMultiplicity==1)
585 {
586 /* OK RHF*/
587 setNWChemSCFMethod(TRUE);
588 }
589 else
590 {
591 /* remove RHF from list*/
592 setNWChemSCFMethod(FALSE);
593 }
594 }
595 /**********************************************************************/
changedEntryCharge(GtkWidget * entry,gpointer data)596 static void changedEntryCharge(GtkWidget *entry, gpointer data)
597 {
598 G_CONST_RETURN gchar* entryText = NULL;
599 GtkWidget* comboSpinMultiplicity = NULL;
600 GtkWidget* labelNumberOfElectrons = NULL;
601
602 if(!GTK_IS_WIDGET(entry)) return;
603
604 entryText = gtk_entry_get_text(GTK_ENTRY(entry));
605 if(strlen(entryText)<1)return;
606
607 totalCharge = atoi(entryText);
608 TotalCharges[0] = totalCharge;
609
610 comboSpinMultiplicity = g_object_get_data(G_OBJECT (entry), "ComboSpinMultiplicity");
611 if(GTK_IS_WIDGET(comboSpinMultiplicity)) setComboSpinMultiplicity(comboSpinMultiplicity);
612
613 labelNumberOfElectrons = g_object_get_data(G_OBJECT (entry), "LabelNumberOfElectrons");
614
615 if(GTK_IS_WIDGET(labelNumberOfElectrons))
616 {
617 gint ne = nwchemMolecule.numberOfValenceElectrons - totalCharge;
618 gchar buffer[BSIZE];
619 sprintf(buffer, "Number of electrons = %d",ne);
620 gtk_label_set_text(GTK_LABEL(labelNumberOfElectrons),buffer);
621 }
622 }
623 /**********************************************************************/
addComboListToATable(GtkWidget * table,gchar ** list,gint nlist,gint i,gint j,gint k)624 static GtkWidget* addComboListToATable(GtkWidget* table,
625 gchar** list, gint nlist, gint i, gint j, gint k)
626 {
627 GtkWidget *entry = NULL;
628 GtkWidget *combo = NULL;
629
630 combo = create_combo_box_entry(list, nlist, TRUE, -1, -1);
631
632 gtk_table_attach(GTK_TABLE(table),combo,j,j+k,i,i+1,
633 (GtkAttachOptions) (GTK_FILL | GTK_EXPAND),
634 (GtkAttachOptions) (GTK_FILL | GTK_SHRINK),
635 2,2);
636 entry = GTK_BIN (combo)->child;
637 g_object_set_data(G_OBJECT (entry), "Combo",combo);
638 gtk_widget_set_size_request(GTK_WIDGET(entry),(gint)(ScreenHeight*0.2),-1);
639
640 return entry;
641 }
642 /***********************************************************************************************/
addNWChemChargeToTable(GtkWidget * table,gint i)643 static GtkWidget *addNWChemChargeToTable(GtkWidget *table, gint i)
644 {
645 GtkWidget* entryCharge = NULL;
646 GtkWidget* comboCharge = NULL;
647 gint nlistCharge = 1;
648 gchar* listCharge[] = {"0"};
649
650 add_label_table(table,_("Charge"),(gushort)i,0);
651 add_label_table(table,":",(gushort)i,1);
652 entryCharge = addComboListToATable(table, listCharge, nlistCharge, i, 2, 1);
653 comboCharge = g_object_get_data(G_OBJECT (entryCharge), "Combo");
654 gtk_widget_set_sensitive(entryCharge, FALSE);
655
656 return comboCharge;
657 }
658 /***********************************************************************************************/
addNWChemSpinToTable(GtkWidget * table,gint i)659 static GtkWidget *addNWChemSpinToTable(GtkWidget *table, gint i)
660 {
661 GtkWidget* entrySpinMultiplicity = NULL;
662 GtkWidget* comboSpinMultiplicity = NULL;
663 gint nlistspinMultiplicity = 1;
664 gchar* listspinMultiplicity[] = {"0"};
665
666 add_label_table(table,_("Spin multiplicity"),(gushort)i,0);
667 add_label_table(table,":",(gushort)i,1);
668 entrySpinMultiplicity = addComboListToATable(table, listspinMultiplicity, nlistspinMultiplicity, i, 2, 1);
669 comboSpinMultiplicity = g_object_get_data(G_OBJECT (entrySpinMultiplicity), "Combo");
670 gtk_widget_set_sensitive(entrySpinMultiplicity, FALSE);
671
672 g_signal_connect(G_OBJECT(entrySpinMultiplicity),"changed", G_CALLBACK(changedEntrySpinMultiplicity),NULL);
673 return comboSpinMultiplicity;
674 }
675 /***********************************************************************************************/
addLabelNumberOfElectronsToTable(GtkWidget * table,gint i,GtkWidget * comboCharge)676 static GtkWidget *addLabelNumberOfElectronsToTable(GtkWidget *table, gint i, GtkWidget *comboCharge)
677 {
678 GtkWidget* labelNumberOfElectrons = NULL;
679 GtkWidget* hbox = NULL;
680 GtkWidget* entryCharge = GTK_BIN(comboCharge)->child;
681
682 labelNumberOfElectrons = gtk_label_new(" ");
683 hbox = gtk_hbox_new(0,FALSE);
684 gtk_box_pack_start (GTK_BOX (hbox), labelNumberOfElectrons, FALSE, FALSE, 0);
685 gtk_table_attach(GTK_TABLE(table),hbox,0,0+3,i,i+1,
686 (GtkAttachOptions) (GTK_FILL | GTK_EXPAND),
687 (GtkAttachOptions) (GTK_FILL | GTK_SHRINK),
688 2,2);
689
690 g_object_set_data(G_OBJECT (entryCharge), "LabelNumberOfElectrons", labelNumberOfElectrons);
691 g_signal_connect(G_OBJECT(entryCharge),"changed", G_CALLBACK(changedEntryCharge),NULL);
692 return labelNumberOfElectrons;
693 }
694 /***********************************************************************************************/
createNWChemChargeMultiplicityFrame(GtkWidget * box)695 void createNWChemChargeMultiplicityFrame(GtkWidget *box)
696 {
697 GtkWidget* frame;
698 GtkWidget* sep;
699 GtkWidget* labelNumberOfElectrons;
700 GtkWidget* vboxFrame;
701 GtkWidget* comboSpinMultiplicity = NULL;
702 GtkWidget* comboCharge = NULL;
703 GtkWidget *table = NULL;
704 gint i;
705
706 totalCharge = TotalCharges[0];
707 spinMultiplicity=SpinMultiplicities[0];
708
709 table = gtk_table_new(3,5,FALSE);
710
711 frame = gtk_frame_new (_("Charge & Multiplicty"));
712 gtk_widget_show (frame);
713 gtk_box_pack_start (GTK_BOX (box), frame, TRUE, TRUE, 3);
714 gtk_frame_set_label_align (GTK_FRAME (frame), 0.5, 0.5);
715
716 vboxFrame = gtk_vbox_new (FALSE, 3);
717 gtk_widget_show (vboxFrame);
718 gtk_container_add (GTK_CONTAINER (frame), vboxFrame);
719
720 gtk_box_pack_start (GTK_BOX (vboxFrame), table, TRUE, TRUE, 0);
721
722 i = 0;
723 comboCharge = addNWChemChargeToTable(table, i);
724 i = 1;
725 comboSpinMultiplicity = addNWChemSpinToTable(table, i);
726 i = 2;
727 sep = gtk_hseparator_new ();;
728 gtk_table_attach(GTK_TABLE(table),sep,0,0+3,i,i+1,
729 (GtkAttachOptions) (GTK_FILL | GTK_EXPAND),
730 (GtkAttachOptions) (GTK_FILL | GTK_EXPAND),
731 2,2);
732
733 i = 3;
734 labelNumberOfElectrons=addLabelNumberOfElectronsToTable(table, i, comboCharge);
735
736 if(GTK_IS_COMBO_BOX(comboCharge))
737 g_object_set_data(G_OBJECT (GTK_BIN(comboCharge)->child), "ComboSpinMultiplicity", comboSpinMultiplicity);
738 setComboCharge(comboCharge);
739 setComboSpinMultiplicity(comboSpinMultiplicity);
740 if(GTK_IS_WIDGET(labelNumberOfElectrons))
741 {
742 gint ne = nwchemMolecule.numberOfValenceElectrons - totalCharge;
743 gchar buffer[BSIZE];
744 sprintf(buffer, "Number of electrons = %d",ne);
745 gtk_label_set_text(GTK_LABEL(labelNumberOfElectrons),buffer);
746 }
747
748 /* activate sensitivity */
749 /*
750 if(GTK_IS_WIDGET(comboMethod)) setComboMethod(comboMethod);
751 g_object_set_data(G_OBJECT (box), "EntryMethod", GTK_BIN(comboMethod)->child);
752 */
753 }
754 /************************************************************************************************************/
755