1 /* GamessMolecule.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 "../Gamess/GamessTypes.h"
27 #include "../Gamess/GamessGlobal.h"
28 #include "../Gamess/GamessControl.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/AtomsProp.h"
41 #include "../Symmetry/MoleculeSymmetry.h"
42 #include "../Symmetry/MoleculeSymmetryInterface.h"
43 
44 /************************************************************************************************************/
45 typedef enum
46 {
47 	GABEDIT = 0, GABFIXED
48 }TypeOfSymmetryButton;
49 
50 
51 static gboolean symReduction = TRUE;
52 static GtkWidget* labelSymmetry = NULL;
53 static GtkWidget *buttonTolerance = NULL;
54 static GtkWidget *buttonSymWithCalc = NULL;
55 /************************************************************************************************************/
56 static gint totalCharge = 0;
57 static gint spinMultiplicity=1;
58 /************************************************************************************************************/
getGamessMultiplicity()59 gint getGamessMultiplicity()
60 {
61 	return spinMultiplicity;
62 }
63 /************************************************************************************************************/
initGamessMoleculeButtons()64 void initGamessMoleculeButtons()
65 {
66 	labelSymmetry = NULL;
67 	buttonTolerance = NULL;
68 	buttonSymWithCalc = NULL;
69 }
70 /************************************************************************************************************/
initGamessMolecule()71 void initGamessMolecule()
72 {
73 	gamessMolecule.listOfAtoms = NULL;
74 	gamessMolecule.totalNumberOfElectrons = 0;
75 	gamessMolecule.numberOfValenceElectrons = 0;
76 	gamessMolecule.numberOfAtoms = 0;
77 	gamessMolecule.groupSymmetry = NULL;
78 }
79 /************************************************************************************************************/
freeGamessMolecule()80 void freeGamessMolecule()
81 {
82 	static gboolean first = TRUE;
83 
84 	if(first)
85 	{
86 		initGamessMolecule();
87 		first = FALSE;
88 		return;
89 	}
90 
91 	if(gamessMolecule.listOfAtoms) g_free(gamessMolecule.listOfAtoms);
92 	if(gamessMolecule.groupSymmetry) g_free(gamessMolecule.groupSymmetry);
93 	initGamessMolecule();
94 }
95 /************************************************************************************************************/
setGamessMoleculeFromSXYZ(gint nAtoms,gchar ** symbols,gdouble * X,gdouble * Y,gdouble * Z)96 static gint setGamessMoleculeFromSXYZ(gint nAtoms, gchar** symbols, gdouble* X, gdouble* Y, gdouble* Z)
97 {
98 	gint n;
99 	GamessAtom* atomList = NULL;
100 
101 	gamessMolecule.listOfAtoms = NULL;
102 	gamessMolecule.numberOfAtoms = 0;
103 	if(nAtoms<1) return 1;
104 
105 	gamessMolecule.listOfAtoms = (GamessAtom*)g_malloc(sizeof(GamessAtom)*(nAtoms));
106 	if(gamessMolecule.listOfAtoms==NULL) return -1;
107 
108 	gamessMolecule.numberOfAtoms = nAtoms;
109 
110 	atomList = gamessMolecule.listOfAtoms;
111 	for(n=0; n<gamessMolecule.numberOfAtoms; n++)
112 	{
113 		atomList->position[0]  = X[n];
114 		atomList->position[1]  = Y[n];
115 		atomList->position[2]  = Z[n];
116 		atomList->symbol  = g_strdup(symbols[n]);
117 		atomList++;
118 	}
119 
120 	return 0;
121 }
122 /************************************************************************************************************/
setXYZFromGeomXYZ(gint i,gdouble * x,gdouble * y,gdouble * z)123 static void setXYZFromGeomXYZ(gint i, gdouble* x, gdouble* y, gdouble *z)
124 {
125   	if(!test(GeomXYZ[i].X))
126     		*x = get_value_variableXYZ(GeomXYZ[i].X);
127   	else
128     		*x = atof(GeomXYZ[i].X);
129   	if(!test(GeomXYZ[i].Y))
130     		*y = get_value_variableXYZ(GeomXYZ[i].Y);
131   	else
132     		*y = atof(GeomXYZ[i].Y);
133   	if(!test(GeomXYZ[i].Z))
134     		*z = get_value_variableXYZ(GeomXYZ[i].Z);
135   	else
136     		*z = atof(GeomXYZ[i].Z);
137 
138          if(Units==0)
139          {
140               *x *= BOHR_TO_ANG;
141               *y *= BOHR_TO_ANG;
142               *z *= BOHR_TO_ANG;
143          }
144 }
145 /************************************************************************************************************/
setGamessFormatGroup(gchar * pointGroupSymbol,gchar * gamessName)146 static void setGamessFormatGroup(gchar* pointGroupSymbol, gchar* gamessName)
147 {
148 	if(!pointGroupSymbol) return;
149 	if(strlen(pointGroupSymbol)<2 || strcmp(pointGroupSymbol,"C1")==0)
150 	{
151 		sprintf(gamessName,"%s",pointGroupSymbol);
152 		return;
153 	}
154 	if(strcmp(pointGroupSymbol,"Cinfv")==0)
155 	{
156 		sprintf(gamessName,"Cnv  4");
157 		return;
158 	}
159 	if(strcmp(pointGroupSymbol,"Dinfh")==0)
160 	{
161 		sprintf(gamessName,"Dnh  4");
162 		return;
163 	}
164 	if(isdigit(pointGroupSymbol[1]))
165 	{
166 		gchar a[3];
167 		sprintf(a,"%c",pointGroupSymbol[1]);
168 		gint n=atoi(a);
169 		if(pointGroupSymbol[0] !='S')
170 		{
171 			if(strlen(pointGroupSymbol)>2)
172 			sprintf(gamessName,"%cn%c %d",pointGroupSymbol[0],pointGroupSymbol[2],n);
173 			else
174 			sprintf(gamessName,"%cn %d",pointGroupSymbol[0],n);
175 		}
176 		else sprintf(gamessName,"%c2n %d",pointGroupSymbol[0],n/2);
177 		return;
178 	}
179 	sprintf(gamessName,"%s",pointGroupSymbol);
180 	return;
181 }
182 /************************************************************************************************************/
computeGroupSymmetry()183 static gchar* computeGroupSymmetry()
184 {
185 	gint i;
186 	gchar** symbols = NULL;
187 	gdouble* X = NULL;
188 	gdouble* Y = NULL;
189 	gdouble* Z = NULL;
190 	gint numberOfAtoms = gamessMolecule.numberOfAtoms;
191 	gchar pointGroupSymbol[BSIZE];
192 	gchar message[BSIZE];
193 	gint maximalOrder = 8;
194 	gdouble principalAxisTolerance = getTolerancePrincipalAxis();
195 	gdouble positionTolerance = getTolerancePosition();
196 
197 	if(numberOfAtoms<1) return NULL;
198 
199 
200 	symbols = (gchar**)g_malloc(sizeof(gchar*)*(numberOfAtoms));
201 	if(symbols == NULL) return NULL;
202 
203 	X = (gdouble*)g_malloc(sizeof(gdouble)*(numberOfAtoms));
204 	if(X == NULL) return NULL;
205 	Y = (gdouble*)g_malloc(sizeof(gdouble)*(numberOfAtoms));
206 	if(Y == NULL) return NULL;
207 	Z = (gdouble*)g_malloc(sizeof(gdouble)*(numberOfAtoms));
208 	if(Z == NULL) return NULL;
209 
210 	for(i=0; i<numberOfAtoms; i++)
211 	{
212 		symbols[i] = g_strdup(gamessMolecule.listOfAtoms[i].symbol);
213 		X[i] = gamessMolecule.listOfAtoms[i].position[0];
214 		Y[i] = gamessMolecule.listOfAtoms[i].position[1];
215 		Z[i] = gamessMolecule.listOfAtoms[i].position[2];
216 	}
217 	sprintf(pointGroupSymbol,"NO");
218 	computeSymmetryOld(principalAxisTolerance, FALSE, pointGroupSymbol,maximalOrder, TRUE, &numberOfAtoms,symbols, X, Y, Z, &positionTolerance, message);
219 
220 
221 	for (i=0;i<(gint)numberOfAtoms;i++) g_free( symbols[i]);
222 	g_free( symbols);
223 	g_free(X);
224 	g_free(Y);
225 	g_free(Z);
226 	return g_strdup(pointGroupSymbol);
227 }
228 /************************************************************************************************************/
setGamessMoleculeFromGeomXYZ()229 static gboolean setGamessMoleculeFromGeomXYZ()
230 {
231 	gint i;
232 	gchar** symbols = NULL;
233 	gdouble* X = NULL;
234 	gdouble* Y = NULL;
235 	gdouble* Z = NULL;
236 	gint numberOfAtoms = NcentersXYZ;
237 
238 	if(numberOfAtoms<1) return FALSE;
239 
240 	symbols = (gchar**)g_malloc(sizeof(gchar*)*(numberOfAtoms));
241 
242 	if(symbols == NULL) return FALSE;
243 
244 	X = (gdouble*)g_malloc(sizeof(gdouble)*(numberOfAtoms));
245 	if(X == NULL) return FALSE;
246 	Y = (gdouble*)g_malloc(sizeof(gdouble)*(numberOfAtoms));
247 	if(Y == NULL) return FALSE;
248 	Z = (gdouble*)g_malloc(sizeof(gdouble)*(numberOfAtoms));
249 	if(Z == NULL) return FALSE;
250 
251 	gamessMolecule.totalNumberOfElectrons = 0;
252 	for(i=0; i<numberOfAtoms; i++)
253 	{
254 		SAtomsProp prop = prop_atom_get(GeomXYZ[i].Symb);
255 
256 		symbols[i] = g_strdup(GeomXYZ[i].Symb);
257 		setXYZFromGeomXYZ(i, &X[i] , &Y[i] , &Z[i]);
258 		gamessMolecule.totalNumberOfElectrons += prop.atomicNumber;
259 	}
260 	gamessMolecule.numberOfValenceElectrons = gamessMolecule.totalNumberOfElectrons;
261 	setGamessMoleculeFromSXYZ(numberOfAtoms, symbols, X, Y, Z);
262 	gamessMolecule.groupSymmetry = computeGroupSymmetry();
263 
264 	for (i=0;i<(gint)NcentersXYZ;i++) g_free( symbols[i]);
265 	g_free( symbols);
266 	g_free(X);
267 	g_free(Y);
268 	g_free(Z);
269 	return TRUE;
270 }
271 /************************************************************************************************************/
setGamessMoleculeFromGeomZMatrix()272 static gboolean setGamessMoleculeFromGeomZMatrix()
273 {
274 	iprogram=PROG_IS_GAMESS;
275 	if(!zmat_to_xyz()) return FALSE;
276 	/* delete_dummy_atoms();*/
277 	/* conversion_zmat_to_xyz();*/
278 	return setGamessMoleculeFromGeomXYZ();
279 }
280 /************************************************************************************************************/
setGamessMolecule()281 gboolean setGamessMolecule()
282 {
283 	freeGamessMolecule();
284 	if(MethodeGeom==GEOM_IS_XYZ && setGamessMoleculeFromGeomXYZ()) return TRUE;
285 	if(setGamessMoleculeFromGeomZMatrix()) return TRUE;
286 	return FALSE;
287 }
288 /************************************************************************************************************/
setGamessGeometryFromInputFile(gchar * fileName)289 void setGamessGeometryFromInputFile(gchar* fileName)
290 {
291 	read_XYZ_from_gamess_input_file(fileName);
292 	setGamessMolecule();
293 }
294 /*************************************************************************************************************/
getRealNumberXYZVariables()295 static gint getRealNumberXYZVariables()
296 {
297 	gint k=0;
298 	gint i;
299         for(i=0;i<NcentersXYZ;i++)
300 	{
301 		if(test(GeomXYZ[i].X))k++;
302 		if(test(GeomXYZ[i].Y))k++;
303 		if(test(GeomXYZ[i].Z))k++;
304 	}
305 	return k;
306 }
307 /*************************************************************************************************************/
putGamessMoleculeXYZFixedInTextEditor()308 static void putGamessMoleculeXYZFixedInTextEditor()
309 {
310         gchar buffer[BSIZE];
311 	gint i,k,l;
312 	gint nvar = 0;
313 	gint nrvar = 0;
314 	if(MethodeGeom!=GEOM_IS_XYZ)return;
315         if(NcentersXYZ<2)return;
316 	nrvar = getRealNumberXYZVariables();
317 	nvar = 3*NcentersXYZ;
318 	if(nrvar==nvar) return;
319 	if(nrvar==0) return;
320 
321         gabedit_text_insert (GABEDIT_TEXT(text), NULL, NULL, NULL, " ",-1);
322         gabedit_text_insert (GABEDIT_TEXT(text), NULL, &gamessColorFore.keyWord, &gamessColorBack.keyWord, "$STATPT\n",-1);
323         gabedit_text_insert (GABEDIT_TEXT(text), NULL, NULL, NULL, "   IFREEZ(1)=",-1);
324 
325 	k = 0;
326 	l = 0;
327         for(i=0;i<NcentersXYZ;i++)
328 	{
329 		k++;
330 		if(test(GeomXYZ[i].X))
331 		{
332 			l++;
333 			sprintf(buffer,"%d, ",k);
334 			gabedit_text_insert (GABEDIT_TEXT(text), NULL, NULL, NULL, buffer, -1);
335 			if(l%10==0)
336         			gabedit_text_insert (GABEDIT_TEXT(text), NULL, NULL, NULL, "\n   ", -1);
337 		}
338 		k++;
339 		if(test(GeomXYZ[i].Y))
340 		{
341 			l++;
342 			sprintf(buffer,"%d, ",k);
343 			gabedit_text_insert (GABEDIT_TEXT(text), NULL, NULL, NULL, buffer, -1);
344 			if(l%10==0)
345         			gabedit_text_insert (GABEDIT_TEXT(text), NULL, NULL, NULL, "\n   ", -1);
346 		}
347 		k++;
348 		if(test(GeomXYZ[i].Z))
349 		{
350 			l++;
351 			sprintf(buffer,"%d, ",k);
352 			gabedit_text_insert (GABEDIT_TEXT(text), NULL, NULL, NULL, buffer, -1);
353 			if(l%10==0)
354         			gabedit_text_insert (GABEDIT_TEXT(text), NULL, NULL, NULL, "\n   ", -1);
355 		}
356 	}
357 	gabedit_text_insert (GABEDIT_TEXT(text), NULL, NULL, NULL, "\n ",-1);
358         gabedit_text_insert (GABEDIT_TEXT(text), NULL, &gamessColorFore.keyWord, &gamessColorBack.keyWord, "$END\n",-1);
359 }
360 /*************************************************************************************************************/
getRealNumberZmatVariables()361 static gint getRealNumberZmatVariables()
362 {
363 	gint k=0;
364 	gint i;
365         for(i=0;i<NcentersZmat;i++)
366 	{
367         	if(Geom[i].Nentry>NUMBER_ENTRY_0 && !test(Geom[i].R)) k++;
368         	if(Geom[i].Nentry>NUMBER_ENTRY_R && !test(Geom[i].Angle)) k++;
369         	if(Geom[i].Nentry>NUMBER_ENTRY_ANGLE && !test(Geom[i].Dihedral)) k++;
370 	}
371 	return k;
372 }
373 /*************************************************************************************************************/
putGamessMoleculeZMatInTextEditor()374 static void putGamessMoleculeZMatInTextEditor()
375 {
376         gchar buffer[BSIZE];
377 	gint i,k,l;
378 	gint nzvar = 0;
379 	gint nrzvar = 0;
380 	if(MethodeGeom==GEOM_IS_XYZ)return;
381         if(NcentersZmat<2)return;
382 	 if(NcentersZmat==2) nzvar = 3*NcentersZmat-5;
383 	 else nzvar = 3*NcentersZmat-6;
384 	nrzvar = getRealNumberZmatVariables();
385 
386         gabedit_text_insert (GABEDIT_TEXT(text), NULL, NULL, NULL, " ",-1);
387         gabedit_text_insert (GABEDIT_TEXT(text), NULL, &gamessColorFore.keyWord, &gamessColorBack.keyWord, "$CONTRL",-1);
388 	sprintf(buffer," COORD=ZMT NZVAR=%d ",nzvar);
389         gabedit_text_insert (GABEDIT_TEXT(text), NULL, NULL, NULL, buffer,-1);
390         gabedit_text_insert (GABEDIT_TEXT(text), NULL, &gamessColorFore.keyWord, &gamessColorBack.keyWord, "$END\n",-1);
391 
392         gabedit_text_insert (GABEDIT_TEXT(text), NULL, NULL, NULL, " ",-1);
393         gabedit_text_insert (GABEDIT_TEXT(text), NULL, &gamessColorFore.keyWord, &gamessColorBack.keyWord, "$ZMAT\n",-1);
394         gabedit_text_insert (GABEDIT_TEXT(text), NULL, NULL, NULL, "   IZMAT(1)=\n   ",-1);
395         for(i=0;i<NcentersZmat;i++)
396 	{
397         	if(Geom[i].Nentry>NUMBER_ENTRY_0)
398 		{
399 			sprintf(buffer,"1,%d,%s, ",i+1,Geom[i].NR);
400         		gabedit_text_insert (GABEDIT_TEXT(text), NULL, NULL, NULL, buffer, -1);
401 			if((i+1)%3==0)
402         		gabedit_text_insert (GABEDIT_TEXT(text), NULL, NULL, NULL, "\n   ", -1);
403 		}
404 	}
405 	if(NcentersZmat%3!=0)
406 		gabedit_text_insert (GABEDIT_TEXT(text), NULL, NULL, NULL, "\n   ", -1);
407         for(i=0;i<NcentersZmat;i++)
408 	{
409         	if(Geom[i].Nentry>NUMBER_ENTRY_R)
410 		{
411 			sprintf(buffer,"2,%d,%s,%s, ",i+1,Geom[i].NR,Geom[i].NAngle);
412         		gabedit_text_insert (GABEDIT_TEXT(text), NULL, NULL, NULL, buffer, -1);
413 			if((i+1)%3==0)
414         		gabedit_text_insert (GABEDIT_TEXT(text), NULL, NULL, NULL, "\n   ", -1);
415 		}
416 	}
417 	if(NcentersZmat%3!=0)
418 		gabedit_text_insert (GABEDIT_TEXT(text), NULL, NULL, NULL, "\n   ", -1);
419         for(i=0;i<NcentersZmat;i++)
420 	{
421         	if(Geom[i].Nentry>NUMBER_ENTRY_ANGLE)
422 		{
423 			sprintf(buffer,"3,%d,%s,%s,%s, ",i+1,Geom[i].NR,Geom[i].NAngle,Geom[i].NDihedral);
424         		gabedit_text_insert (GABEDIT_TEXT(text), NULL, NULL, NULL, buffer, -1);
425 			if((i+1)%3==0)
426         		gabedit_text_insert (GABEDIT_TEXT(text), NULL, NULL, NULL, "\n   ", -1);
427 		}
428 	}
429         gabedit_text_insert (GABEDIT_TEXT(text), NULL, NULL, NULL, "\n ",-1);
430         gabedit_text_insert (GABEDIT_TEXT(text), NULL, &gamessColorFore.keyWord, &gamessColorBack.keyWord, "$END\n",-1);
431 	if(nrzvar==nzvar) return;
432         gabedit_text_insert (GABEDIT_TEXT(text), NULL, NULL, NULL, " ",-1);
433         gabedit_text_insert (GABEDIT_TEXT(text), NULL, &gamessColorFore.keyWord, &gamessColorBack.keyWord, "$STATPT\n",-1);
434         gabedit_text_insert (GABEDIT_TEXT(text), NULL, NULL, NULL, "   IFREEZ(1)=",-1);
435 
436 	k = 0;
437 	l = 0;
438         for(i=0;i<NcentersZmat;i++)
439 	{
440         	if(Geom[i].Nentry>NUMBER_ENTRY_0)
441 		{
442 			k++;
443 			if(test(Geom[i].R))
444 			{
445 				l++;
446 				sprintf(buffer,"%d, ",k);
447 				gabedit_text_insert (GABEDIT_TEXT(text), NULL, NULL, NULL, buffer, -1);
448 				if(l%5==0)
449         			gabedit_text_insert (GABEDIT_TEXT(text), NULL, NULL, NULL, "\n   ", -1);
450 			}
451 		}
452 	}
453 	 if(l!=0 && l%5!=0) gabedit_text_insert (GABEDIT_TEXT(text), NULL, NULL, NULL, "\n    ", -1);
454 	 l = 0;
455         for(i=0;i<NcentersZmat;i++)
456 	{
457         	if(Geom[i].Nentry>NUMBER_ENTRY_R)
458 		{
459 			k++;
460 			if(test(Geom[i].Angle))
461 			{
462 				l++;
463 				sprintf(buffer,"%d, ",k);
464 				gabedit_text_insert (GABEDIT_TEXT(text), NULL, NULL, NULL, buffer, -1);
465 				if(l%5==0)
466         			gabedit_text_insert (GABEDIT_TEXT(text), NULL, NULL, NULL, "\n   ", -1);
467 			}
468 		}
469 	}
470 	 if(l!=0 && l%5!=0) gabedit_text_insert (GABEDIT_TEXT(text), NULL, NULL, NULL, "\n   ", -1);
471 	 l = 0;
472         for(i=0;i<NcentersZmat;i++)
473 	{
474         	if(Geom[i].Nentry>NUMBER_ENTRY_ANGLE)
475 		{
476 			k++;
477 			if(test(Geom[i].Dihedral))
478 			{
479 				l++;
480 				sprintf(buffer,"%d, ",k);
481 				gabedit_text_insert (GABEDIT_TEXT(text), NULL, NULL, NULL, buffer, -1);
482 				if(l%5==0)
483         			gabedit_text_insert (GABEDIT_TEXT(text), NULL, NULL, NULL, "\n   ", -1);
484 			}
485 		}
486 	}
487 	 gabedit_text_insert (GABEDIT_TEXT(text), NULL, NULL, NULL, "\n ",-1);
488         gabedit_text_insert (GABEDIT_TEXT(text), NULL, &gamessColorFore.keyWord, &gamessColorBack.keyWord, "$END\n",-1);
489 }
490 /************************************************************************/
setEpsToZero(gint n,gdouble * X,gdouble * Y,gdouble * Z,gdouble eps)491 static void setEpsToZero(gint n, gdouble* X, gdouble* Y, gdouble* Z, gdouble eps)
492 {
493 	gint i;
494 
495 	if(n<1) return;
496 	if(!X) return;
497 	if(!Y) return;
498 	if(!Z) return;
499 	if(eps<=0) eps = 1e-3;
500 
501 	for(i=0;i<n;i++)
502 	{
503 		if( fabs(X[i]) < eps) X[i] = 0;
504 		if( fabs(Y[i]) < eps) Y[i] = 0;
505 		if( fabs(Z[i]) < eps) Z[i] = 0;
506 	}
507 }
508 /************************************************************************/
build_rotation_matrix_about_an_axis(gdouble m[3][3],gdouble * vect,gdouble angle)509 static gboolean build_rotation_matrix_about_an_axis(gdouble m[3][3], gdouble* vect, gdouble angle)
510 {
511 	gdouble q[4];
512 	gdouble norm = 1;
513 	gdouble angleRad = angle/180.0*PI;
514 	gdouble vcos ;
515 	gdouble vsin ;
516 	if(!vect)return FALSE;
517 	norm = vect[0]*vect[0] + vect[1]*vect[1] + vect[2]*vect[2];
518 	norm = sqrt(norm);
519 	if(norm <1e-8) return FALSE;
520 	vect[0] /= norm;
521 	vect[1] /= norm;
522 	vect[2] /= norm;
523 	vcos = cos(angleRad/2);
524 	vsin = sin(angleRad/2);
525 	q[0] = vect[0]*vsin;
526 	q[1] = vect[1]*vsin;
527 	q[2] = vect[2]*vsin;
528 	q[3] = vcos;
529 
530 	m[0][0] = 1.0 - 2.0 * (q[1] * q[1] + q[2] * q[2]);
531     	m[0][1] = 2.0 * (q[0] * q[1] - q[2] * q[3]);
532     	m[0][2] = 2.0 * (q[2] * q[0] + q[1] * q[3]);
533 
534     	m[1][0] = 2.0 * (q[0] * q[1] + q[2] * q[3]);
535     	m[1][1]= 1.0 - 2.0 * (q[2] * q[2] + q[0] * q[0]);
536     	m[1][2] = 2.0 * (q[1] * q[2] - q[0] * q[3]);
537 
538     	m[2][0] = 2.0 * (q[2] * q[0] - q[1] * q[3]);
539     	m[2][1] = 2.0 * (q[1] * q[2] + q[0] * q[3]);
540     	m[2][2] = 1.0 - 2.0 * (q[1] * q[1] + q[0] * q[0]);
541 	return TRUE;
542 }
543 /************************************************************************/
build_rotation_about_an_axis(gdouble * vect,gdouble angle,gint n,gdouble * X,gdouble * Y,gdouble * Z)544 static gboolean build_rotation_about_an_axis(gdouble* vect, gdouble angle, gint n, gdouble* X, gdouble* Y, gdouble* Z)
545 {
546 	gdouble m[3][3];
547 	gboolean res = build_rotation_matrix_about_an_axis(m,vect, angle);
548 	gint i;
549 	if(!res) return res;
550 	for(i=0;i<n;i++)
551 	{
552 		gdouble x = X[i]*m[0][0]+Y[i]*m[0][1]+Z[i]*m[0][2];
553 		gdouble y = X[i]*m[1][0]+Y[i]*m[1][1]+Z[i]*m[1][2];
554 		gdouble z = X[i]*m[2][0]+Y[i]*m[2][1]+Z[i]*m[2][2];
555 		X[i] =x;
556 		Y[i] =y;
557 		Z[i] =z;
558 	}
559 	return TRUE;
560 }
561 /*************************************************************************************************************/
putGamessMoleculeInTextEditor()562 static void putGamessMoleculeInTextEditor()
563 {
564         gchar buffer[BSIZE];
565         gchar g[BSIZE];
566 	gint i;
567 	gchar** symbols = NULL;
568 	gdouble* X = NULL;
569 	gdouble* Y = NULL;
570 	gdouble* Z = NULL;
571 	gint numberOfAtoms = gamessMolecule.numberOfAtoms;
572 	gchar pointGroupSymbol[BSIZE];
573 	gchar message[BSIZE];
574 	gint maximalOrder = 8;
575 	gdouble principalAxisTolerance = getTolerancePrincipalAxis();
576 	gdouble positionTolerance = getTolerancePosition();
577 	gint nrvar = 0;
578 
579 	if(gamessMolecule.numberOfAtoms<1) return;
580 	nrvar = getRealNumberXYZVariables();
581 
582 	symbols = (gchar**)g_malloc(sizeof(gchar*)*(numberOfAtoms));
583 	if(symbols == NULL) return;
584 
585 	X = (gdouble*)g_malloc(sizeof(gdouble)*(numberOfAtoms));
586 	if(X == NULL) return;
587 	Y = (gdouble*)g_malloc(sizeof(gdouble)*(numberOfAtoms));
588 	if(Y == NULL) return;
589 	Z = (gdouble*)g_malloc(sizeof(gdouble)*(numberOfAtoms));
590 	if(Z == NULL) return;
591 	for(i=0; i<numberOfAtoms; i++)
592 	{
593 		symbols[i] = g_strdup(gamessMolecule.listOfAtoms[i].symbol);
594 		X[i] = gamessMolecule.listOfAtoms[i].position[0];
595 		Y[i] = gamessMolecule.listOfAtoms[i].position[1];
596 		Z[i] = gamessMolecule.listOfAtoms[i].position[2];
597 	}
598 
599 	if(MethodeGeom==GEOM_IS_XYZ && (nrvar== 3*NcentersXYZ || nrvar==0))
600 	{
601 		sprintf(pointGroupSymbol,"%s",gamessMolecule.groupSymmetry);
602 		computeSymmetryOld(principalAxisTolerance, FALSE, pointGroupSymbol,maximalOrder, TRUE, &numberOfAtoms,symbols, X, Y, Z, &positionTolerance, message);
603 		/*
604 		if(strlen(pointGroupSymbol)>1 && strcmp(pointGroupSymbol,"C1")!=0 && isdigit(pointGroupSymbol[1]))
605 			setFirstAtomToXAxis(numberOfAtoms, X, Y, Z);
606 			*/
607 		setGamessFormatGroup(gamessMolecule.groupSymmetry,g);
608 	}
609 	else
610 	{
611 		sprintf(g,"C1");
612 	}
613 
614 	if(strcmp(g,"C1")==0 || MethodeGeom!=GEOM_IS_XYZ) sprintf(buffer,"%s\n","C1");
615 	else sprintf(buffer,"%s\n\n",g);
616         gabedit_text_insert (GABEDIT_TEXT(text), NULL, NULL, NULL, buffer, -1);
617 	if(MethodeGeom==GEOM_IS_XYZ)
618 	{
619 		if(buffer[0]=='T')
620 		{
621 			gdouble vect[3] = {-1.0,1.0,0.0};
622 			vect[0] = 0.0;
623 			vect[1] = 0.0;
624 			vect[2] = 1.0;
625 			build_rotation_about_an_axis(vect, -135, numberOfAtoms, X, Y,Z);
626 			setEpsToZero(numberOfAtoms, X, Y, Z, positionTolerance);
627 			vect[0] = -1.0;
628 			vect[1] = 1.0;
629 			vect[2] = 0.0;
630 			build_rotation_about_an_axis(vect, atan(sqrt(2.0))*180/PI, numberOfAtoms, X, Y,Z);
631 			setEpsToZero(numberOfAtoms, X, Y, Z, positionTolerance);
632 		}
633 		if(strlen(buffer)>2 && buffer[0]=='D' && buffer[2]=='d')
634 		{
635 			gdouble vect[3] = {0.0,0.0,1.0};
636 			gchar* t = strstr(buffer,"d")+1;
637 			gint o = 1;
638 			if(t && atoi(t)>0) o = atoi(t);
639 
640 			build_rotation_about_an_axis(vect, 180/2/o, numberOfAtoms, X, Y,Z);
641 			setEpsToZero(numberOfAtoms, X, Y, Z, positionTolerance);
642 		}
643 		if(strlen(buffer)>2 && buffer[0]=='D' && buffer[2]=='h')
644 		{
645 			gdouble vect[3] = {0.0,0.0,1.0};
646 			gchar* t = strstr(buffer,"h")+1;
647 			gint o = 1;
648 			if(t && atoi(t)>0) o = atoi(t);
649 
650 			build_rotation_about_an_axis(vect, 2*180/2/o, numberOfAtoms, X, Y,Z);
651 			setEpsToZero(numberOfAtoms, X, Y, Z, positionTolerance);
652 		}
653       		for (i=0;i<numberOfAtoms;i++)
654 		{
655 			SAtomsProp prop = prop_atom_get(symbols[i]);
656 
657 			sprintf(buffer,"%s  %f %f %f %f\n",symbols[i], (gdouble)prop.atomicNumber, X[i], Y[i], Z[i]);
658         		gabedit_text_insert (GABEDIT_TEXT(text), NULL, NULL, NULL, buffer, -1);
659 		}
660 	}
661 	else
662 	{
663         	for(i=0;i<NcentersZmat;i++)
664         	{
665 			SAtomsProp prop = prop_atom_get(symbols[i]);
666         		if(Geom[i].Nentry>NUMBER_ENTRY_ANGLE)
667 			{
668 				sprintf(buffer,"%s  %s %s %s %s %s %s\n",
669 						Geom[i].Symb,
670 						Geom[i].NR,Geom[i].R,
671 						Geom[i].NAngle,Geom[i].Angle,
672 						Geom[i].NDihedral,Geom[i].Dihedral);
673         			gabedit_text_insert (GABEDIT_TEXT(text), NULL, NULL, &prop.color, buffer, -1);
674 			}
675 			else
676         		if(Geom[i].Nentry>NUMBER_ENTRY_R)
677 			{
678 				sprintf(buffer,"%s  %s %s %s %s\n",
679 						Geom[i].Symb,
680 						Geom[i].NR,Geom[i].R,
681 						Geom[i].NAngle,Geom[i].Angle
682 						);
683         			gabedit_text_insert (GABEDIT_TEXT(text), NULL, NULL, &prop.color, buffer, -1);
684 			}
685 			else
686         		if(Geom[i].Nentry>NUMBER_ENTRY_0)
687 			{
688 				sprintf(buffer,"%s  %s %s\n",
689 						Geom[i].Symb,
690 						Geom[i].NR,Geom[i].R
691 						);
692         			gabedit_text_insert (GABEDIT_TEXT(text), NULL, NULL, &prop.color, buffer, -1);
693 			}
694 			else
695 			{
696 				sprintf(buffer,"%s \n",
697 						Geom[i].Symb
698 						);
699         			gabedit_text_insert (GABEDIT_TEXT(text), NULL, NULL, &prop.color, buffer, -1);
700 			}
701         	}
702         	if(NVariables>0 && getRealNumberZmatVariables()>0)
703 		{
704         	for(i=0;i<NVariables;i++)
705         	{
706         		if(Variables[i].Used)
707 			{
708         			gabedit_text_insert (GABEDIT_TEXT(text), NULL, NULL, NULL,"\n",-1);
709 				break;
710 			}
711         	}
712         	for(i=0;i<NVariables;i++)
713         	{
714         		if(Variables[i].Used)
715 			{
716   				sprintf(buffer,"%s=%s\n",Variables[i].Name,Variables[i].Value);
717         			gabedit_text_insert (GABEDIT_TEXT(text), NULL, NULL, NULL,buffer,-1);
718 			}
719         	}
720 		}
721 	}
722 	for (i=0;i<(gint)numberOfAtoms;i++) g_free( symbols[i]);
723 	g_free( symbols);
724 	g_free(X);
725 	g_free(Y);
726 	g_free(Z);
727 
728 }
729 /************************************************************************************************************/
putNoSymmetryWithCalcul()730 static void putNoSymmetryWithCalcul()
731 {
732 	if(!GTK_TOGGLE_BUTTON (buttonSymWithCalc)->active ) return;
733         gabedit_text_insert (GABEDIT_TEXT(text), NULL, NULL, NULL, " ",-1);
734         gabedit_text_insert (GABEDIT_TEXT(text), NULL, &gamessColorFore.keyWord, &gamessColorBack.keyWord, "$CONTRL",-1);
735         gabedit_text_insert (GABEDIT_TEXT(text), NULL, NULL, NULL, " NOSYM=1 ",-1);
736         gabedit_text_insert (GABEDIT_TEXT(text), NULL, NULL, NULL, " ",-1);
737         gabedit_text_insert (GABEDIT_TEXT(text), NULL, &gamessColorFore.keyWord, &gamessColorBack.keyWord, "$END\n",-1);
738 }
739 /************************************************************************************************************/
putBeginGeometryInTextEditor()740 static void putBeginGeometryInTextEditor()
741 {
742         gabedit_text_insert (GABEDIT_TEXT(text), NULL, NULL, NULL, " ",-1);
743         gabedit_text_insert (GABEDIT_TEXT(text), NULL, &gamessColorFore.keyWord, &gamessColorBack.keyWord, "$DATA\n",-1);
744 }
745 /************************************************************************************************************/
putTitleGeometryInTextEditor()746 static void putTitleGeometryInTextEditor()
747 {
748         gchar buffer[BSIZE];
749 
750 	sprintf(buffer,"Molecule specification\n");
751         gabedit_text_insert (GABEDIT_TEXT(text), NULL, NULL, NULL, buffer,-1);
752 }
753 /************************************************************************************************************/
putEndGeometryInTextEditor()754 static void putEndGeometryInTextEditor()
755 {
756         gabedit_text_insert (GABEDIT_TEXT(text), NULL, NULL, NULL, " ",-1);
757         gabedit_text_insert (GABEDIT_TEXT(text), NULL,  &gamessColorFore.keyWord, &gamessColorBack.keyWord, "$END\n",-1);
758 }
759 /************************************************************************************************************/
putGamessGeometryInfoInTextEditor()760 void putGamessGeometryInfoInTextEditor()
761 {
762 	putNoSymmetryWithCalcul();
763 	if(MethodeGeom!=GEOM_IS_XYZ) putGamessMoleculeZMatInTextEditor();
764 	else putGamessMoleculeXYZFixedInTextEditor();
765 
766 	putBeginGeometryInTextEditor();
767 	putTitleGeometryInTextEditor();
768 
769 	putGamessMoleculeInTextEditor();
770 	putEndGeometryInTextEditor();
771 }
772 /**************************************************************************************************************************************/
activateRadioButton(GtkWidget * button,gpointer data)773 static void activateRadioButton(GtkWidget *button, gpointer data)
774 {
775 	gint* type = NULL;
776 	GtkWidget* label = NULL;
777 	GtkWidget* comboSymmetry = NULL;
778 	gchar buffer[BSIZE];
779 
780 	if(!GTK_IS_WIDGET(button)) return;
781 
782 	type  = g_object_get_data(G_OBJECT (button), "Type");
783 	label = g_object_get_data(G_OBJECT (button), "Label");
784 	comboSymmetry = g_object_get_data(G_OBJECT (button), "ComboSymmetry");
785 	if(type)
786 	{
787 		setGamessMolecule();
788 
789 		if( GTK_TOGGLE_BUTTON (button)->active && *type == GABFIXED)
790 		{
791 			if(gamessMolecule.groupSymmetry) g_free(gamessMolecule.groupSymmetry);
792 			gamessMolecule.groupSymmetry = g_strdup("C1");
793 			symReduction = FALSE;
794 			if(GTK_IS_WIDGET(comboSymmetry))
795 				gtk_widget_set_sensitive(comboSymmetry, TRUE);
796 		}
797 		if(GTK_TOGGLE_BUTTON (button)->active &&  *type == GABEDIT)
798 		{
799 			/* groupSymmetry define in setGamessMolecule */
800 			symReduction = TRUE;
801 			if(GTK_IS_WIDGET(comboSymmetry))
802 				gtk_widget_set_sensitive(comboSymmetry, FALSE);
803 		}
804 
805 		if(label) gtk_label_set_text(GTK_LABEL(label)," ");
806 		if(GTK_IS_WIDGET(buttonTolerance) && symReduction ) gtk_widget_set_sensitive(buttonTolerance, TRUE);
807 		if(GTK_IS_WIDGET(buttonTolerance) && !symReduction ) gtk_widget_set_sensitive(buttonTolerance, FALSE);
808 
809 		if(GTK_TOGGLE_BUTTON (button)->active && label && symReduction)
810 		{
811 			sprintf(buffer,"%s group",gamessMolecule.groupSymmetry);
812 			gtk_label_set_text(GTK_LABEL(label),buffer);
813 		}
814 	}
815 }
816 /************************************************************************************************************/
addRadioButtonToATable(GtkWidget * table,GtkWidget * friendButton,gchar * label,gint i,gint j,gint k)817 static GtkWidget* addRadioButtonToATable(GtkWidget* table, GtkWidget* friendButton, gchar* label, gint i, gint j, gint k)
818 {
819 	GtkWidget *newButton;
820 
821 	if(friendButton)
822 		newButton = gtk_radio_button_new_with_label( gtk_radio_button_get_group (GTK_RADIO_BUTTON (friendButton)), label);
823 	else
824 		newButton = gtk_radio_button_new_with_label( NULL, label);
825 
826 	gtk_table_attach(GTK_TABLE(table),newButton,j,j+k,i,i+1,
827 		(GtkAttachOptions)	(GTK_FILL | GTK_EXPAND),
828 		(GtkAttachOptions)	(GTK_FILL | GTK_EXPAND),
829                   2,2);
830 
831 	g_object_set_data(G_OBJECT (newButton), "Label",NULL);
832 	g_object_set_data(G_OBJECT (newButton), "Type",NULL);
833 	return newButton;
834 }
835 /**************************************************************************************************************************************/
resetTolerance(GtkWidget * win)836 static void resetTolerance(GtkWidget *win)
837 {
838 	gchar buffer[BSIZE];
839 
840 	setGamessMolecule();
841 	if(labelSymmetry)
842 	{
843 		sprintf(buffer,"%s group",gamessMolecule.groupSymmetry);
844 		gtk_label_set_text(GTK_LABEL(labelSymmetry),buffer);
845 	}
846 }
847 /**************************************************************************************************************************************/
activateToleranceButton(GtkWidget * button,gpointer data)848 static void activateToleranceButton(GtkWidget *button, gpointer data)
849 {
850 	if(!GTK_IS_WIDGET(button)) return;
851 	createToleranceWindow(gamessWin, resetTolerance);
852 }
853 /********************************************************************************/
setComboSymmetry(GtkWidget * comboSymmetry)854 static void setComboSymmetry(GtkWidget *comboSymmetry)
855 {
856 	GList *glist = NULL;
857 
858   	glist = g_list_append(glist,"C1");
859   	glist = g_list_append(glist,"Cs");
860   	glist = g_list_append(glist,"Ci");
861 
862   	glist = g_list_append(glist,"C2");
863   	glist = g_list_append(glist,"C3");
864   	glist = g_list_append(glist,"C4");
865   	glist = g_list_append(glist,"C5");
866   	glist = g_list_append(glist,"C6");
867   	glist = g_list_append(glist,"C7");
868   	glist = g_list_append(glist,"C8");
869 
870   	glist = g_list_append(glist,"C2v");
871   	glist = g_list_append(glist,"C3v");
872   	glist = g_list_append(glist,"C4v");
873   	glist = g_list_append(glist,"C5v");
874   	glist = g_list_append(glist,"C6v");
875   	glist = g_list_append(glist,"C7v");
876   	glist = g_list_append(glist,"C8v");
877 
878   	glist = g_list_append(glist,"C2h");
879   	glist = g_list_append(glist,"C3h");
880   	glist = g_list_append(glist,"C4h");
881   	glist = g_list_append(glist,"C5h");
882   	glist = g_list_append(glist,"C6h");
883   	glist = g_list_append(glist,"C7h");
884   	glist = g_list_append(glist,"C8h");
885 
886   	glist = g_list_append(glist,"D2");
887   	glist = g_list_append(glist,"D3");
888   	glist = g_list_append(glist,"D4");
889   	glist = g_list_append(glist,"D5");
890   	glist = g_list_append(glist,"D6");
891   	glist = g_list_append(glist,"D7");
892   	glist = g_list_append(glist,"D8");
893 
894   	glist = g_list_append(glist,"D2h");
895   	glist = g_list_append(glist,"D3h");
896   	glist = g_list_append(glist,"D4h");
897   	glist = g_list_append(glist,"D5h");
898   	glist = g_list_append(glist,"D6h");
899   	glist = g_list_append(glist,"D7h");
900   	glist = g_list_append(glist,"D8h");
901 
902   	glist = g_list_append(glist,"D2d");
903   	glist = g_list_append(glist,"D3d");
904   	glist = g_list_append(glist,"D4d");
905   	glist = g_list_append(glist,"D5d");
906   	glist = g_list_append(glist,"D6d");
907   	glist = g_list_append(glist,"D7d");
908   	glist = g_list_append(glist,"D8d");
909 
910   	glist = g_list_append(glist,"S2");
911   	glist = g_list_append(glist,"S4");
912   	glist = g_list_append(glist,"S6");
913   	glist = g_list_append(glist,"S8");
914   	glist = g_list_append(glist,"S10");
915   	glist = g_list_append(glist,"S12");
916   	glist = g_list_append(glist,"S14");
917   	glist = g_list_append(glist,"S16");
918 
919   	glist = g_list_append(glist,"T");
920   	glist = g_list_append(glist,"Td");
921   	glist = g_list_append(glist,"Th");
922   	glist = g_list_append(glist,"O");
923   	glist = g_list_append(glist,"Oh");
924 
925   	gtk_combo_box_entry_set_popdown_strings( comboSymmetry, glist) ;
926 
927   	g_list_free(glist);
928 }
929 /**********************************************************************/
changedEntrySymmetry(GtkWidget * entry,gpointer data)930 static void changedEntrySymmetry(GtkWidget *entry, gpointer data)
931 {
932 	G_CONST_RETURN gchar* entryText = NULL;
933 
934 	if(!GTK_IS_WIDGET(entry)) return;
935 
936 	entryText = gtk_entry_get_text(GTK_ENTRY(entry));
937 	if(strlen(entryText)<1)return;
938 	if(gamessMolecule.groupSymmetry) g_free(gamessMolecule.groupSymmetry);
939 	gamessMolecule.groupSymmetry = g_strdup(entryText);
940 
941 	if(strstr(entryText,"C1")) symReduction = FALSE;
942 	else symReduction = FALSE;
943 }
944 /************************************************************************************************************/
createGamessSymmetryFrame(GtkWidget * win,GtkWidget * box)945 void createGamessSymmetryFrame(GtkWidget *win, GtkWidget *box)
946 {
947 	GtkWidget* button;
948 	GtkWidget* buttonGabedit;
949 	GtkWidget* frame;
950 	GtkWidget* vboxFrame;
951 	GtkWidget* sep;
952 	GtkWidget* comboSymmetry = NULL;
953 	GtkWidget* entrySymmetry = NULL;
954 	GtkWidget* label = gtk_label_new(" ");
955 	GtkWidget *table = gtk_table_new(4,3,FALSE);
956 	static TypeOfSymmetryButton typeOfSymmetry[] = { GABEDIT, GABFIXED};
957 	gchar* list[] = {"C1"};
958 
959 	frame = gtk_frame_new ("Symmetry");
960 	gtk_widget_show (frame);
961 	gtk_box_pack_start (GTK_BOX (box), frame, TRUE, TRUE, 3);
962 	gtk_frame_set_label_align (GTK_FRAME (frame), 0.5, 0.5);
963 
964 	vboxFrame = gtk_vbox_new (FALSE, 3);
965 	gtk_widget_show (vboxFrame);
966 	gtk_container_add (GTK_CONTAINER (frame), vboxFrame);
967 
968 	gtk_box_pack_start (GTK_BOX (vboxFrame), table, TRUE, TRUE, 0);
969 
970 	comboSymmetry = create_combo_box_entry(list, 1, TRUE, -1, -1);
971 	entrySymmetry = GTK_BIN(comboSymmetry)->child;
972 	gtk_widget_set_sensitive(entrySymmetry, FALSE);
973 
974 
975 	if(gamessMolecule.groupSymmetry) g_free(gamessMolecule.groupSymmetry);
976 	gamessMolecule.groupSymmetry = g_strdup("C1");
977 
978 	button = addRadioButtonToATable(table, NULL, _("Detected by Gabedit"), 0, 0, 1);
979 	g_object_set_data(G_OBJECT (button), "Label",label);
980 	g_object_set_data(G_OBJECT (button), "Type",&typeOfSymmetry[GABEDIT]);
981 	g_object_set_data(G_OBJECT (button), "ComboSymmetry",comboSymmetry);
982 	g_signal_connect(G_OBJECT(button),"clicked", G_CALLBACK(activateRadioButton),NULL);
983 	add_widget_table(table, label, 0, 1);
984 	gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), FALSE);
985 	buttonGabedit=button;
986 
987 	buttonTolerance = create_button(win,_("Tolerance"));
988 	add_widget_table(table, buttonTolerance, 0, 2);
989 	g_signal_connect(G_OBJECT(buttonTolerance),"clicked", G_CALLBACK(activateToleranceButton),NULL);
990 
991 	labelSymmetry = label;
992 	gtk_widget_set_sensitive(buttonTolerance, FALSE);
993 
994 	button = addRadioButtonToATable(table, button, _("Fixed Symmetry"), 1, 0,1);
995 	g_signal_connect(G_OBJECT(entrySymmetry),"changed", G_CALLBACK(changedEntrySymmetry),NULL);
996 	setComboSymmetry(comboSymmetry);
997 	gtk_table_attach(GTK_TABLE(table),comboSymmetry,1,1+2,1,1+1,
998 		(GtkAttachOptions)	(GTK_FILL | GTK_EXPAND),
999 		(GtkAttachOptions)	(GTK_FILL | GTK_EXPAND),
1000                   2,2);
1001 	g_object_set_data(G_OBJECT (button), "Label",label);
1002 	g_object_set_data(G_OBJECT (button), "Type",&typeOfSymmetry[GABFIXED]);
1003 	gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), FALSE);
1004 	g_object_set_data(G_OBJECT (button), "ComboSymmetry",comboSymmetry);
1005 	g_signal_connect(G_OBJECT(button),"clicked", G_CALLBACK(activateRadioButton),NULL);
1006 	gtk_widget_set_sensitive(comboSymmetry, FALSE);
1007 
1008 	sep = gtk_hseparator_new ();;
1009 	gtk_table_attach(GTK_TABLE(table),sep,0,0+3,2,2+1,
1010 		(GtkAttachOptions)	(GTK_FILL | GTK_EXPAND),
1011 		(GtkAttachOptions)	(GTK_FILL | GTK_EXPAND),
1012                   2,2);
1013 
1014 	buttonSymWithCalc = gtk_check_button_new_with_label (_("Symmetry not used during calculation"));
1015 	gtk_table_attach(GTK_TABLE(table),buttonSymWithCalc,0,0+3,3,3+1,
1016 		(GtkAttachOptions)	(GTK_FILL | GTK_EXPAND),
1017 		(GtkAttachOptions)	(GTK_FILL | GTK_EXPAND),
1018                   2,2);
1019 
1020 	gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (buttonGabedit), FALSE);
1021 	gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (buttonGabedit), TRUE);
1022 
1023 	gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), TRUE);
1024 }
1025 /********************************************************************************/
setSpinMultiplicityComboSpinMultiplicity(GtkWidget * comboSpinMultiplicity,gint spin)1026 static void setSpinMultiplicityComboSpinMultiplicity(GtkWidget *comboSpinMultiplicity, gint spin)
1027 {
1028 	GtkWidget *entry = NULL;
1029 	gchar* t = NULL;
1030 	if(!comboSpinMultiplicity) return;
1031 	entry = GTK_BIN (comboSpinMultiplicity)->child;
1032 	t = g_strdup_printf("%d",spin);
1033 	gtk_entry_set_text(GTK_ENTRY(entry),t);
1034 	g_free(t);
1035 }
1036 /************************************************************************************************************/
setComboSpinMultiplicity(GtkWidget * comboSpinMultiplicity)1037 static void setComboSpinMultiplicity(GtkWidget *comboSpinMultiplicity)
1038 {
1039 	GList *glist = NULL;
1040 	gint i;
1041 	gint nlist = 0;
1042 	gchar** list = NULL;
1043 	gint k;
1044 	gint kinc;
1045 	gint ne = gamessMolecule.numberOfValenceElectrons - totalCharge;
1046 
1047 	if(ne%2==0) nlist = ne/2+1;
1048 	else nlist = (ne+1)/2;
1049 
1050 	if(nlist<1) return;
1051 	list = g_malloc(nlist*sizeof(gchar*));
1052 	if(!list) return;
1053 	for(i=0;i<nlist;i++)
1054 		list[i] = g_malloc(10*sizeof(gchar));
1055 
1056 
1057 	if(GTK_IS_WIDGET(comboSpinMultiplicity)) gtk_widget_set_sensitive(comboSpinMultiplicity, TRUE);
1058 	if(ne%2==0) k = 1;
1059 	else k = 2;
1060 
1061 	kinc = 2;
1062 	for(i=0;i<nlist;i++)
1063 	{
1064 		sprintf(list[i],"%d",k);
1065 		k+=kinc;
1066 	}
1067 
1068   	for(i=0;i<nlist;i++) glist = g_list_append(glist,list[i]);
1069 
1070   	gtk_combo_box_entry_set_popdown_strings( comboSpinMultiplicity, glist) ;
1071   	g_list_free(glist);
1072 	if( SpinMultiplicities[0]%2 == atoi(list[0])%2) setSpinMultiplicityComboSpinMultiplicity(comboSpinMultiplicity, SpinMultiplicities[0]);
1073 	else SpinMultiplicities[0] = atoi(list[0]);
1074 	if(list)
1075 	{
1076 		for(i=0;i<nlist;i++) if(list[i]) g_free(list[i]);
1077 		g_free(list);
1078 	}
1079 }
1080 /********************************************************************************/
setChargeComboCharge(GtkWidget * comboCharge,gint charge)1081 static void setChargeComboCharge(GtkWidget *comboCharge, gint charge)
1082 {
1083 	GtkWidget *entry = NULL;
1084 	gchar* t = NULL;
1085 	if(!comboCharge) return;
1086 	entry = GTK_BIN (comboCharge)->child;
1087 	t = g_strdup_printf("%d",charge);
1088 	gtk_entry_set_text(GTK_ENTRY(entry),t);
1089 	g_free(t);
1090 }
1091 /********************************************************************************/
setComboCharge(GtkWidget * comboCharge)1092 static void setComboCharge(GtkWidget *comboCharge)
1093 {
1094 	GList *glist = NULL;
1095 	gint i;
1096 	gint nlist;
1097 	gchar** list = NULL;
1098 	gint k;
1099 
1100 	nlist = gamessMolecule.numberOfValenceElectrons*2-2+1;
1101 
1102 	if(nlist<1) return;
1103 	if(nlist==1) nlist++;
1104 	list = g_malloc(nlist*sizeof(gchar*));
1105 	if(!list) return;
1106 	for(i=0;i<nlist;i++)
1107 		list[i] = g_malloc(10*sizeof(gchar));
1108 
1109 
1110 	sprintf(list[0],"0");
1111 	k = 1;
1112 	for(i=1;i<nlist-1;i+=2)
1113 	{
1114 		sprintf(list[i],"+%d",k);
1115 		sprintf(list[i+1],"%d",-k);
1116 		k += 1;
1117 	}
1118 	if(nlist==2) sprintf(list[1],"%d",-1);
1119 
1120   	for(i=0;i<nlist;i++) glist = g_list_append(glist,list[i]);
1121 
1122   	gtk_combo_box_entry_set_popdown_strings( comboCharge, glist) ;
1123   	g_list_free(glist);
1124 	if(list)
1125 	{
1126 		for(i=0;i<nlist;i++) if(list[i]) g_free(list[i]);
1127 		g_free(list);
1128 	}
1129 	setChargeComboCharge(comboCharge, totalCharge);
1130 }
1131 /**********************************************************************/
changedEntrySpinMultiplicity(GtkWidget * entry,gpointer data)1132 static void changedEntrySpinMultiplicity(GtkWidget *entry, gpointer data)
1133 {
1134 	G_CONST_RETURN gchar* entryText = NULL;
1135 
1136 	if(!GTK_IS_WIDGET(entry)) return;
1137 
1138 	entryText = gtk_entry_get_text(GTK_ENTRY(entry));
1139 	if(strlen(entryText)<1)return;
1140 
1141 	spinMultiplicity=atoi(entryText);
1142 	if(spinMultiplicity==1)
1143 	{
1144 		/* OK RHF*/
1145 		setGamessSCFMethod(TRUE);
1146 	}
1147 	else
1148 	{
1149 		/* remove RHF from list*/
1150 		setGamessSCFMethod(FALSE);
1151 	}
1152 }
1153 /**********************************************************************/
changedEntryCharge(GtkWidget * entry,gpointer data)1154 static void changedEntryCharge(GtkWidget *entry, gpointer data)
1155 {
1156 	G_CONST_RETURN gchar* entryText = NULL;
1157 	GtkWidget* comboSpinMultiplicity = NULL;
1158 	GtkWidget* labelNumberOfElectrons = NULL;
1159 
1160 	if(!GTK_IS_WIDGET(entry)) return;
1161 
1162 	entryText = gtk_entry_get_text(GTK_ENTRY(entry));
1163 	if(strlen(entryText)<1)return;
1164 
1165 	totalCharge = atoi(entryText);
1166 	TotalCharges[0] = totalCharge;
1167 
1168 	comboSpinMultiplicity  = g_object_get_data(G_OBJECT (entry), "ComboSpinMultiplicity");
1169 	if(GTK_IS_WIDGET(comboSpinMultiplicity)) setComboSpinMultiplicity(comboSpinMultiplicity);
1170 
1171 	labelNumberOfElectrons = g_object_get_data(G_OBJECT (entry), "LabelNumberOfElectrons");
1172 
1173 	if(GTK_IS_WIDGET(labelNumberOfElectrons))
1174 	{
1175 		gint ne = gamessMolecule.numberOfValenceElectrons - totalCharge;
1176 		gchar buffer[BSIZE];
1177 		sprintf(buffer, _("Number of electrons = %d"),ne);
1178 		gtk_label_set_text(GTK_LABEL(labelNumberOfElectrons),buffer);
1179 	}
1180 }
1181 /**********************************************************************/
addComboListToATable(GtkWidget * table,gchar ** list,gint nlist,gint i,gint j,gint k)1182 static GtkWidget* addComboListToATable(GtkWidget* table,
1183 		gchar** list, gint nlist, gint i, gint j, gint k)
1184 {
1185 	GtkWidget *entry = NULL;
1186 	GtkWidget *combo = NULL;
1187 
1188 	combo = create_combo_box_entry(list, nlist, TRUE, -1, -1);
1189 
1190 	gtk_table_attach(GTK_TABLE(table),combo,j,j+k,i,i+1,
1191 		(GtkAttachOptions)	(GTK_FILL | GTK_EXPAND),
1192 		(GtkAttachOptions)	(GTK_FILL | GTK_SHRINK),
1193                   2,2);
1194 	entry = GTK_BIN (combo)->child;
1195 	g_object_set_data(G_OBJECT (entry), "Combo",combo);
1196 	gtk_widget_set_size_request(GTK_WIDGET(entry),(gint)(ScreenHeight*0.2),-1);
1197 
1198 	return entry;
1199 }
1200 /***********************************************************************************************/
addGamessChargeToTable(GtkWidget * table,gint i)1201 static GtkWidget *addGamessChargeToTable(GtkWidget *table, gint i)
1202 {
1203 	GtkWidget* entryCharge = NULL;
1204 	GtkWidget* comboCharge = NULL;
1205 	gint nlistCharge = 1;
1206 	gchar* listCharge[] = {"0"};
1207 
1208 	add_label_table(table,_("Charge"),(gushort)i,0);
1209 	add_label_table(table,":",(gushort)i,1);
1210 	entryCharge = addComboListToATable(table, listCharge, nlistCharge, i, 2, 1);
1211 	comboCharge  = g_object_get_data(G_OBJECT (entryCharge), "Combo");
1212 	gtk_widget_set_sensitive(entryCharge, FALSE);
1213 
1214 	return comboCharge;
1215 }
1216 /***********************************************************************************************/
addGamessSpinToTable(GtkWidget * table,gint i)1217 static GtkWidget *addGamessSpinToTable(GtkWidget *table, gint i)
1218 {
1219 	GtkWidget* entrySpinMultiplicity = NULL;
1220 	GtkWidget* comboSpinMultiplicity = NULL;
1221 	gint nlistspinMultiplicity = 1;
1222 	gchar* listspinMultiplicity[] = {"0"};
1223 
1224 	add_label_table(table,_("Spin multiplicity"),(gushort)i,0);
1225 	add_label_table(table,":",(gushort)i,1);
1226 	entrySpinMultiplicity = addComboListToATable(table, listspinMultiplicity, nlistspinMultiplicity, i, 2, 1);
1227 	comboSpinMultiplicity  = g_object_get_data(G_OBJECT (entrySpinMultiplicity), "Combo");
1228 	gtk_widget_set_sensitive(entrySpinMultiplicity, FALSE);
1229 
1230 	g_signal_connect(G_OBJECT(entrySpinMultiplicity),"changed", G_CALLBACK(changedEntrySpinMultiplicity),NULL);
1231 	return comboSpinMultiplicity;
1232 }
1233 /***********************************************************************************************/
addLabelNumberOfElectronsToTable(GtkWidget * table,gint i,GtkWidget * comboCharge)1234 static GtkWidget *addLabelNumberOfElectronsToTable(GtkWidget *table, gint i, GtkWidget *comboCharge)
1235 {
1236 	GtkWidget* labelNumberOfElectrons = NULL;
1237 	GtkWidget* hbox = NULL;
1238 	GtkWidget* entryCharge = GTK_BIN(comboCharge)->child;
1239 
1240 	labelNumberOfElectrons = gtk_label_new(" ");
1241 	hbox = gtk_hbox_new(0,FALSE);
1242 	gtk_box_pack_start (GTK_BOX (hbox), labelNumberOfElectrons, FALSE, FALSE, 0);
1243 	gtk_table_attach(GTK_TABLE(table),hbox,0,0+3,i,i+1,
1244 		(GtkAttachOptions)	(GTK_FILL | GTK_EXPAND),
1245 		(GtkAttachOptions)	(GTK_FILL | GTK_SHRINK),
1246                   2,2);
1247 
1248 	g_object_set_data(G_OBJECT (entryCharge), "LabelNumberOfElectrons", labelNumberOfElectrons);
1249 	g_signal_connect(G_OBJECT(entryCharge),"changed", G_CALLBACK(changedEntryCharge),NULL);
1250 	return labelNumberOfElectrons;
1251 }
1252 /***********************************************************************************************/
createGamessChargeMultiplicityFrame(GtkWidget * box)1253 void createGamessChargeMultiplicityFrame(GtkWidget *box)
1254 {
1255 	GtkWidget* frame;
1256 	GtkWidget* sep;
1257 	GtkWidget* labelNumberOfElectrons;
1258 	GtkWidget* vboxFrame;
1259 	GtkWidget* comboSpinMultiplicity = NULL;
1260 	GtkWidget* comboCharge = NULL;
1261 	GtkWidget *table = NULL;
1262 	gint i;
1263 
1264 	totalCharge = TotalCharges[0];
1265 	spinMultiplicity=SpinMultiplicities[0];
1266 
1267 	table = gtk_table_new(3,5,FALSE);
1268 
1269 	frame = gtk_frame_new (_("Charge & Multiplicty"));
1270 	gtk_widget_show (frame);
1271 	gtk_box_pack_start (GTK_BOX (box), frame, TRUE, TRUE, 3);
1272 	gtk_frame_set_label_align (GTK_FRAME (frame), 0.5, 0.5);
1273 
1274 	vboxFrame = gtk_vbox_new (FALSE, 3);
1275 	gtk_widget_show (vboxFrame);
1276 	gtk_container_add (GTK_CONTAINER (frame), vboxFrame);
1277 
1278 	gtk_box_pack_start (GTK_BOX (vboxFrame), table, TRUE, TRUE, 0);
1279 
1280 	i = 0;
1281 	comboCharge = addGamessChargeToTable(table, i);
1282 	i = 1;
1283 	comboSpinMultiplicity = addGamessSpinToTable(table, i);
1284 	i = 2;
1285 	sep = gtk_hseparator_new ();;
1286 	gtk_table_attach(GTK_TABLE(table),sep,0,0+3,i,i+1,
1287 		(GtkAttachOptions)	(GTK_FILL | GTK_EXPAND),
1288 		(GtkAttachOptions)	(GTK_FILL | GTK_EXPAND),
1289                   2,2);
1290 
1291 	i = 3;
1292 	labelNumberOfElectrons=addLabelNumberOfElectronsToTable(table, i, comboCharge);
1293 
1294 	if(GTK_IS_COMBO_BOX(comboCharge))
1295 		g_object_set_data(G_OBJECT (GTK_BIN(comboCharge)->child), "ComboSpinMultiplicity", comboSpinMultiplicity);
1296 	setComboCharge(comboCharge);
1297 	setComboSpinMultiplicity(comboSpinMultiplicity);
1298 	if(GTK_IS_WIDGET(labelNumberOfElectrons))
1299 	{
1300 		gint ne = gamessMolecule.numberOfValenceElectrons - totalCharge;
1301 		gchar buffer[BSIZE];
1302 		sprintf(buffer, _("Number of electrons = %d"),ne);
1303 		gtk_label_set_text(GTK_LABEL(labelNumberOfElectrons),buffer);
1304 	}
1305 
1306 }
1307 /************************************************************************************************************/
putGamessChargeAndSpinInfoInTextEditor()1308 void putGamessChargeAndSpinInfoInTextEditor()
1309 {
1310 	gchar buffer[BSIZE];
1311         gabedit_text_insert (GABEDIT_TEXT(text), NULL, NULL, NULL, " ",-1);
1312         gabedit_text_insert (GABEDIT_TEXT(text), NULL, &gamessColorFore.keyWord, &gamessColorBack.keyWord, "$CONTRL",-1);
1313 	sprintf(buffer," ICHARG=%d ",totalCharge);
1314         gabedit_text_insert (GABEDIT_TEXT(text), NULL, NULL, NULL, buffer,-1);
1315 	sprintf(buffer," MULT=%d ",spinMultiplicity);
1316         gabedit_text_insert (GABEDIT_TEXT(text), NULL, NULL, NULL, buffer,-1);
1317         gabedit_text_insert (GABEDIT_TEXT(text), NULL, &gamessColorFore.keyWord, &gamessColorBack.keyWord, "$END\n",-1);
1318 }
1319