1 /* PsicodeMolecule.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 "../Psicode/PsicodeTypes.h"
27 #include "../Psicode/PsicodeGlobal.h"
28 #include "../Psicode/PsicodeKeywords.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 /************************************************************************************************************/
getPsicodeMultiplicity()49 gint getPsicodeMultiplicity()
50 {
51 return spinMultiplicity;
52 }
53 /************************************************************************************************************/
initPsicodeMoleculeButtons()54 void initPsicodeMoleculeButtons()
55 {
56 }
57 /************************************************************************************************************/
initPsicodeMolecule()58 void initPsicodeMolecule()
59 {
60 psicodeMolecule.listOfAtoms = NULL;
61 psicodeMolecule.totalNumberOfElectrons = 0;
62 psicodeMolecule.numberOfValenceElectrons = 0;
63 psicodeMolecule.numberOfAtoms = 0;
64 }
65 /************************************************************************************************************/
freePsicodeMolecule()66 void freePsicodeMolecule()
67 {
68 static gboolean first = TRUE;
69
70 if(first)
71 {
72 initPsicodeMolecule();
73 first = FALSE;
74 return;
75 }
76
77 if(psicodeMolecule.listOfAtoms) g_free(psicodeMolecule.listOfAtoms);
78 initPsicodeMolecule();
79 }
80 /************************************************************************************************************/
setPsicodeMoleculeFromSXYZ(gint nAtoms,gchar ** symbols,gdouble * X,gdouble * Y,gdouble * Z)81 static gint setPsicodeMoleculeFromSXYZ(gint nAtoms, gchar** symbols, gdouble* X, gdouble* Y, gdouble* Z)
82 {
83 gint n;
84 PsicodeAtom* atomList = NULL;
85
86 psicodeMolecule.listOfAtoms = NULL;
87 psicodeMolecule.numberOfAtoms = 0;
88 if(nAtoms<1) return 1;
89
90 psicodeMolecule.listOfAtoms = (PsicodeAtom*)g_malloc(sizeof(PsicodeAtom)*(nAtoms));
91 if(psicodeMolecule.listOfAtoms==NULL) return -1;
92
93 psicodeMolecule.numberOfAtoms = nAtoms;
94
95 atomList = psicodeMolecule.listOfAtoms;
96 for(n=0; n<psicodeMolecule.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 /************************************************************************************************************/
setPsicodeMoleculeFromGeomXYZ()131 static gboolean setPsicodeMoleculeFromGeomXYZ()
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 psicodeMolecule.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 psicodeMolecule.totalNumberOfElectrons += prop.atomicNumber;
161 }
162 psicodeMolecule.numberOfValenceElectrons = psicodeMolecule.totalNumberOfElectrons;
163 setPsicodeMoleculeFromSXYZ(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 /************************************************************************************************************/
setPsicodeMoleculeFromGeomZMatrix()173 static gboolean setPsicodeMoleculeFromGeomZMatrix()
174 {
175 iprogram=PROG_IS_PSICODE;
176 if(!zmat_to_xyz()) return FALSE;
177 delete_dummy_atoms();
178 /* conversion_zmat_to_xyz();*/
179 return setPsicodeMoleculeFromGeomXYZ();
180 }
181 /************************************************************************************************************/
setPsicodeMolecule()182 gboolean setPsicodeMolecule()
183 {
184 freePsicodeMolecule();
185 if(MethodeGeom==GEOM_IS_XYZ && setPsicodeMoleculeFromGeomXYZ()) return TRUE;
186 if(setPsicodeMoleculeFromGeomZMatrix()) return TRUE;
187 return FALSE;
188 }
189 /************************************************************************************************************/
setPsicodeGeometryFromInputFile(gchar * fileName)190 void setPsicodeGeometryFromInputFile(gchar* fileName)
191 {
192 read_XYZ_from_psicode_input_file(fileName);
193 setPsicodeMolecule();
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 = psicodeMolecule.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(psicodeMolecule.listOfAtoms[i].symbol);
239 X[i] = psicodeMolecule.listOfAtoms[i].position[0];
240 Y[i] = psicodeMolecule.listOfAtoms[i].position[1];
241 Z[i] = psicodeMolecule.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 PsicodeAtom* atomList = psicodeMolecule.listOfAtoms;
270 for(i=0; i<psicodeMolecule.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 /*************************************************************************************************************/
putPsicodeMoleculeInTextEditor()333 static void putPsicodeMoleculeInTextEditor()
334 {
335 gchar buffer[BSIZE];
336 gint i;
337 gint nV = 0;
338 gdouble x,y,z;
339
340 if(psicodeMolecule.numberOfAtoms<1) return;
341
342 if(MethodeGeom==GEOM_IS_XYZ)
343 {
344 sprintf(buffer,"\nmolecule mymol {\n");
345 gabedit_text_insert (GABEDIT_TEXT(text), NULL, &psicodeColorFore.keyWord, &psicodeColorBack.keyWord, buffer, -1);
346 sprintf(buffer," %d %d\n",totalCharge, SpinMultiplicities[0]);
347 gabedit_text_insert (GABEDIT_TEXT(text), NULL, NULL, NULL, buffer, -1);
348 for (i=0;i<psicodeMolecule.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",psicodeMolecule.listOfAtoms[i].symbol, X,Y,Z);
358 gabedit_text_insert (GABEDIT_TEXT(text), NULL, NULL, NULL, buffer, -1);
359 }
360 if(strstr(getPsicodeExcitedMethod(),"EOM")||strstr(getPsicodeExcitedMethod(),"TDDFT") || strstr(getPsicodeTypeMethod(),"HL-"))
361 {
362 if(!testAbelianGroup())
363 gabedit_text_insert (GABEDIT_TEXT(text), NULL, NULL, NULL, " symmetry C1\n", -1);
364 }
365 nV = 0;
366 if(NVariablesXYZ>0)
367 for(i=0;i<NVariablesXYZ;i++)
368 {
369 if(VariablesXYZ[i].Used) nV++;
370 }
371 if(nV>0 && nV!= 3*psicodeMolecule.numberOfAtoms)
372 {
373 sprintf(buffer,"\nconstraints\n");
374 gabedit_text_insert (GABEDIT_TEXT(text), NULL, &psicodeColorFore.keyWord, &psicodeColorBack.keyWord, buffer, -1);
375 for (i=0;i<psicodeMolecule.numberOfAtoms;i++)
376 {
377 if(!(!test(GeomXYZ[i].X) || !test(GeomXYZ[i].Y) || !test(GeomXYZ[i].Z)))
378 {
379 sprintf(buffer," fix atom %d\n",i+1);
380 gabedit_text_insert (GABEDIT_TEXT(text), NULL, NULL, NULL,buffer,-1);
381 }
382 }
383 }
384 sprintf(buffer,"}\n");
385 gabedit_text_insert (GABEDIT_TEXT(text), NULL, &psicodeColorFore.keyWord, &psicodeColorBack.keyWord, buffer, -1);
386 }
387 else
388 {
389 sprintf(buffer,"\nmolecule mymol {\n");
390 gabedit_text_insert (GABEDIT_TEXT(text), NULL, &psicodeColorFore.keyWord, &psicodeColorBack.keyWord, buffer, -1);
391 sprintf(buffer," %d %d\n",totalCharge, SpinMultiplicities[0]);
392 gabedit_text_insert (GABEDIT_TEXT(text), NULL, NULL, NULL, buffer, -1);
393 for(i=0;i<NcentersZmat;i++)
394 {
395 SAtomsProp prop = prop_atom_get(Geom[i].Symb);
396 gchar *line;
397 gabedit_text_insert (GABEDIT_TEXT(text), NULL, NULL, NULL," ",-1);
398 line=g_strdup_printf("%s",Geom[i].Symb);
399 if(Geom[i].Nentry>NUMBER_ENTRY_0) line=g_strdup_printf("%s\t%s\t%s",line,Geom[i].NR,Geom[i].R);
400 if(Geom[i].Nentry>NUMBER_ENTRY_R) line=g_strdup_printf("%s\t%s\t%s",line,Geom[i].NAngle,Geom[i].Angle);
401 if(Geom[i].Nentry>NUMBER_ENTRY_ANGLE) line=g_strdup_printf("%s\t%s\t%s",line,Geom[i].NDihedral,Geom[i].Dihedral);
402 line=g_strdup_printf("%s\n",line);
403 prop = prop_atom_get(Geom[i].Symb);
404 gabedit_text_insert (GABEDIT_TEXT(text), NULL,NULL, &prop.color,line,-1);
405 g_free(line);
406 }
407 if(NVariables>0)
408 {
409 gint nV = 0;
410 for(i=0;i<NVariables;i++)
411 {
412 if(Variables[i].Used)
413 {
414 gabedit_text_insert (GABEDIT_TEXT(text), NULL, NULL, NULL," \n",-1);
415 nV++;
416 break;
417 }
418 }
419 for(i=0;i<NVariables;i++)
420 {
421 if(Variables[i].Used)
422 {
423 gchar* line=g_strdup_printf(" %s\t%s\n",Variables[i].Name,Variables[i].Value);
424 gabedit_text_insert (GABEDIT_TEXT(text), NULL, NULL, NULL,line,-1);
425 g_free(line);
426 }
427 }
428 }
429 gabedit_text_insert (GABEDIT_TEXT(text), NULL, &psicodeColorFore.keyWord, &psicodeColorBack.keyWord,"}\n",-1);
430 }
431
432 }
433 /************************************************************************************************************/
putPsicodeMoleculeInfoInTextEditor()434 void putPsicodeMoleculeInfoInTextEditor()
435 {
436 putPsicodeMoleculeInTextEditor();
437 }
438 /************************************************************************************************************/
439 /*
440 static GtkWidget* addRadioButtonToATable(GtkWidget* table, GtkWidget* friendButton, gchar* label, gint i, gint j, gint k)
441 {
442 GtkWidget *newButton;
443
444 if(friendButton)
445 newButton = gtk_radio_button_new_with_label( gtk_radio_button_get_group (GTK_RADIO_BUTTON (friendButton)), label);
446 else
447 newButton = gtk_radio_button_new_with_label( NULL, label);
448
449 gtk_table_attach(GTK_TABLE(table),newButton,j,j+k,i,i+1,
450 (GtkAttachOptions) (GTK_FILL | GTK_EXPAND),
451 (GtkAttachOptions) (GTK_FILL | GTK_EXPAND),
452 2,2);
453
454 g_object_set_data(G_OBJECT (newButton), "Label",NULL);
455 g_object_set_data(G_OBJECT (newButton), "Type",NULL);
456 return newButton;
457 }
458 */
459 /********************************************************************************/
setSpinMultiplicityComboSpinMultiplicity(GtkWidget * comboSpinMultiplicity,gint spin)460 static void setSpinMultiplicityComboSpinMultiplicity(GtkWidget *comboSpinMultiplicity, gint spin)
461 {
462 GtkWidget *entry = NULL;
463 gchar* t = NULL;
464 if(!comboSpinMultiplicity) return;
465 entry = GTK_BIN (comboSpinMultiplicity)->child;
466 t = g_strdup_printf("%d",spin);
467 gtk_entry_set_text(GTK_ENTRY(entry),t);
468 g_free(t);
469 }
470 /************************************************************************************************************/
setComboSpinMultiplicity(GtkWidget * comboSpinMultiplicity)471 static void setComboSpinMultiplicity(GtkWidget *comboSpinMultiplicity)
472 {
473 GList *glist = NULL;
474 gint i;
475 gint nlist = 0;
476 gchar** list = NULL;
477 gint k;
478 gint kinc;
479 gint ne = psicodeMolecule.numberOfValenceElectrons - totalCharge;
480
481 if(ne%2==0) nlist = ne/2+1;
482 else nlist = (ne+1)/2;
483
484 if(nlist<1) return;
485 list = g_malloc(nlist*sizeof(gchar*));
486 if(!list) return;
487 for(i=0;i<nlist;i++)
488 list[i] = g_malloc(10*sizeof(gchar));
489
490
491 if(GTK_IS_WIDGET(comboSpinMultiplicity)) gtk_widget_set_sensitive(comboSpinMultiplicity, TRUE);
492 if(ne%2==0) k = 1;
493 else k = 2;
494
495 kinc = 2;
496 for(i=0;i<nlist;i++)
497 {
498 sprintf(list[i],"%d",k);
499 k+=kinc;
500 }
501
502 for(i=0;i<nlist;i++) glist = g_list_append(glist,list[i]);
503
504 gtk_combo_box_entry_set_popdown_strings( comboSpinMultiplicity, glist) ;
505 g_list_free(glist);
506 if( SpinMultiplicities[0]%2 == atoi(list[0])%2) setSpinMultiplicityComboSpinMultiplicity(comboSpinMultiplicity, SpinMultiplicities[0]);
507 else SpinMultiplicities[0] = atoi(list[0]);
508 if(list)
509 {
510 for(i=0;i<nlist;i++) if(list[i]) g_free(list[i]);
511 g_free(list);
512 }
513 }
514 /********************************************************************************/
setChargeComboCharge(GtkWidget * comboCharge,gint charge)515 static void setChargeComboCharge(GtkWidget *comboCharge, gint charge)
516 {
517 GtkWidget *entry = NULL;
518 gchar* t = NULL;
519 if(!comboCharge) return;
520 entry = GTK_BIN (comboCharge)->child;
521 t = g_strdup_printf("%d",charge);
522 gtk_entry_set_text(GTK_ENTRY(entry),t);
523 g_free(t);
524 }
525 /********************************************************************************/
setComboCharge(GtkWidget * comboCharge)526 static void setComboCharge(GtkWidget *comboCharge)
527 {
528 GList *glist = NULL;
529 gint i;
530 gint nlist;
531 gchar** list = NULL;
532 gint k;
533
534 nlist = psicodeMolecule.numberOfValenceElectrons*2-2+1;
535
536 if(nlist<1) return;
537 list = g_malloc(nlist*sizeof(gchar*));
538 if(!list) return;
539 for(i=0;i<nlist;i++)
540 list[i] = g_malloc(10*sizeof(gchar));
541
542
543 sprintf(list[0],"0");
544 k = 1;
545 for(i=1;i<nlist-1;i+=2)
546 {
547 sprintf(list[i],"+%d",k);
548 sprintf(list[i+1],"%d",-k);
549 k += 1;
550 }
551
552 for(i=0;i<nlist;i++) glist = g_list_append(glist,list[i]);
553
554 gtk_combo_box_entry_set_popdown_strings( comboCharge, glist) ;
555 g_list_free(glist);
556 if(list)
557 {
558 for(i=0;i<nlist;i++) if(list[i]) g_free(list[i]);
559 g_free(list);
560 }
561 setChargeComboCharge(comboCharge, totalCharge);
562 }
563 /**********************************************************************/
changedEntrySpinMultiplicity(GtkWidget * entry,gpointer data)564 static void changedEntrySpinMultiplicity(GtkWidget *entry, gpointer data)
565 {
566 G_CONST_RETURN gchar* entryText = NULL;
567
568 if(!GTK_IS_WIDGET(entry)) return;
569
570 entryText = gtk_entry_get_text(GTK_ENTRY(entry));
571 if(strlen(entryText)<1)return;
572
573 spinMultiplicity=atoi(entryText);
574 if(spinMultiplicity==1)
575 {
576 /* OK RHF*/
577 setPsicodeSCFMethod(TRUE);
578 }
579 else
580 {
581 /* remove RHF from list*/
582 setPsicodeSCFMethod(FALSE);
583 }
584 }
585 /**********************************************************************/
changedEntryCharge(GtkWidget * entry,gpointer data)586 static void changedEntryCharge(GtkWidget *entry, gpointer data)
587 {
588 G_CONST_RETURN gchar* entryText = NULL;
589 GtkWidget* comboSpinMultiplicity = NULL;
590 GtkWidget* labelNumberOfElectrons = NULL;
591
592 if(!GTK_IS_WIDGET(entry)) return;
593
594 entryText = gtk_entry_get_text(GTK_ENTRY(entry));
595 if(strlen(entryText)<1)return;
596
597 totalCharge = atoi(entryText);
598 TotalCharges[0] = totalCharge;
599
600 comboSpinMultiplicity = g_object_get_data(G_OBJECT (entry), "ComboSpinMultiplicity");
601 if(GTK_IS_WIDGET(comboSpinMultiplicity)) setComboSpinMultiplicity(comboSpinMultiplicity);
602
603 labelNumberOfElectrons = g_object_get_data(G_OBJECT (entry), "LabelNumberOfElectrons");
604
605 if(GTK_IS_WIDGET(labelNumberOfElectrons))
606 {
607 gint ne = psicodeMolecule.numberOfValenceElectrons - totalCharge;
608 gchar buffer[BSIZE];
609 sprintf(buffer, "Number of electrons = %d",ne);
610 gtk_label_set_text(GTK_LABEL(labelNumberOfElectrons),buffer);
611 }
612 }
613 /**********************************************************************/
addComboListToATable(GtkWidget * table,gchar ** list,gint nlist,gint i,gint j,gint k)614 static GtkWidget* addComboListToATable(GtkWidget* table,
615 gchar** list, gint nlist, gint i, gint j, gint k)
616 {
617 GtkWidget *entry = NULL;
618 GtkWidget *combo = NULL;
619
620 combo = create_combo_box_entry(list, nlist, TRUE, -1, -1);
621
622 gtk_table_attach(GTK_TABLE(table),combo,j,j+k,i,i+1,
623 (GtkAttachOptions) (GTK_FILL | GTK_EXPAND),
624 (GtkAttachOptions) (GTK_FILL | GTK_SHRINK),
625 2,2);
626 entry = GTK_BIN (combo)->child;
627 g_object_set_data(G_OBJECT (entry), "Combo",combo);
628 gtk_widget_set_size_request(GTK_WIDGET(entry),(gint)(ScreenHeight*0.2),-1);
629
630 return entry;
631 }
632 /***********************************************************************************************/
addPsicodeChargeToTable(GtkWidget * table,gint i)633 static GtkWidget *addPsicodeChargeToTable(GtkWidget *table, gint i)
634 {
635 GtkWidget* entryCharge = NULL;
636 GtkWidget* comboCharge = NULL;
637 gint nlistCharge = 1;
638 gchar* listCharge[] = {"0"};
639
640 add_label_table(table,_("Charge"),(gushort)i,0);
641 add_label_table(table,":",(gushort)i,1);
642 entryCharge = addComboListToATable(table, listCharge, nlistCharge, i, 2, 1);
643 comboCharge = g_object_get_data(G_OBJECT (entryCharge), "Combo");
644 gtk_widget_set_sensitive(entryCharge, FALSE);
645
646 return comboCharge;
647 }
648 /***********************************************************************************************/
addPsicodeSpinToTable(GtkWidget * table,gint i)649 static GtkWidget *addPsicodeSpinToTable(GtkWidget *table, gint i)
650 {
651 GtkWidget* entrySpinMultiplicity = NULL;
652 GtkWidget* comboSpinMultiplicity = NULL;
653 gint nlistspinMultiplicity = 1;
654 gchar* listspinMultiplicity[] = {"0"};
655
656 add_label_table(table,_("Spin multiplicity"),(gushort)i,0);
657 add_label_table(table,":",(gushort)i,1);
658 entrySpinMultiplicity = addComboListToATable(table, listspinMultiplicity, nlistspinMultiplicity, i, 2, 1);
659 comboSpinMultiplicity = g_object_get_data(G_OBJECT (entrySpinMultiplicity), "Combo");
660 gtk_widget_set_sensitive(entrySpinMultiplicity, FALSE);
661
662 g_signal_connect(G_OBJECT(entrySpinMultiplicity),"changed", G_CALLBACK(changedEntrySpinMultiplicity),NULL);
663 return comboSpinMultiplicity;
664 }
665 /***********************************************************************************************/
addLabelNumberOfElectronsToTable(GtkWidget * table,gint i,GtkWidget * comboCharge)666 static GtkWidget *addLabelNumberOfElectronsToTable(GtkWidget *table, gint i, GtkWidget *comboCharge)
667 {
668 GtkWidget* labelNumberOfElectrons = NULL;
669 GtkWidget* hbox = NULL;
670 GtkWidget* entryCharge = GTK_BIN(comboCharge)->child;
671
672 labelNumberOfElectrons = gtk_label_new(" ");
673 hbox = gtk_hbox_new(0,FALSE);
674 gtk_box_pack_start (GTK_BOX (hbox), labelNumberOfElectrons, FALSE, FALSE, 0);
675 gtk_table_attach(GTK_TABLE(table),hbox,0,0+3,i,i+1,
676 (GtkAttachOptions) (GTK_FILL | GTK_EXPAND),
677 (GtkAttachOptions) (GTK_FILL | GTK_SHRINK),
678 2,2);
679
680 g_object_set_data(G_OBJECT (entryCharge), "LabelNumberOfElectrons", labelNumberOfElectrons);
681 g_signal_connect(G_OBJECT(entryCharge),"changed", G_CALLBACK(changedEntryCharge),NULL);
682 return labelNumberOfElectrons;
683 }
684 /***********************************************************************************************/
createPsicodeChargeMultiplicityFrame(GtkWidget * box)685 void createPsicodeChargeMultiplicityFrame(GtkWidget *box)
686 {
687 GtkWidget* frame;
688 GtkWidget* sep;
689 GtkWidget* labelNumberOfElectrons;
690 GtkWidget* vboxFrame;
691 GtkWidget* comboSpinMultiplicity = NULL;
692 GtkWidget* comboCharge = NULL;
693 GtkWidget *table = NULL;
694 gint i;
695
696 totalCharge = TotalCharges[0];
697 spinMultiplicity=SpinMultiplicities[0];
698
699 table = gtk_table_new(3,5,FALSE);
700
701 frame = gtk_frame_new (_("Charge & Multiplicty"));
702 gtk_widget_show (frame);
703 gtk_box_pack_start (GTK_BOX (box), frame, TRUE, TRUE, 3);
704 gtk_frame_set_label_align (GTK_FRAME (frame), 0.5, 0.5);
705
706 vboxFrame = gtk_vbox_new (FALSE, 3);
707 gtk_widget_show (vboxFrame);
708 gtk_container_add (GTK_CONTAINER (frame), vboxFrame);
709
710 gtk_box_pack_start (GTK_BOX (vboxFrame), table, TRUE, TRUE, 0);
711
712 i = 0;
713 comboCharge = addPsicodeChargeToTable(table, i);
714 i = 1;
715 comboSpinMultiplicity = addPsicodeSpinToTable(table, i);
716 i = 2;
717 sep = gtk_hseparator_new ();;
718 gtk_table_attach(GTK_TABLE(table),sep,0,0+3,i,i+1,
719 (GtkAttachOptions) (GTK_FILL | GTK_EXPAND),
720 (GtkAttachOptions) (GTK_FILL | GTK_EXPAND),
721 2,2);
722
723 i = 3;
724 labelNumberOfElectrons=addLabelNumberOfElectronsToTable(table, i, comboCharge);
725
726 if(GTK_IS_COMBO_BOX(comboCharge))
727 g_object_set_data(G_OBJECT (GTK_BIN(comboCharge)->child), "ComboSpinMultiplicity", comboSpinMultiplicity);
728 setComboCharge(comboCharge);
729 setComboSpinMultiplicity(comboSpinMultiplicity);
730 if(GTK_IS_WIDGET(labelNumberOfElectrons))
731 {
732 gint ne = psicodeMolecule.numberOfValenceElectrons - totalCharge;
733 gchar buffer[BSIZE];
734 sprintf(buffer, "Number of electrons = %d",ne);
735 gtk_label_set_text(GTK_LABEL(labelNumberOfElectrons),buffer);
736 }
737
738 /* activate sensitivity */
739 /*
740 if(GTK_IS_WIDGET(comboMethod)) setComboMethod(comboMethod);
741 g_object_set_data(G_OBJECT (box), "EntryMethod", GTK_BIN(comboMethod)->child);
742 */
743 }
744 /************************************************************************************************************/
745