1 /*
2  *  (c) 2004 Iowa State University
3  *      see the LICENSE file in the top level directory
4  */
5 
6 /*	�����������������������������������������
7 	InputData.cpp
8 
9 	Class member functions related to InputData
10 	Brett Bode - February 1996
11 	Changed InputeFileData uses to BufferFile calls 8-97
12 */
13 #define		kPGroupStrings		305
14 #define		kMaxPGroups			15
15 #define		kDFTGridFunctionalStrings		311
16 #define		kDFTGridFunctionalMaxStrings	21
17 #define		kDFTGridFreeFunctionalStrings		312
18 #define		kDFTGridFreeFunctionalMaxStrings	21
19 
20 #include "Globals.h"
21 #include "InputData.h"
22 #include "MoleculeData.h"
23 #include "Frame.h"
24 #include "myFiles.h"
25 #include "GlobalExceptions.h"
26 #include "BasisSet.h"
27 #include "Internals.h"
28 #include "Prefs.h"
29 #include <ctype.h>
30 #include <stdio.h>
31 #include <string.h>
32 #include "XML.hpp"
33 #include "CML.h"
34 #include <cctype>
35 #include <sstream>
36 
37 
38 //InputData functions
InputData(void)39 InputData::InputData(void) {
40 	//Always create Control, System, Basis, and Data groups
41 	Control = new ControlGroup;
42 	System = new SystemGroup;
43 	Basis = new BasisGroup;
44 	Data = new DataGroup;
45 	StatPt = new StatPtGroup;
46 	Guess = new GuessGroup;
47 	SCF = new SCFGroup;
48 	MP2 = NULL;
49 	Hessian = NULL;
50 }
InputData(InputData * Copy)51 InputData::InputData(InputData *Copy) {
52 	//Always create Control, System, Basis, and Data groups
53 	Control = new ControlGroup(Copy->Control);	//Create the new group and copy over the data
54 	System = new SystemGroup(Copy->System);
55 	Basis = new BasisGroup(Copy->Basis);
56 	Data = new DataGroup(Copy->Data);
57 	StatPt = new StatPtGroup(Copy->StatPt);
58 	if (Copy->Guess) Guess = new GuessGroup(Copy->Guess);
59 	else Guess = new GuessGroup;
60 	if (Copy->SCF) SCF = new SCFGroup(Copy->SCF);
61 	else SCF = new SCFGroup;
62 	if (Copy->MP2) MP2 = new MP2Group(Copy->MP2);
63 	else MP2 = NULL;
64 	if (Copy->Hessian) Hessian = new HessianGroup(Copy->Hessian);
65 	else Hessian = NULL;
66 	DFT = Copy->DFT;
67 	EFP = Copy->EFP;
68 	FMO = Copy->FMO;
69 }
~InputData(void)70 InputData::~InputData(void) {	//destructor
71 	if (Control) delete Control;	//simply delete all groups present
72 	if (System) delete System;
73 	if (Basis) delete Basis;
74 	if (Data) delete Data;
75 	if (Guess) delete Guess;
76 	if (SCF) delete SCF;
77 	if (MP2) delete MP2;
78 	if (Hessian) delete Hessian;
79 	if (StatPt) delete StatPt;
80 }
WriteXML(XMLElement * parent,MoleculeData * p) const81 void InputData::WriteXML(XMLElement * parent, MoleculeData * p) const {
82 	XMLElement * Ele = parent->addChildElement(CML_convert(MMP_InputOptionsElement));
83 
84 	if (Control) {
85 		Control->WriteXML(Ele);
86 	}
87 	if (System) {
88 		System->WriteXML(Ele);
89 	}
90 	if (Basis) {
91 		Basis->WriteXML(Ele);
92 	}
93 	if (Data) {
94 		Data->WriteXML(Ele);
95 	}
96 	if (Guess) {
97 		Guess->WriteXML(Ele);
98 	}
99 	if (SCF) {
100 		SCF->WriteXML(Ele);
101 	}
102 	if (MP2) {
103 		MP2->WriteXML(Ele);
104 	}
105 	if (Hessian) {
106 		Hessian->WriteXML(Ele);
107 	}
108 	if (StatPt) {
109 		StatPt->WriteXML(Ele);
110 	}
111 	DFT.WriteXML(Ele);
112 	EFP.WriteXML(Ele);
113 	FMO.WriteXML(Ele, p);
114 }
ReadXML(XMLElement * parent,MoleculeData * p)115 void InputData::ReadXML(XMLElement * parent, MoleculeData * p) {
116 	XMLElementList * ipxml = parent->getChildren();
117 	if (ipxml) {
118 		if (ipxml->length() > 0) {
119 			XMLElement * ipx = ipxml->item(0);
120 			if (ipx) {
121 				if (!strcmp(ipx->getName(),CML_convert(MMP_InputOptionsElement))) {
122 					XMLElementList * children = ipx->getChildren();
123 					if (children) {
124 						for (int i=0; i<children->length(); i++) {
125 							XMLElement * child = children->item(i);
126 							MMP_InputOptionsNS IOchild;
127 							if (CML_convert(child->getName(), IOchild)) {
128 								switch (IOchild) {
129 									case MMP_IOControlGroupElement:
130 										if (Control == NULL) Control = new ControlGroup;
131 										if (Control) Control->ReadXML(child);
132 										break;
133 									case MMP_IOSystemGroupElement:
134 										if (System == NULL) System = new SystemGroup;
135 										if (System) System->ReadXML(child);
136 										break;
137 									case MMP_IOBasisGroupElement:
138 										if (Basis == NULL) Basis = new BasisGroup;
139 										if (Basis) Basis->ReadXML(child);
140 										break;
141 									case MMP_IODataGroupElement:
142 										if (Data == NULL) Data = new DataGroup;
143 										if (Data) Data->ReadXML(child);
144 										break;
145 									case MMP_IOGuessGroupElement:
146 										if (Guess == NULL) Guess = new GuessGroup;
147 										if (Guess) Guess->ReadXML(child);
148 										break;
149 									case MMP_IOSCFGroupElement:
150 										if (SCF == NULL) SCF = new SCFGroup;
151 										if (SCF) SCF->ReadXML(child);
152 										break;
153 									case MMP_IOMP2GroupElement:
154 										if (MP2 == NULL) MP2 = new MP2Group;
155 										if (MP2) MP2->ReadXML(child);
156 										break;
157 									case MMP_IOHessianGroupElement:
158 										if (Hessian == NULL) Hessian = new HessianGroup;
159 										if (Hessian) Hessian->ReadXML(child);
160 										break;
161 									case MMP_IOStatPtGroupElement:
162 										if (StatPt == NULL) StatPt = new StatPtGroup;
163 										if (StatPt) StatPt->ReadXML(child);
164 										break;
165 									case MMP_IODFTGroupElement:
166 										DFT.ReadXML(child);
167 										break;
168 									case MMP_IOEFPGroupElement:
169 										EFP.ReadXML(child);
170 										break;
171 									case MMP_IOFMOGroupElement:
172 										FMO.ReadXML(child, p);
173 										break;
174 									default:
175 									{
176 										wxString msg;
177 										msg.Printf(_T("Unknown CML element: %s"), child->getName());
178 										wxLogMessage(msg);
179 									}
180 								}
181 							}
182 						}
183 						delete children;
184 					}
185 				}
186 			}
187 		}
188 		delete ipxml;
189 	}
190 }
191 
192 	//ControlGroup functions
ControlGroup(void)193 ControlGroup::ControlGroup(void) {
194 	ExeType = NULL;
195 	Options=0;
196 	InitControlPaneData();
197 	InitProgPaneData();
198 	NPrint=ITol=ICut=0;
199 }
ControlGroup(ControlGroup * Copy)200 ControlGroup::ControlGroup(ControlGroup *Copy) {
201 	if (Copy == NULL) return;
202 	*this = *Copy;
203 	ExeType = NULL;
204 	if (Copy->ExeType) {
205 		ExeType = new char[1+strlen(Copy->ExeType)];
206 		if (ExeType) strcpy(ExeType, Copy->ExeType);
207 	}
208 }
~ControlGroup(void)209 ControlGroup::~ControlGroup(void) {
210 	if (ExeType) delete [] ExeType;
211 }
InitControlPaneData(void)212 void ControlGroup::InitControlPaneData(void) {
213 	if (ExeType) {
214 		delete [] ExeType;
215 		ExeType = NULL;
216 	}
217 	SCFType=GAMESSDefaultSCFType;
218 	MPLevelCIType=MaxIt=Charge=Multiplicity=0;
219 	Local=GAMESS_No_Localization;
220 	RunType=InvalidRunType;
221 	CCType = CC_None;
222 }
InitProgPaneData(void)223 void ControlGroup::InitProgPaneData(void) {
224 	Friend=Friend_None;
225 	SetMolPlot(false);
226 	SetPlotOrb(false);
227 	SetAIMPAC(false);
228 	SetRPAC(false);
229 }
SetSCFType(GAMESS_SCFType NewSCFType)230 GAMESS_SCFType ControlGroup::SetSCFType(GAMESS_SCFType NewSCFType) {
231 	if ((NewSCFType >= GAMESSDefaultSCFType)||(NewSCFType<NumGAMESSSCFTypes))
232 		SCFType = NewSCFType;
233 	return SCFType;
234 }
GAMESSSCFTypeToText(GAMESS_SCFType t)235 const char * ControlGroup::GAMESSSCFTypeToText(GAMESS_SCFType t) {
236 	switch (t) {
237 		case GAMESS_RHF:
238 			return "RHF";
239 		case GAMESS_UHF:
240 			return "UHF";
241 		case GAMESS_ROHF:
242 			return "ROHF";
243 		case GAMESS_GVB:
244 			return "GVB";
245 		case GAMESS_MCSCF:
246 			return "MCSCF";
247 		case GAMESS_NO_SCF:
248 			return "NONE";
249 		default: //Fall through to the invalid
250 			wxLogMessage(_T("Attempt to convert invalid GAMESS SCF Type"));
251 	}
252 	return "invalid";
253 }
SetSCFType(const char * SCFText)254 GAMESS_SCFType ControlGroup::SetSCFType(const char *SCFText) {
255 	GAMESS_SCFType temp = GAMESS_Invalid_SCFType;
256 	for (int i=1; i<=NumGAMESSSCFTypes; i++) {
257 		if (!strcasecmp(SCFText, GAMESSSCFTypeToText((GAMESS_SCFType) i))) {
258 			temp = (GAMESS_SCFType) i;
259 			break;
260 		}
261 	}
262 	if (temp != GAMESS_Invalid_SCFType) SCFType = temp;
263 	return temp;
264 }
SetMPLevel(short NewMPLevel)265 long ControlGroup::SetMPLevel(short NewMPLevel) {
266 	if ((NewMPLevel!=0)&&(NewMPLevel!=2)) return -1;
267 
268 	MPLevelCIType = (MPLevelCIType & 0xFFF0) + NewMPLevel;
269 	return (MPLevelCIType & 0x0F);
270 }
GetMPLevel(void) const271 short ControlGroup::GetMPLevel(void) const {	//return the appropriate MP value based on SCF and Run types
272 	short result=-1;
273 		//MP2 energy and gradients are available for RHF, UHF and ROHF
274 	if ((SCFType >= GAMESSDefaultSCFType)&&(SCFType <= GAMESS_ROHF)) result = (MPLevelCIType & 0x0F);
275 		//MrMP2 energies are also available
276 	else if ((SCFType==GAMESS_MCSCF)&&
277 		(RunType!=GradientRun)&&(RunType!=HessianRun)&&(RunType!=OptimizeRun)&&
278 		(RunType!=SadPointRun)&&(RunType!=IRCRun)&&(RunType!=GradExtrRun)&&(RunType!=DRCRun)) result=(MPLevelCIType & 0x0F);
279 	if (MPLevelCIType & 0xF0) result = -1;	//deactivate MP2 when CI is requested
280 	if (GetCCType() != CC_None) result = -1;
281 	if (GetRunType() == G3MP2) result = -1;
282 	return result;
283 }
SetCIType(CIRunType NewVal)284 CIRunType ControlGroup::SetCIType(CIRunType NewVal) {
285 	MPLevelCIType = (MPLevelCIType&0x0F) + (NewVal<<4);
286 	return (CIRunType)(MPLevelCIType & 0xF0);
287 }
GetCIType(void) const288 CIRunType ControlGroup::GetCIType(void) const {
289 	short result = ((MPLevelCIType & 0xF0)>>4);
290 	if (GetSCFType() == 2) result = 0;
291 	return (CIRunType) result;
292 };
SetRunType(const TypeOfRun & NewRunType)293 TypeOfRun ControlGroup::SetRunType(const TypeOfRun & NewRunType) {
294 	if ((NewRunType<=0)||(NewRunType>NumGAMESSRunTypes)) return InvalidRunType;
295 
296 	RunType = NewRunType;
297 	return RunType;
298 }
SetRunType(const char * RunText)299 TypeOfRun ControlGroup::SetRunType(const char *RunText) {
300 	TypeOfRun NewType = InvalidRunType;
301 
302 	for (int i=1; i<NumGAMESSRunTypes; i++) {
303 		const char * test = GetGAMESSRunText((TypeOfRun)i);
304 		if (-1<LocateKeyWord(RunText, test, strlen(test), 9)) {
305 			NewType = (TypeOfRun)i;
306 			if (NewType == TDHFRun) {
307 				test = GetGAMESSRunText(TDHFXRun);
308 				if (-1<LocateKeyWord(RunText, test, strlen(test), 9)) {
309 					NewType = TDHFXRun;
310 				}
311 			}
312 			break;
313 		}
314 	}
315 
316 	if (NewType<=0) return InvalidRunType;
317 
318 	RunType = NewType;
319 	return RunType;
320 }
GetGAMESSRunText(const TypeOfRun & r)321 const char * ControlGroup::GetGAMESSRunText(const TypeOfRun & r) {
322 	switch (r) {
323 		case Energy:
324 			return "ENERGY";
325 		case GradientRun:
326 			return "GRADIENT";
327 		case HessianRun:
328 			return "HESSIAN";
329 		case OptimizeRun:
330 			return "OPTIMIZE";
331 		case TrudgeRun:
332 			return "TRUDGE";
333 		case SadPointRun:
334 			return "SADPOINT";
335 		case MinEnergyCrossing:
336 			return "MEX";
337 		case IRCRun:
338 			return "IRC";
339 		case MolDynamics:
340 			return "MD";
341 		case GradExtrRun:
342 			return "GRADEXTR";
343 		case DRCRun:
344 			return "DRC";
345 		case SurfaceRun:
346 			return "SURFACE";
347 		case G3MP2:
348 			return "G3MP2";
349 		case PropRun:
350 			return "PROP";
351 		case MorokumaRun:
352 			return "MOROKUMA";
353 		case TransitnRun:
354 			return "TRANSITN";
355 		case SpinOrbitRun:
356 			return "SPINORBT";
357 		case FFieldRun:
358 			return "FFIELD";
359 		case TDHFRun:
360 			return "TDHF";
361 		case TDHFXRun:
362 			return "TDHFX";
363 		case GLOBOPRun:
364 			return "GLOBOP";
365 		case VSCFRun:
366 			return "VSCF";
367 		case OptFMORun:
368 			return "OPTFMO";
369 		case RamanRun:
370 			return "RAMAN";
371 		case NMRRun:
372 			return "NMR";
373 		case MakeEFPRun:
374 			return "MAKEFP";
375 		case FreeStateFMORun:
376 			return "FMO0";
377 		default:
378 			return "unknown";
379 	}
380 }
GetGAMESSCCType(const CCRunType & r)381 const char * ControlGroup::GetGAMESSCCType(const CCRunType & r) {
382 	switch (r) {
383 		case CC_None:
384 			return "NONE";
385 		case CC_LCCD:
386 			return "LCCD";
387 		case CC_CCD:
388 			return "CCD";
389 		case CC_CCSD:
390 			return "CCSD";
391 		case CC_CCSDT:
392 			return "CCSD(T)";
393 		case CC_RCC:
394 			return "R-CC";
395 		case CC_CRCC:
396 			return "CR-CC";
397 		case CC_CRCCL:
398 			return "CR-CCL";
399 		case CC_CCSDTQ:
400 			return "CCSD(TQ)";
401 		case CC_CRCCQ:
402 			return "CR-CC(Q)";
403 		case CC_EOMCCSD:
404 			return "EOM-CCSD";
405 		case CC_CREOM:
406 			return "CR-EOM";
407 		case CC_CREOML:
408 			return "CR-EOML";
409 		case CC_IP_EOM2:
410 			return "IP-EOM2";
411 		case CC_IP_EOM3A:
412 			return "IP-EOM3A";
413 		case CC_EA_EOM2:
414 			return "EA-EOM2";
415 		case CC_EA_EOM3A:
416 			return "EA-EOM3A";
417 		default:
418 			return "unknown";
419 	}
420 }
SetCCType(CCRunType n)421 CCRunType ControlGroup::SetCCType(CCRunType n) {
422 	CCType = n;
423 	return CCType;
424 }
SetCCType(const char * n)425 CCRunType ControlGroup::SetCCType(const char * n) {
426 	CCRunType NewType = CC_None;
427 
428 	for (int i=1; i<NumCCTypes; i++) {
429 		const char * test = GetGAMESSCCType((CCRunType)i);
430 		if (-1<LocateKeyWord(n, test, strlen(test), 8)) {
431 			NewType = (CCRunType)i;
432 			break;
433 		}
434 	}
435 
436 	if (NewType<=0) return CC_None;
437 
438 	CCType = NewType;
439 	return CCType;
440 }
GetCCType(void) const441 CCRunType ControlGroup::GetCCType(void) const {
442 	CCRunType result = CCType;
443 
444 	if (GetSCFType() > 1) result = CC_None;
445 	if (GetCIType() > 0) result = CC_None;
446 	return result;
447 }
GetExeType(void)448 short ControlGroup::GetExeType(void) {
449 	if ((ExeType==NULL)||(0<=LocateKeyWord(ExeType, "RUN", 3,3))) return 0;	//Normal run
450 	if (0<=LocateKeyWord(ExeType, "CHECK", 5,5)) return 1;
451 	if (0<=LocateKeyWord(ExeType, "DEBUG", 5,5)) return 2;
452 	return 3;
453 }
SetExeType(const char * ExeText)454 short ControlGroup::SetExeType(const char *ExeText) {
455 	if (ExeText==NULL) return 0;
456 	long nchar = strlen(ExeText);
457 	if (ExeType) {
458 		delete [] ExeType;
459 		ExeType = NULL;
460 	}
461 	ExeType = new char[nchar+1];
462 	strcpy(ExeType, ExeText);
463 	return nchar;
464 }
SetExeType(short NewType)465 short ControlGroup::SetExeType(short NewType) {
466 	if ((NewType < 0)||(NewType > 2)) return -1;
467 	if (ExeType) {
468 		delete [] ExeType;
469 		ExeType = NULL;
470 	}
471 	if (NewType==1) {
472 		ExeType = new char[6];
473 		strcpy(ExeType, "CHECK");
474 	} else if (NewType == 2) {
475 		ExeType = new char[6];
476 		strcpy(ExeType, "DEBUG");
477 	}
478 	return NewType;
479 }
SetCIType(const char * CIText)480 CIRunType ControlGroup::SetCIType(const char * CIText) {
481 	CIRunType newType = CI_None;
482 	if (-1<FindKeyWord(CIText, "GUGA", 4)) newType = CI_GUGA;
483 	else if (-1<FindKeyWord(CIText, "ALDET", 5)) newType = CI_ALDET;
484 	else if (-1<FindKeyWord(CIText, "ORMAS", 5)) newType = CI_ORMAS;
485 	else if (-1<FindKeyWord(CIText, "CIS", 3)) newType = CI_CIS;
486 	else if (-1<FindKeyWord(CIText, "FSOCI", 5)) newType = CI_FSOCI;
487 	else if (-1<FindKeyWord(CIText, "GENCI", 5)) newType = CI_GENCI;
488 	return SetCIType(newType);
489 }
GetCIType(const CIRunType & citype) const490 const char * ControlGroup::GetCIType(const CIRunType & citype) const {
491 	switch (citype) {
492 		default:
493 			return "NONE";
494 		case CI_GUGA:
495 			return "GUGA";
496 		case CI_ALDET:
497 			return "ALDET";
498 		case CI_ORMAS:
499 			return "ORMAS";
500 		case CI_CIS:
501 			return "CIS";
502 		case CI_FSOCI:
503 			return "FSOCI";
504 		case CI_GENCI:
505 			return "GENCI";
506 	}
507 }
GetCIType(char * outText) const508 CIRunType ControlGroup::GetCIType(char * outText) const {
509 	CIRunType temp = GetCIType();
510 	if (outText != NULL) {
511 		strcpy(outText, GetCIType(temp));
512 	}
513 	return temp;
514 }
SetMaxIt(short NewVal)515 short ControlGroup::SetMaxIt(short NewVal) {
516 	if (NewVal>=0) MaxIt = NewVal;
517 	return MaxIt;
518 }
SetLocal(GAMESS_Localization NewVal)519 GAMESS_Localization ControlGroup::SetLocal(GAMESS_Localization NewVal) {
520 	if ((NewVal>=GAMESS_No_Localization)&&(NewVal<NumGAMESSLocalizations)) Local = NewVal;
521 	return Local;
522 }
SetLocal(const char * t)523 GAMESS_Localization ControlGroup::SetLocal(const char * t) {
524 	GAMESS_Localization temp = Invalid_Localization;
525 	for (int i=0; i<NumGAMESSLocalizations; i++) {
526 		if (!strcasecmp(t, GAMESSLocalizationToText((GAMESS_Localization) i))) {
527 			temp = (GAMESS_Localization) i;
528 			break;
529 		}
530 	}
531 	if (temp != Invalid_Localization) Local = temp;
532 	return temp;
533 }
GAMESSLocalizationToText(GAMESS_Localization t)534 const char * ControlGroup::GAMESSLocalizationToText(GAMESS_Localization t) {
535 	switch (t) {
536 		case GAMESS_No_Localization:
537 			return "NONE";
538 		case GAMESS_BOYS_Localization:
539 			return "BOYS";
540 		case GAMESS_RUEDNBRG_Localization:
541 			return "RUEDNBRG";
542 		case GAMESS_POP_Localization:
543 			return "POP";
544 		case GAMESS_SVD_Localization:
545 			return "SVD";
546 		default:
547 			wxLogMessage(_T("Attempt to convert invalid GAMESS Localization"));
548 	}
549 	return "invalid";
550 }
GetFriendText(FriendType f)551 const char * ControlGroup::GetFriendText(FriendType f) {
552 	switch (f) {
553 		case Friend_HONDO:
554 			return "HONDO";
555 		case Friend_MELDF:
556 			return "MELDF";
557 		case Friend_GAMESSUK:
558 			return "GAMESSUK";
559 		case Friend_GAUSSIAN:
560 			return "GAUSSIAN";
561 		case Friend_ALL:
562 			return "ALL";
563 		default:
564 			wxLogMessage(_T("Attempt to convert invalid Friend text"));
565 	}
566 	return "invalid";	//Getting to here indicates a bad value
567 }
TextToFriend(const char * c)568 FriendType ControlGroup::TextToFriend(const char * c) {
569 	FriendType result = Friend_None;
570 	for (int i=0; i<NumFriendTypes; i++) {
571 		if (!strcasecmp(c, GetFriendText((FriendType) i))) {
572 			result = (FriendType) i;
573 			break;
574 		}
575 	}
576 	return result;
577 }
SetFriend(FriendType NewValue)578 FriendType ControlGroup::SetFriend(FriendType NewValue) {
579 	if ((NewValue >= Friend_None)&&(NewValue < NumFriendTypes)) Friend = NewValue;
580 	return (FriendType)Friend;
581 }
SetFriend(const char * c)582 FriendType ControlGroup::SetFriend(const char * c) {
583 	return SetFriend(TextToFriend(c));
584 }
SetCharge(short NewCharge)585 short ControlGroup::SetCharge(short NewCharge) {
586 	Charge = NewCharge;
587 	return Charge;
588 }
SetMultiplicity(short NewMult)589 short ControlGroup::SetMultiplicity(short NewMult) {
590 	Multiplicity = NewMult;
591 	return Multiplicity;
592 }
SetMolPlot(bool State)593 bool ControlGroup::SetMolPlot(bool State) {
594 	if (Options & 1) Options -= 1;
595 	if (State) Options += 1;
596 	return ((Options & 1)?true:false);
597 }
SetPlotOrb(bool State)598 bool ControlGroup::SetPlotOrb(bool State) {
599 	if (Options & (1<<1)) Options -= (1<<1);
600 	if (State) Options += (1<<1);
601 	return ((Options & (1<<1))?true:false);
602 }
SetAIMPAC(bool State)603 bool ControlGroup::SetAIMPAC(bool State) {
604 	if (Options & (1<<2)) Options -= (1<<2);
605 	if (State) Options += (1<<2);
606 	return ((Options & (1<<2))?true:false);
607 }
SetRPAC(bool State)608 bool ControlGroup::SetRPAC(bool State) {
609 	if (Options & (1<<3)) Options -= (1<<3);
610 	if (State) Options += (1<<3);
611 	return ((Options & (1<<3))?true:false);
612 }
UseSphericalHarmonics(bool State)613 bool ControlGroup::UseSphericalHarmonics(bool State) {
614 	if (Options & (1<<5)) Options -= (1<<5);
615 	if (State) Options += (1<<5);
616 	return ((Options & (1<<5))?true:false);
617 }
SetNormF(bool State)618 bool ControlGroup::SetNormF(bool State) {
619 	if (Options & (1<<6)) Options -= (1<<6);
620 	if (State) Options += (1<<6);
621 	return ((Options & (1<<6))?true:false);
622 }
UseDFT(bool State)623 bool ControlGroup::UseDFT(bool State) {
624 	if (Options & (1<<4)) Options -= (1<<4);
625 	if (State) Options += (1<<4);
626 	return (UseDFT());
627 }
UseDFT(void) const628 bool ControlGroup::UseDFT(void) const {
629 	bool result = false;
630 	result = ((Options & (1<<4))?true:false);
631 	if (GetSCFType() > 3) result = false;
632 	if (GetMPLevel() > 0) result = false;
633 	if (GetCIType() > 0) result = false;
634 	if (GetCCType() != CC_None) result = false;
635 	return result;
636 }
SetNormP(bool State)637 bool ControlGroup::SetNormP(bool State) {
638 	if (Options & (1<<7)) Options -= (1<<7);
639 	if (State) Options += (1<<7);
640 	return GetNormP();
641 }
ReadXML(XMLElement * parent)642 void ControlGroup::ReadXML(XMLElement * parent) {
643 	XMLElementList * children = parent->getChildren();
644 	if (children) {
645 		for (int i=0; i<children->length(); i++) {
646 			XMLElement * child = children->item(i);
647 			MMP_IOControlGroupNS item;
648 			if (child && CML_convert(child->getName(), item)) {
649 				bool tb;
650 				switch (item) {
651 					case MMP_IOCGSCFType:
652 					{
653 						const char * v = child->getValue();
654 						if (v) SetSCFType(v);
655 					}
656 						break;
657 					case MMP_IOCGRunType:
658 					{
659 						const char * v = child->getValue();
660 						if (v) SetRunType(v);
661 					}
662 						break;
663 					case MMP_IOCGExeType:
664 					{
665 						const char * v = child->getValue();
666 						if (v) SetExeType(v);
667 					}
668 						break;
669 					case MMP_IOCGMPLevel:
670 					{
671 						const char * v = child->getValue();
672 						if (v) {
673 							int mpl;
674 							sscanf(v, "%d", &mpl);
675 							SetMPLevel(mpl);
676 						}
677 					}
678 						break;
679 					case MMP_IOCGCIType:
680 					{
681 						const char * v = child->getValue();
682 						if (v) SetCIType(v);
683 					}
684 						break;
685 					case MMP_IOCGCCType:
686 					{
687 						const char * v = child->getValue();
688 						if (v) SetCCType(v);
689 					}
690 						break;
691 					case MMP_IOCGMaxIterations:
692 					{
693 						const char * v = child->getValue();
694 						if (v) {
695 							int mit;
696 							sscanf(v, "%d", &mit);
697 							SetMaxIt(mit);
698 						}
699 					}
700 						break;
701 					case MMP_IOCGCharge:
702 					{
703 						const char * v = child->getValue();
704 						if (v) {
705 							int chg;
706 							sscanf(v, "%d", &chg);
707 							SetCharge(chg);
708 						}
709 					}
710 						break;
711 					case MMP_IOCGMultiplicity:
712 					{
713 						const char * v = child->getValue();
714 						if (v) {
715 							int mul;
716 							sscanf(v, "%d", &mul);
717 							SetMultiplicity(mul);
718 						}
719 					}
720 						break;
721 					case MMP_IOCGLocalization:
722 					{
723 						const char * v = child->getValue();
724 						if (v) SetLocal(v);
725 					}
726 						break;
727 					case MMP_IOCGFriend:
728 					{
729 						const char * v = child->getValue();
730 						if (v) SetFriend(v);
731 					}
732 						break;
733 					case MMP_IOCGPrintOption:
734 					{
735 						const char * v = child->getValue();
736 						if (v) {
737 							int np;
738 							sscanf(v, "%d", &np);
739 							NPrint = np;
740 						}
741 					}
742 						break;
743 					case MMP_IOCGTolerance:
744 					{
745 						const char * v = child->getValue();
746 						if (v) {
747 							int it;
748 							sscanf(v, "%d", &it);
749 							ITol = it;
750 						}
751 					}
752 						break;
753 					case MMP_IOCGCutoff:
754 					{
755 						const char * v = child->getValue();
756 						if (v) {
757 							int it;
758 							sscanf(v, "%d", &it);
759 							ICut = it;
760 						}
761 					}
762 						break;
763 					case MMP_IOCGMolPlt:
764 						if (child->getBoolValue(tb))
765 							SetMolPlot(tb);
766 						break;
767 					case MMP_IOCGPlotOrb:
768 						if (child->getBoolValue(tb))
769 							SetPlotOrb(tb);
770 						break;
771 					case MMP_IOCGAIMPac:
772 						if (child->getBoolValue(tb))
773 							SetAIMPAC(tb);
774 						break;
775 					case MMP_IOCGRPac:
776 						if (child->getBoolValue(tb))
777 							SetRPAC(tb);
778 						break;
779 					case MMP_IOCGDFTActive:
780 						if (child->getBoolValue(tb))
781 							UseDFT(tb);
782 						break;
783 					case MMP_IOCGSphericalHarm:
784 						if (child->getBoolValue(tb))
785 							UseSphericalHarmonics(tb);
786 						break;
787 					case MMP_IOCGNormF:
788 						if (child->getBoolValue(tb))
789 							SetNormF(tb);
790 						break;
791 					case MMP_IOCGNormP:
792 						if (child->getBoolValue(tb))
793 							SetNormP(tb);
794 						break;
795 					default:
796 					{
797 						wxString msg;
798 						msg.Printf(_T("Unknown control group CML element: %s"), child->getName());
799 						wxLogMessage(msg);
800 					}
801 				}
802 			}
803 		}
804 		delete children;
805 	}
806 }
WriteXML(XMLElement * parent) const807 void ControlGroup::WriteXML(XMLElement * parent) const {
808 	char line[kMaxLineLength];
809 	XMLElement * Ele = parent->addChildElement(CML_convert(MMP_IOControlGroupElement));
810 	if (SCFType)
811 		Ele->addChildElement(CML_convert(MMP_IOCGSCFType), GetSCFTypeText());
812 	if (ExeType) Ele->addChildElement(CML_convert(MMP_IOCGExeType), ExeType);
813 	Ele->addChildElement(CML_convert(MMP_IOCGCIType), GetCIType(GetCIType()));
814 	Ele->addChildElement(CML_convert(MMP_IOCGRunType), GetGAMESSRunText(GetRunType()));
815 	snprintf(line, kMaxLineLength, "%d", GetMPLevel());
816 	Ele->addChildElement(CML_convert(MMP_IOCGMPLevel), line);
817 	if (GetCCType() != CC_None)
818 		Ele->addChildElement(CML_convert(MMP_IOCGCCType), GetGAMESSCCType(GetCCType()));
819 	if (MaxIt) {
820 		snprintf(line, kMaxLineLength, "%d", MaxIt);
821 		Ele->addChildElement(CML_convert(MMP_IOCGMaxIterations), line);
822 	}
823 	if (Charge) {
824 		snprintf(line, kMaxLineLength, "%d", Charge);
825 		Ele->addChildElement(CML_convert(MMP_IOCGCharge), line);
826 	}
827 	if (Multiplicity) {
828 		snprintf(line, kMaxLineLength, "%d", Multiplicity);
829 		Ele->addChildElement(CML_convert(MMP_IOCGMultiplicity), line);
830 	}
831 	if (Local) {
832 		Ele->addChildElement(CML_convert(MMP_IOCGLocalization), GetLocalText());
833 	}
834 	if (Friend) {	//punchs out input to other programs, disables exetype (forces check run)
835 		Ele->addChildElement(CML_convert(MMP_IOCGFriend), GetFriendText());
836 	}
837 	if (NPrint) {
838 		snprintf(line, kMaxLineLength, "%d", NPrint);
839 		Ele->addChildElement(CML_convert(MMP_IOCGPrintOption), line);
840 	}
841 	if (ITol) {
842 		snprintf(line, kMaxLineLength, "%d", ITol);
843 		Ele->addChildElement(CML_convert(MMP_IOCGTolerance), line);
844 	}
845 	if (ICut) {
846 		snprintf(line, kMaxLineLength, "%d", ICut);
847 		Ele->addChildElement(CML_convert(MMP_IOCGCutoff), line);
848 	}
849 	if (GetMolPlot()) Ele->addChildElement(CML_convert(MMP_IOCGMolPlt), trueXML);
850 	if (GetPlotOrb()) Ele->addChildElement(CML_convert(MMP_IOCGPlotOrb), trueXML);
851 	if (GetAIMPAC()) Ele->addChildElement(CML_convert(MMP_IOCGAIMPac), trueXML);
852 	if (GetRPAC()) Ele->addChildElement(CML_convert(MMP_IOCGRPac), trueXML);
853 	if (UseDFT()) Ele->addChildElement(CML_convert(MMP_IOCGDFTActive), trueXML);
854 	if (UseSphericalHarmonics()) Ele->addChildElement(CML_convert(MMP_IOCGSphericalHarm), trueXML);
855 	if (GetNormF()) Ele->addChildElement(CML_convert(MMP_IOCGNormF), trueXML);
856 	if (GetNormP()) Ele->addChildElement(CML_convert(MMP_IOCGNormP), trueXML);
857 }
WriteToFile(BufferFile * File,InputData * IData,long NumElectrons)858 void ControlGroup::WriteToFile(BufferFile *File, InputData *IData, long NumElectrons) {
859 	char	Out[133], textVal[133];
860 
861 		//Punch the group label
862 	File->WriteLine(" $CONTRL ", false);
863 		//punch the SCF type and Run type
864 	if (SCFType) {
865 		sprintf(Out,"SCFTYP=%s ",GetSCFTypeText());
866 		File->WriteLine(Out, false);
867 	} else {	//Punch out the default RHF/ROHF wavefunction
868 		if (NumElectrons & 1) sprintf(Out, "SCFTYP=ROHF ");
869 		else sprintf(Out, "SCFTYP=RHF ");
870 		File->WriteLine(Out, false);
871 	}
872 	TypeOfRun t = GetRunType();
873 	if (t <= InvalidRunType) t = Energy;
874 	sprintf(Out,"RUNTYP=%s ", GetGAMESSRunText(t));
875 	File->WriteLine(Out, false);
876 	if ((ExeType)&&(!Friend)) {	//punch out ExeType if it is other than run
877 		sprintf(Out, "EXETYP=%s ", ExeType);
878 		File->WriteLine(Out, false);
879 	}
880 	if (GetMPLevel() > 0) {	//Write out MP level only if > zero
881 		sprintf(Out,"MPLEVL=2 ");
882 		File->WriteLine(Out, false);
883 	}
884 	if (GetCIType() || (GetSCFType() == 6)) {	//punch CIType if CI requested
885 		GetCIType(textVal);
886 		sprintf(Out, "CITYP=%s ", textVal);
887 		File->WriteLine(Out, false);
888 	}
889 	if (GetCCType() != CC_None) {
890 		sprintf(Out, "CCTYP=%s ", GetGAMESSCCType(CCType));
891 		File->WriteLine(Out, false);
892 	}
893 
894 	if (UseDFT()) {
895 		sprintf(Out, "DFTTYP=%s ", IData->DFT.GetFunctionalText());
896 		File->WriteLine(Out, false);
897 	}
898 
899 	if (MaxIt) {	//Punch Maxit if non-default value
900 		sprintf(Out, "MAXIT=%d ",MaxIt);
901 		File->WriteLine(Out, false);
902 	}
903 	if (Charge) {
904 		sprintf(Out, "ICHARG=%d ", Charge);
905 		File->WriteLine(Out, false);
906 	}
907 	if (Multiplicity) {
908 		sprintf(Out, "MULT=%d ", Multiplicity);
909 		File->WriteLine(Out, false);
910 	} else if (NumElectrons & 1) {	//for odd electron systems punch out a default doublet
911 		sprintf(Out, "MULT=2 ");
912 		File->WriteLine(Out, false);
913 	}
914 	if (Local) {
915 		sprintf(Out, "LOCAL=%s ", GetLocalText());
916  		File->WriteLine(Out, false);
917 	}
918 	if (IData->Basis) {
919 		if (IData->Basis->GetECPPotential()) {
920 			sprintf(Out, "PP=%s ",IData->Basis->GetECPPotentialText());
921 	 		File->WriteLine(Out, false);
922 		}
923 	}
924 	bool tempSphere = UseSphericalHarmonics();
925 	if (!tempSphere && IData->Basis) {
926 		if ((IData->Basis->GetBasis()>=GAMESS_BS_CC_PVDZ)&&(IData->Basis->GetBasis()<=GAMESS_BS_APC4))
927 			tempSphere = true;
928 	}
929 	if (tempSphere) {
930 		sprintf(Out, "ISPHER=1 ");
931 		File->WriteLine(Out, false);
932 	}
933 	if (IData->Data) {
934 		if (IData->Data->GetCoordType()) {
935 			sprintf(Out, "COORD=%s ", IData->Data->GetCoordText());
936 	 		File->WriteLine(Out, false);
937 		}
938 		if (IData->Data->GetUnits()) {
939 			sprintf(Out, "UNITS=BOHR ");
940 	 		File->WriteLine(Out, false);
941 		}
942 		if (IData->Data->GetNumZVar()) {
943 			sprintf(Out, "NZVAR=%d ",IData->Data->GetNumZVar());
944 	 		File->WriteLine(Out, false);
945 		}
946 		if (!IData->Data->GetUseSym()) {
947 			sprintf(Out, "NOSYM=1 ");
948 	 		File->WriteLine(Out, false);
949 		}
950 	}
951 	if (Friend) {	//punchs out input to other programs, disables exetype (forces check run)
952 		sprintf(Out, "FRIEND=%s ", GetFriendText());
953  		File->WriteLine(Out, false);
954 	}
955 	if (GetMolPlot()) {
956 		sprintf(Out, "MOLPLT=.TRUE. ");
957  		File->WriteLine(Out, false);
958 	}
959 	if (GetPlotOrb()) {
960 		sprintf(Out, "PLTORB=.TRUE. ");
961  		File->WriteLine(Out, false);
962 	}
963 	if ((1!=GetExeType())&&(Friend==0)) {
964 		if (GetAIMPAC()) {
965 			sprintf(Out, "AIMPAC=.TRUE. ");
966 	 		File->WriteLine(Out, false);
967 		}
968 		if (GetRPAC()) {
969 			sprintf(Out, "RPAC=.TRUE. ");
970 	 		File->WriteLine(Out, false);
971 		}
972 	}
973 
974 	File->WriteLine("$END", true);
975 }
RevertControlPane(ControlGroup * OldData)976 void ControlGroup::RevertControlPane(ControlGroup *OldData) {
977 	RunType = OldData->RunType;
978 	SCFType = OldData->SCFType;
979 	SetMPLevel(OldData->GetMPLevel());
980 	UseDFT(OldData->UseDFT());
981 	SetCIType(OldData->GetCIType());
982 	SetCCType(OldData->GetCCType());
983 	MaxIt = OldData->MaxIt;
984 	if (ExeType) {
985 		delete [] ExeType;
986 		ExeType = NULL;
987 	}
988 	SetExeType(OldData->ExeType);
989 	Local = OldData->Local;
990 	Charge = OldData->Charge;
991 	Multiplicity = OldData->Multiplicity;
992 }
RevertProgPane(ControlGroup * OldData)993 void ControlGroup::RevertProgPane(ControlGroup *OldData) {
994 	SetMolPlot(OldData->GetMolPlot());
995 	SetPlotOrb(OldData->GetPlotOrb());
996 	SetAIMPAC(OldData->GetAIMPAC());
997 	SetRPAC(OldData->GetRPAC());
998 	SetFriend(OldData->GetFriend());
999 }
1000 #pragma mark SystemGroup
1001 		//SystemGroup member functions
SetTimeLimit(long NewTime)1002 long SystemGroup::SetTimeLimit(long NewTime) {
1003 	if (NewTime >= 0) TimeLimit = NewTime;
1004 	return TimeLimit;
1005 }
MemoryUnitToText(const MemoryUnit & mu)1006 const char * MemoryUnitToText(const MemoryUnit & mu) {
1007 	switch (mu) {
1008 		case wordsUnit:
1009 			return "words";
1010 		case bytesUnit:
1011 			return "bytes";
1012 		case megaWordsUnit:
1013 			return "Mwords";
1014 		case megaBytesUnit:
1015 			return "MB";
1016 		case gigaWordsUnit:
1017 			return "Gwords";
1018 		case gigaBytesUnit:
1019 			return "GB";
1020 		default:
1021 			wxLogMessage(_T("Attempt to convert invalid memory unit"));
1022 	}
1023 	return "invalid";
1024 }
TextToMemoryUnit(const char * t,MemoryUnit & mu)1025 bool TextToMemoryUnit(const char * t, MemoryUnit & mu) {
1026 	if (!t || !*t) return false;
1027 	for (int i = (int) wordsUnit; i != (int) NumberMemoryUnits; ++i) {
1028 		if (strcasecmp(t, MemoryUnitToText((MemoryUnit) i)) == 0) {
1029 			mu = (MemoryUnit) i;
1030 			return true;
1031 		}
1032 	}
1033 	return false;
1034 }
TimeUnitToText(const TimeUnit & tu)1035 const char * TimeUnitToText(const TimeUnit & tu) {
1036 	switch (tu) {
1037 		case secondUnit:
1038 			return "sec";
1039 		case minuteUnit:
1040 			return "min";
1041 		case hourUnit:
1042 			return "hr";
1043 		case dayUnit:
1044 			return "days";
1045 		case weekUnit:
1046 			return "weeks";
1047 		case yearUnit:
1048 			return "years";
1049 		case milleniaUnit:
1050 			return "millenia";
1051 		default:
1052 			wxLogMessage(_T("Attempt to convert invalid time unit"));
1053 	}
1054 	return "invalid";
1055 }
TextToTimeUnit(const char * t,TimeUnit & tu)1056 bool TextToTimeUnit(const char * t, TimeUnit & tu) {
1057 	if (!t || !*t) return false;
1058 	for (int i = (int) secondUnit; i != (int) NumberTimeUnits; ++i) {
1059 		if (strcasecmp(t, TimeUnitToText((TimeUnit) i)) == 0) {
1060 			tu = (TimeUnit) i;
1061 			return true;
1062 		}
1063 	}
1064 	return false;
1065 }
SetTimeUnits(TimeUnit NewUnits)1066 TimeUnit SystemGroup::SetTimeUnits(TimeUnit NewUnits) {
1067 	if ((NewUnits >= secondUnit)&&(NewUnits<NumberTimeUnits)) TimeUnits = NewUnits;
1068 	return TimeUnits;
1069 }
GetConvertedTime(void) const1070 float SystemGroup::GetConvertedTime(void) const {
1071 	float result, factor=1.0f;
1072 
1073 	if (TimeLimit) result = TimeLimit;
1074 	else result = 525600.0f;
1075 
1076 	switch (TimeUnits) {
1077 		case milleniaUnit:
1078 			factor = 1.0/1000.0;
1079 		case yearUnit:
1080 			factor *= 1/52.0;
1081 		case weekUnit:
1082 			factor *= 1/7.0;
1083 		case dayUnit:
1084 			factor *= 1/24.0;
1085 		case hourUnit:
1086 			factor *= 1/60.0;
1087 		case minuteUnit:
1088 		break;
1089 		case secondUnit:
1090 			factor = 60.0f;
1091 		break;
1092 		default:
1093 			wxLogMessage(_T("Attempt to use Convert invalid time unit"));
1094 	}
1095 	result *= factor;
1096 	return result;
1097 }
SetConvertedTime(float NewTime)1098 long SystemGroup::SetConvertedTime(float NewTime) {
1099 	long	result=-1, factor = 1;
1100 
1101 	switch (TimeUnits) {
1102 		case milleniaUnit:
1103 			factor = 1000;
1104 		case yearUnit:
1105 			factor *= 52;
1106 		case weekUnit:
1107 			factor *= 7;
1108 		case dayUnit:
1109 			factor *= 24;
1110 		case hourUnit:
1111 			factor *= 60;
1112 		case minuteUnit:
1113 			result = (long)(NewTime * factor);
1114 		break;
1115 		case secondUnit:
1116 			result = (long)(NewTime/60.0);
1117 		break;
1118 		default:
1119 			wxLogMessage(_T("Attempt to set time with invalid unit"));
1120 	}
1121 	if (result >= 0) TimeLimit = result;
1122 	return TimeLimit;
1123 }
SetMemory(double NewMemory)1124 double SystemGroup::SetMemory(double NewMemory) {
1125 	if (NewMemory > 0.0) Memory = NewMemory;
1126 	return Memory;
1127 }
SetMemUnits(MemoryUnit NewUnits)1128 MemoryUnit SystemGroup::SetMemUnits(MemoryUnit NewUnits) {
1129 	if ((NewUnits>=wordsUnit)&&(NewUnits<NumberMemoryUnits)) MemUnits = NewUnits;
1130 	return MemUnits;
1131 }
GetConvertedMem(void) const1132 double SystemGroup::GetConvertedMem(void) const {
1133 	double result, factor=1.0;
1134 
1135 	if (Memory) result = Memory;
1136 	else result = 1000000;
1137 
1138 	switch (MemUnits) {
1139 		case wordsUnit:
1140 			factor = 1.0;
1141 			break;
1142 		case bytesUnit:
1143 			factor = 8.0;
1144 		break;
1145 		case megaWordsUnit:
1146 			factor = 1.0/1000000.0;
1147 		break;
1148 		case megaBytesUnit:
1149 			factor = 8.0/(1024*1024);
1150 		break;
1151 		case gigaWordsUnit:
1152 			factor = 1.0/1000000000.0;
1153 		break;
1154 		case gigaBytesUnit:
1155 			factor = 8.0/(1024*1024*1024);
1156 		break;
1157 		default:
1158 			wxLogMessage(_T("Attempt to convert memory with invalid unit"));
1159 	}
1160 	result *= factor;
1161 	return result;
1162 }
SetConvertedMem(double NewMem)1163 double SystemGroup::SetConvertedMem(double NewMem) {
1164 	double	result=-1, factor = 1;
1165 
1166 	switch (MemUnits) {
1167 		case gigaBytesUnit:
1168 			factor *= 1024;
1169 		case megaBytesUnit:
1170 			factor *= 1024*1024;
1171 		case bytesUnit:
1172 			result = (long)(factor*NewMem/8.0);
1173 		break;
1174 		case gigaWordsUnit:
1175 			factor *= 1000;
1176 		case megaWordsUnit:
1177 			factor *= 1000000;
1178 		case wordsUnit:
1179 			result = (long)(factor*NewMem);
1180 		break;
1181 		default:
1182 			wxLogMessage(_T("Attempt to set memory with invalid unit"));
1183 	}
1184 	if (result >= 0) Memory = result;
1185 	return Memory;
1186 }
SetMemDDI(double NewMemory)1187 double SystemGroup::SetMemDDI(double NewMemory) {
1188 	if (NewMemory >= 0.0) MemDDI = NewMemory;
1189 	return Memory;
1190 }
SetMemDDIUnits(MemoryUnit NewUnits)1191 MemoryUnit SystemGroup::SetMemDDIUnits(MemoryUnit NewUnits) {
1192 	if ((NewUnits>=megaWordsUnit)&&(NewUnits<NumberMemoryUnits)) MemDDIUnits = NewUnits;
1193 	return MemDDIUnits;
1194 }
GetConvertedMemDDI(void) const1195 double SystemGroup::GetConvertedMemDDI(void) const {
1196 	double result, factor=1.0;
1197 
1198 	result = MemDDI;	//memDDI is stored in MW
1199 
1200 	switch (MemDDIUnits) {
1201 		case megaWordsUnit:
1202 			factor = 1.0;
1203 			break;
1204 		case megaBytesUnit:
1205 			factor = 8.0;
1206 			break;
1207 		case gigaWordsUnit:
1208 			factor = 1.0/1000.0;
1209 			break;
1210 		case gigaBytesUnit:
1211 			factor = 8.0/(1000.0);
1212 			break;
1213 		default:
1214 			wxLogMessage(_T("Unhandled memory unit in GetConvertedMemDDI"));
1215 	}
1216 	result *= factor;
1217 	return result;
1218 }
SetConvertedMemDDI(double NewMem)1219 double SystemGroup::SetConvertedMemDDI(double NewMem) {
1220 	double	result, factor = 1;
1221 
1222 	switch (MemDDIUnits) {
1223 		case megaWordsUnit:
1224 			factor = 1.0;
1225 			break;
1226 		case megaBytesUnit:
1227 			factor = 1.0/8.0;
1228 			break;
1229 		case gigaWordsUnit:
1230 			factor = 1000.0;
1231 			break;
1232 		case gigaBytesUnit:
1233 			factor = 1000.0/8.0;
1234 			break;
1235 		default:
1236 			wxLogMessage(_T("Unhandled memory unit in SetConvertedMemDDI"));
1237 	}
1238 	result = NewMem*factor;
1239 	if (result >= 0) MemDDI = result;
1240 	return MemDDI;
1241 }
1242 
SetDiag(char NewMethod)1243 char SystemGroup::SetDiag(char NewMethod) {
1244 	if ((NewMethod>=0)&&(NewMethod<4)) KDiag = NewMethod;
1245 	return KDiag;
1246 }
SetCoreFlag(bool State)1247 bool SystemGroup::SetCoreFlag(bool State) {
1248 	if (Flags & 1) Flags --;
1249 	if (State) Flags ++;
1250 	return GetCoreFlag();
1251 }
SetBalanceType(bool Type)1252 bool SystemGroup::SetBalanceType(bool Type) {
1253 	if (Flags & 2) Flags -= 2;
1254 	if (Type) Flags += 2;
1255 	return GetBalanceType();
1256 }
SetXDR(bool State)1257 bool SystemGroup::SetXDR(bool State) {
1258 	if (Flags & 4) Flags -= 4;
1259 	if (State) Flags += 4;
1260 	return GetXDR();
1261 }
SetParallel(bool State)1262 bool SystemGroup::SetParallel(bool State) {
1263 	if (Flags & 8) Flags -= 8;
1264 	if (State) Flags += 8;
1265 	return GetParallel();
1266 }
SystemGroup(void)1267 SystemGroup::SystemGroup(void) {
1268 	InitData();
1269 }
SystemGroup(SystemGroup * Copy)1270 SystemGroup::SystemGroup(SystemGroup *Copy) {
1271 	if (Copy) *this=*Copy;
1272 }
InitData(void)1273 void SystemGroup::InitData(void) {
1274 	TimeLimit = 0;
1275 	Memory = 0.0;
1276 	MemDDI = 0.0;
1277 	KDiag = 0;
1278 	TimeUnits = minuteUnit;
1279 	MemUnits = wordsUnit;
1280 	MemDDIUnits = megaWordsUnit;
1281 	Flags = 0;
1282 }
WriteXML(XMLElement * parent) const1283 void SystemGroup::WriteXML(XMLElement * parent) const {
1284 	char line[kMaxLineLength];
1285 	XMLElement * Ele = parent->addChildElement(CML_convert(MMP_IOSystemGroupElement));
1286 	if (TimeLimit) {
1287 		snprintf(line, kMaxLineLength, "%f", GetConvertedTime());
1288 		XMLElement * t = Ele->addChildElement(CML_convert(MMP_IOSGTimeLimit), line);
1289 		t->addAttribute(CML_convert(MMP_IOSGTimeUnits), TimeUnitToText(TimeUnits));
1290 	}
1291 	if (Memory) {
1292 		snprintf(line, kMaxLineLength, "%lf", GetConvertedMem());
1293 		XMLElement * t = Ele->addChildElement(CML_convert(MMP_IOSGMemory), line);
1294 		t->addAttribute(CML_convert(MMP_IOSGMemoryUnits), MemoryUnitToText(MemUnits));
1295 	}
1296 	if (MemDDI) {
1297 		snprintf(line, kMaxLineLength, "%lf", GetConvertedMemDDI());
1298 		XMLElement * t = Ele->addChildElement(CML_convert(MMP_IOSGMemDDI), line);
1299 		t->addAttribute(CML_convert(MMP_IOSGMemoryUnits), MemoryUnitToText(MemDDIUnits));
1300 	}
1301 	if (KDiag) {
1302 		snprintf(line, kMaxLineLength, "%d", KDiag);
1303 		Ele->addChildElement(CML_convert(MMP_IOSGKDiag), line);
1304 	}
1305 	if (GetParallel()) Ele->addChildElement(CML_convert(MMP_IOSGParallel), trueXML);
1306 	if (GetCoreFlag()) Ele->addChildElement(CML_convert(MMP_IOSGCoreFlag), trueXML);
1307 	if (GetBalanceType()) Ele->addChildElement(CML_convert(MMP_IOSGBalanceType), trueXML);
1308 	if (GetXDR()) Ele->addChildElement(CML_convert(MMP_IOSGXDR), trueXML);
1309 }
ReadXML(XMLElement * parent)1310 void SystemGroup::ReadXML(XMLElement * parent) {
1311 	XMLElementList * children = parent->getChildren();
1312 	if (children) {
1313 		for (int i=0; i<children->length(); i++) {
1314 			XMLElement * child = children->item(i);
1315 			MMP_IOSystemGroupNS item;
1316 			if (child && CML_convert(child->getName(), item)) {
1317 				bool tb;
1318 				switch (item) {
1319 					case MMP_IOSGTimeLimit:
1320 					{
1321 						double temp;
1322 						if (child->getDoubleValue(temp)) {
1323 							const char * u = child->getAttributeValue(CML_convert(MMP_IOSGTimeUnits));
1324 							if (u) {
1325 								TimeUnit t;
1326 								if (TextToTimeUnit(u, t)) SetTimeUnits(t);
1327 							}
1328 							SetConvertedTime(temp);
1329 						}
1330 					}
1331 						break;
1332 					case MMP_IOSGMemory:
1333 					{
1334 						double temp;
1335 						if (child->getDoubleValue(temp)) {
1336 							const char * u = child->getAttributeValue(CML_convert(MMP_IOSGMemoryUnits));
1337 							if (u) {
1338 								MemoryUnit t;
1339 								if (TextToMemoryUnit(u, t)) SetMemUnits(t);
1340 							}
1341 							SetConvertedMem(temp);
1342 						}
1343 					}
1344 						break;
1345 					case MMP_IOSGKDiag:
1346 					{
1347 						long temp;
1348 						if (child->getLongValue(temp)) {
1349 							SetDiag(temp);
1350 						}
1351 					}
1352 						break;
1353 					case MMP_IOSGCoreFlag:
1354 						if (child->getBoolValue(tb))
1355 							SetCoreFlag(tb);
1356 						break;
1357 					case MMP_IOSGBalanceType:
1358 						if (child->getBoolValue(tb))
1359 							SetBalanceType(tb);
1360 						break;
1361 					case MMP_IOSGXDR:
1362 						if (child->getBoolValue(tb))
1363 							SetXDR(tb);
1364 						break;
1365 					case MMP_IOSGMemDDI:
1366 					{
1367 						double temp;
1368 						if (child->getDoubleValue(temp)) {
1369 							const char * u = child->getAttributeValue(CML_convert(MMP_IOSGMemoryUnits));
1370 							if (u) {
1371 								MemoryUnit t;
1372 								if (TextToMemoryUnit(u, t)) SetMemDDIUnits(t);
1373 							}
1374 							SetConvertedMemDDI(temp);
1375 						}
1376 					}
1377 						break;
1378 					case MMP_IOSGParallel:
1379 						if (child->getBoolValue(tb))
1380 							SetParallel(tb);
1381 						break;
1382 					default:
1383 					{
1384 						wxString msg;
1385 						msg.Printf(_T("Unknown system group CML element: %s"), child->getName());
1386 						wxLogMessage(msg);
1387 					}
1388 				}
1389 			}
1390 		}
1391 		delete children;
1392 	}
1393 }
WriteToFile(BufferFile * File)1394 void SystemGroup::WriteToFile(BufferFile *File) {
1395 	long	test;
1396 	char	Out[133];
1397 
1398 		//Punch the group label
1399 	File->WriteLine(" $SYSTEM ", false);
1400 		//Time limit
1401 	test = TimeLimit;
1402 	if (test==0) test = 600;
1403 	sprintf(Out,"TIMLIM=%ld ",test);
1404 	File->WriteLine(Out, false);
1405 		//Memory
1406 	if (Memory) {
1407 		sprintf(Out, "MEMORY=%ld ", (long)Memory);
1408 		File->WriteLine(Out, false);
1409 	}
1410 	if (MemDDI) {
1411 		sprintf(Out, "MEMDDI=%ld ", (long)MemDDI);
1412 		File->WriteLine(Out, false);
1413 	}	//PARALL
1414 	if (GetParallel()) {
1415 		sprintf(Out, "PARALL=.TRUE. ");
1416 		File->WriteLine(Out, false);
1417 	}	//diag method
1418 	if (KDiag) {
1419 		sprintf(Out, "KDIAG=%d ", KDiag);
1420 		File->WriteLine(Out, false);
1421 	}	//core flag
1422 	if (GetCoreFlag()) {
1423 		sprintf(Out, "COREFL=.TRUE. ");
1424 		File->WriteLine(Out, false);
1425 	}	//Balance type
1426 	if (GetBalanceType()) {
1427 		sprintf(Out, "BALTYP=NXTVAL ");
1428 		File->WriteLine(Out, false);
1429 	}	//XDR
1430 	if (GetXDR()) {
1431 		sprintf(Out, "XDR=.TRUE. ");
1432 		File->WriteLine(Out, false);
1433 	}
1434 	File->WriteLine("$END", true);
1435 }
1436 #pragma mark BasisGroup
1437 		//BasisGroup member functions
BasisGroup(void)1438 BasisGroup::BasisGroup(void) {
1439 	InitData();
1440 }
BasisGroup(BasisGroup * Copy)1441 BasisGroup::BasisGroup(BasisGroup *Copy) {
1442 	if (Copy) {
1443 		*this = *Copy;
1444 	}
1445 }
InitData(void)1446 void BasisGroup::InitData(void) {
1447 	Split2[0]=Split2[1]=0.0f;
1448 	Split3[0]=Split3[1]=Split3[2]=0.0f;
1449 	Basis=NumGauss=NumHeavyFuncs=NumPFuncs=ECPPotential=0;
1450 	Polar = GAMESS_BS_No_Polarization;
1451 	Flags = 0;
1452 }
GAMESSBasisSetToText(GAMESS_BasisSet bs)1453 const char * BasisGroup::GAMESSBasisSetToText(GAMESS_BasisSet bs) {
1454 	switch (bs) {
1455 		case GAMESS_BS_None:
1456 			break; //Let this one fall through and return invalid
1457 		case GAMESS_BS_MINI:
1458 			return "MINI";
1459 		case GAMESS_BS_MIDI:
1460 			return "MIDI";
1461 		case GAMESS_BS_STO:
1462 			return "STO";
1463 		case GAMESS_BS_N21:
1464 			return "N21";
1465 		case GAMESS_BS_N31:
1466 			return "N31";
1467 		case GAMESS_BS_N311:
1468 			return "N311";
1469 		case GAMESS_BS_DZV:
1470 			return "DZV";
1471 		case GAMESS_BS_DH:
1472 			return "DH";
1473 		case GAMESS_BS_BC:
1474 			return "BC";
1475 		case GAMESS_BS_TZV:
1476 			return "TZV";
1477 		case GAMESS_BS_MC:
1478 			return "MC";
1479 		case GAMESS_BS_CC_PVDZ:
1480 			return "CCD";
1481 		case GAMESS_BS_CC_PVTZ:
1482 			return "CCT";
1483 		case GAMESS_BS_CC_PVQZ:
1484 			return "CCQ";
1485 		case GAMESS_BS_CC_PV5Z:
1486 			return "CC5";
1487 		case GAMESS_BS_CC_PV6Z:
1488 			return "CC6";
1489 		case GAMESS_BS_AUG_CC_PVDZ:
1490 			return "ACCD";
1491 		case GAMESS_BS_AUG_CC_PVTZ:
1492 			return "ACCT";
1493 		case GAMESS_BS_AUG_CC_PVQZ:
1494 			return "ACCQ";
1495 		case GAMESS_BS_AUG_CC_PV5Z:
1496 			return "ACC5";
1497 		case GAMESS_BS_AUG_CC_PV6Z:
1498 			return "ACC6";
1499 		case GAMESS_BS_CC_PCVDZ:
1500 			return "CCDC";
1501 		case GAMESS_BS_CC_PCVTZ:
1502 			return "CCTC";
1503 		case GAMESS_BS_CC_PCVQZ:
1504 			return "CCQC";
1505 		case GAMESS_BS_CC_PCV5Z:
1506 			return "CC5C";
1507 		case GAMESS_BS_CC_PCV6Z:
1508 			return "CC6C";
1509 		case GAMESS_BS_AUG_CC_PCVDZ:
1510 			return "ACCDC";
1511 		case GAMESS_BS_AUG_CC_PCVTZ:
1512 			return "ACCTC";
1513 		case GAMESS_BS_AUG_CC_PCVQZ:
1514 			return "ACCQC";
1515 		case GAMESS_BS_AUG_CC_PCV5Z:
1516 			return "ACC5C";
1517 		case GAMESS_BS_AUG_CC_PCV6Z:
1518 			return "ACC6C";
1519 		case GAMESS_BS_PC0:
1520 			return "PC0";
1521 		case GAMESS_BS_PC1:
1522 			return "PC1";
1523 		case GAMESS_BS_PC2:
1524 			return "PC2";
1525 		case GAMESS_BS_PC3:
1526 			return "PC3";
1527 		case GAMESS_BS_PC4:
1528 			return "PC4";
1529 		case GAMESS_BS_APC0:
1530 			return "APC0";
1531 		case GAMESS_BS_APC1:
1532 			return "APC1";
1533 		case GAMESS_BS_APC2:
1534 			return "APC2";
1535 		case GAMESS_BS_APC3:
1536 			return "APC3";
1537 		case GAMESS_BS_APC4:
1538 			return "APC4";
1539 		case GAMESS_BW_SPK_DZP:
1540 			return "SPK-DZP";
1541 		case GAMESS_BW_SPK_TZP:
1542 			return "SPK-TZP";
1543 		case GAMESS_BW_SPK_QZP:
1544 			return "SPK-QZP";
1545 		case GAMESS_BW_SPK_ADZP:
1546 			return "SPK-ADZP";
1547 		case GAMESS_BW_SPK_ATZP:
1548 			return "SPK-ATZP";
1549 		case GAMESS_BW_SPK_AQZP:
1550 			return "SPK-AQZP";
1551 		case GAMESS_BW_SPKRDZP:
1552 			return "SPKRDZP";
1553 		case GAMESS_BW_SPKRTZP:
1554 			return "SPKRTZP";
1555 		case GAMESS_BW_SPKRQZP:
1556 			return "SPKRQZP";
1557 		case GAMESS_BW_SPKRADZP:
1558 			return "SPKRADZP";
1559 		case GAMESS_BW_SPKRATZP:
1560 			return "SPKRATZP";
1561 		case GAMESS_BW_SPKRAQZP:
1562 			return "SPKRAQZP";
1563 		case GAMESS_BW_KTZV:
1564 			return "KTZV";
1565 		case GAMESS_BW_KTZVP:
1566 			return "KTZVP";
1567 		case GAMESS_BW_KTZVPP:
1568 			return "KTZVPP";
1569 
1570 		case GAMESS_BS_SBKJC:
1571 			return "SBKJC";
1572 		case GAMESS_BS_HW:
1573 			return "HW";
1574 		case GAMESS_BS_MCP_DZP:
1575 			return "MCP-DZP";
1576 		case GAMESS_BS_MCP_TZP:
1577 			return "MCP-TZP";
1578 		case GAMESS_BS_MCP_QZP:
1579 			return "MCP-QZP";
1580 		case GAMESS_BS_MCP_ATZP:
1581 			return "MCP-ATZP";
1582 		case GAMESS_BS_MCP_AQZP:
1583 			return "MCP-AQZP";
1584 		case GAMESS_BS_MCPCDZP:
1585 			return "MCPCDZP";
1586 		case GAMESS_BS_MCPCTZP:
1587 			return "MCPCTZP";
1588 		case GAMESS_BS_MCPCQZP:
1589 			return "MCPCQZP";
1590 		case GAMESS_BS_MCPACDZP:
1591 			return "MCPACDZP";
1592 		case GAMESS_BS_MCPACTZP:
1593 			return "MCPACTZP";
1594 		case GAMESS_BS_MCPACQZP:
1595 			return "MCPACQZP";
1596 		case GAMESS_BS_IMCP_SR1:
1597 			return "IMCP-SR1";
1598 		case GAMESS_BS_IMCP_SR2:
1599 			return "IMCP-SR2";
1600 		case GAMESS_BS_IMCP_NR1:
1601 			return "IMCP-NR1";
1602 		case GAMESS_BS_IMCP_NR2:
1603 			return "IMCP-NR2";
1604 		case GAMESS_BS_ZFK3_DK3:
1605 			return "ZFK3-DK3";
1606 		case GAMESS_BS_ZFK4_DK3:
1607 			return "ZFK4-DK3";
1608 		case GAMESS_BS_ZFK5_DK3:
1609 			return "ZFK5-DK3";
1610 		case GAMESS_BS_ZFK3LDK3:
1611 			return "ZFK3LDK3";
1612 		case GAMESS_BS_ZFK4LDK3:
1613 			return "ZFK4LDK3";
1614 		case GAMESS_BS_ZFK5LDK3:
1615 			return "ZFK5LDK3";
1616 
1617 		case GAMESS_BS_MNDO:
1618 			return "MNDO";
1619 		case GAMESS_BS_AM1:
1620 			return "AM1";
1621 		case GAMESS_BS_PM3:
1622 			return "PM3";
1623 		case GAMESS_BS_RM1:
1624 			return "RM1";
1625 		default:
1626 			wxLogMessage(_T("Unknown basis set encountered in GAMESSBasisSetToText"));
1627 	}
1628 	return "invalid";
1629 }
SetBasis(const char * BasisText)1630 short BasisGroup::SetBasis(const char *BasisText) {
1631 	short NewBasis = -1;
1632 
1633 	for (int i=GAMESS_BS_None; i<NumGAMESSBasisSetsItem; i++) {
1634 		if (!strcasecmp(BasisText, GAMESSBasisSetToText((GAMESS_BasisSet)i))) {
1635 			NewBasis = i;
1636 			break;
1637 		}
1638 	}
1639 	if (NewBasis<0) return -1;
1640 
1641 	Basis = NewBasis;
1642 	return Basis;
1643 }
SetBasis(short NewBasis)1644 short BasisGroup::SetBasis(short NewBasis) {
1645 	if ((NewBasis<-1)||(NewBasis>NumGAMESSBasisSetsItem)) return -1;
1646 
1647 	Basis = NewBasis;
1648 	return Basis;
1649 }
GetBasisText(void) const1650 const char * BasisGroup::GetBasisText(void) const {
1651 	short temp = Basis;
1652 	if (temp <= 0) temp = 1;
1653 
1654 	return GAMESSBasisSetToText((GAMESS_BasisSet) temp);
1655 }
GetBasis(void) const1656 short BasisGroup::GetBasis(void) const {
1657 	return Basis;
1658 }
SetNumGauss(short NewNumGauss)1659 short BasisGroup::SetNumGauss(short NewNumGauss) {
1660 	if ((NewNumGauss<0)||(NewNumGauss>6)) return -1;
1661 	if ((Basis==4)&&(NewNumGauss!=3)&&(NewNumGauss!=6)) return -1;
1662 	if ((Basis==5)&&(NewNumGauss<4)) return -1;
1663 	if ((Basis==6)&&(NewNumGauss!=6)) return -1;
1664 
1665 	NumGauss = NewNumGauss;
1666 	return NumGauss;
1667 }
GetNumGauss(void) const1668 short BasisGroup::GetNumGauss(void) const {
1669 	return NumGauss;
1670 }
SetNumDFuncs(short NewNum)1671 short BasisGroup::SetNumDFuncs(short NewNum) {
1672 	if (NewNum > 3) return -1;
1673 
1674 	NumHeavyFuncs = NewNum + (NumHeavyFuncs & 0xF0);
1675 	return (NumHeavyFuncs & 0x0F);
1676 }
GetNumDFuncs(void) const1677 short BasisGroup::GetNumDFuncs(void) const {
1678 	return (NumHeavyFuncs & 0x0F);
1679 }
SetNumFFuncs(short NewNum)1680 short BasisGroup::SetNumFFuncs(short NewNum) {
1681 	if (NewNum > 3) return -1;
1682 
1683 	NumHeavyFuncs = (NewNum<<4) + (NumHeavyFuncs & 0x0F);
1684 	return ((NumHeavyFuncs & 0xF0)>>4);
1685 }
GetNumFFuncs(void) const1686 short BasisGroup::GetNumFFuncs(void) const {
1687 	return ((NumHeavyFuncs & 0xF0)>>4);
1688 }
SetNumPFuncs(short NewNum)1689 short BasisGroup::SetNumPFuncs(short NewNum) {
1690 	if (NewNum > 3) return -1;
1691 
1692 	NumPFuncs = NewNum;
1693 	return NumPFuncs;
1694 }
GetNumPFuncs(void) const1695 short BasisGroup::GetNumPFuncs(void) const {
1696 	return NumPFuncs;
1697 }
SetDiffuseSP(bool state)1698 short BasisGroup::SetDiffuseSP(bool state) {
1699 	if (state && (!(Flags & 1))) Flags += 1;
1700 	else if (!state && (Flags & 1)) Flags -= 1;
1701 
1702 	return state;
1703 }
SetDiffuseS(bool state)1704 short BasisGroup::SetDiffuseS(bool state) {
1705 	if (state && (!(Flags & 2))) Flags += 2;
1706 	else if (!state && (Flags & 2)) Flags -= 2;
1707 
1708 	return state;
1709 }
SetPolar(GAMESS_BS_Polarization NewPolar)1710 GAMESS_BS_Polarization BasisGroup::SetPolar(GAMESS_BS_Polarization NewPolar) {
1711 	if ((NewPolar>=GAMESS_BS_No_Polarization)||(NewPolar<NumGAMESSBSPolarItems)) {
1712 		Polar = NewPolar;
1713 	}
1714 	return Polar;
1715 }
SetPolar(const char * PolarText)1716 GAMESS_BS_Polarization BasisGroup::SetPolar(const char *PolarText) {
1717 	GAMESS_BS_Polarization NewPolar = GAMESS_BS_Invalid_Polar;
1718 
1719 	for (int i=GAMESS_BS_No_Polarization; i<NumGAMESSBSPolarItems; i++) {
1720 		if (!strcasecmp(PolarText, PolarToText((GAMESS_BS_Polarization)i))) {
1721 			NewPolar = (GAMESS_BS_Polarization) i;
1722 			break;
1723 		}
1724 	}
1725 	if (NewPolar == GAMESS_BS_Invalid_Polar) {	//test against the old POPLE flag
1726 		if (!strcasecmp(PolarText, PolarToText(GAMESS_BS_Pople_Polar))) {
1727 			NewPolar = GAMESS_BS_Common_Polar;
1728 		}
1729 	}
1730 	if (NewPolar>=0) Polar = NewPolar;
1731 	return NewPolar;
1732 }
PolarToText(GAMESS_BS_Polarization p)1733 const char * BasisGroup::PolarToText(GAMESS_BS_Polarization p) {
1734 	switch (p) {
1735 		case GAMESS_BS_Pople_Polar:	//this is retained to read old output
1736 			return "POPLE";
1737 		case GAMESS_BS_No_Polarization:
1738 			return "none";
1739 		case GAMESS_BS_Common_Polar:
1740 			return "COMMON";
1741 		case GAMESS_BS_PopN31_Polar:
1742 			return "POPN31";
1743 		case GAMESS_BS_PopN311_Polar:
1744 			return "POPN311";
1745 		case GAMESS_BS_Dunning_Polar:
1746 			return "DUNNING";
1747 		case GAMESS_BS_Huzinaga_Polar:
1748 			return "HUZINAGA";
1749 		case GAMESS_BS_Hondo7_Polar:
1750 			return "HONDO7";
1751 		default:
1752 			wxLogMessage(_T("Unknown Polarization option in PolarToText"));
1753 	}
1754 	return "invalid";
1755 }
GAMESSECPToText(GAMESS_BS_ECPotential p)1756 const char * BasisGroup::GAMESSECPToText(GAMESS_BS_ECPotential p) {
1757 	switch (p) {
1758 		case GAMESS_BS_ECP_None:
1759 			return "NONE";
1760 		case GAMESS_BS_ECP_Read:
1761 			return "READ";
1762 		case GAMESS_BS_ECP_SBKJC:
1763 			return "SBKJC";
1764 		case GAMESS_BS_ECP_HW:
1765 			return "HW";
1766 		case GAMESS_BS_ECP_MCP:
1767 			return "MCP";
1768 		default:
1769 			wxLogMessage(_T("Unknown ECP type in GAMESSECPToText"));
1770 	}
1771 	return "invalid";
1772 }
SetECPPotential(const char * ECPText)1773 GAMESS_BS_ECPotential BasisGroup::SetECPPotential(const char *ECPText) {
1774 	GAMESS_BS_ECPotential NewPot = GAMESS_BS_Invalid_ECP;
1775 
1776 	for (int i=GAMESS_BS_ECP_None; i<NumGAMESSBSECPItems; i++) {
1777 		if (!strcasecmp(ECPText, GAMESSECPToText((GAMESS_BS_ECPotential)i))) {
1778 			NewPot = (GAMESS_BS_ECPotential) i;
1779 			break;
1780 		}
1781 	}
1782 	if (NewPot == GAMESS_BS_Invalid_ECP) {	//test against the old spelling of sbkjc
1783 		if (!strcasecmp(ECPText, "SBK")) {
1784 			NewPot = GAMESS_BS_ECP_SBKJC;
1785 		}
1786 	}
1787 	if (NewPot>=0) ECPPotential = NewPot;
1788 	return NewPot;
1789 }
GetECPPotential(void) const1790 short BasisGroup::GetECPPotential(void) const {
1791 	short value = ECPPotential;
1792 	if (value <= GAMESS_BS_ECP_None) {
1793 		if (Basis == GAMESS_BS_SBKJC) value = GAMESS_BS_ECP_SBKJC;
1794 		if (Basis == GAMESS_BS_HW) value = GAMESS_BS_ECP_HW;
1795 		if ((Basis >= GAMESS_BS_MCP_DZP)&&(Basis <= GAMESS_BS_IMCP_NR2))
1796 			value = GAMESS_BS_ECP_MCP;
1797 	}
1798 	return value;
1799 }
GetECPPotentialText(void) const1800 const char * BasisGroup::GetECPPotentialText(void) const {
1801 	return GAMESSECPToText((GAMESS_BS_ECPotential) GetECPPotential());
1802 }
SetECPPotential(short NewType)1803 short BasisGroup::SetECPPotential(short NewType) {
1804 	if ((NewType<GAMESS_BS_ECP_None)||(NewType>NumGAMESSBSECPItems)) return -1;
1805 	ECPPotential = NewType;
1806 	return ECPPotential;
1807 }
WriteXML(XMLElement * parent) const1808 void BasisGroup::WriteXML(XMLElement * parent) const {
1809 	char line[kMaxLineLength];
1810 	XMLElement * Ele = parent->addChildElement(CML_convert(MMP_IOBasisGroupElement));
1811 	if (GetBasis() != 0) {
1812 		Ele->addChildElement(CML_convert(MMP_IOBGBasisSet), GetBasisText());
1813 	}
1814 	if (NumGauss) {
1815 		snprintf(line, kMaxLineLength, "%d", NumGauss);
1816 		Ele->addChildElement(CML_convert(MMP_IOBGNumGauss), line);
1817 	}
1818 	if (GetNumDFuncs()) {
1819 		snprintf(line, kMaxLineLength, "%d", GetNumDFuncs());
1820 		Ele->addChildElement(CML_convert(MMP_IOBGNumDFuncs), line);
1821 	}
1822 	if (GetNumFFuncs()) {
1823 		snprintf(line, kMaxLineLength, "%d", GetNumFFuncs());
1824 		Ele->addChildElement(CML_convert(MMP_IOBGNumFFuncs), line);
1825 	}
1826 	if (GetNumPFuncs()) {
1827 		snprintf(line, kMaxLineLength, "%d", GetNumPFuncs());
1828 		Ele->addChildElement(CML_convert(MMP_IOBGNumPFuncs), line);
1829 	}
1830 	if (GetPolar() != 0) {
1831 		Ele->addChildElement(CML_convert(MMP_IOBGPolar), GetPolarText());
1832 	}
1833 	if (GetECPPotential() != 0) {
1834 		Ele->addChildElement(CML_convert(MMP_IOBGECPPotential), GetECPPotentialText());
1835 	}
1836 	if (GetDiffuseSP()) Ele->addChildElement(CML_convert(MMP_IOBGDiffuseSP), trueXML);
1837 	if (GetDiffuseS()) Ele->addChildElement(CML_convert(MMP_IOBGDiffuseS), trueXML);
1838 	if (CheckBasis()) Ele->addChildElement(CML_convert(MMP_IOBGDisableBS), trueXML);
1839 }
ReadXML(XMLElement * parent)1840 void BasisGroup::ReadXML(XMLElement * parent) {
1841 	XMLElementList * children = parent->getChildren();
1842 	if (children) {
1843 		for (int i=0; i<children->length(); i++) {
1844 			XMLElement * child = children->item(i);
1845 			MMP_IOBasisGroupNS item;
1846 			if (child && CML_convert(child->getName(), item)) {
1847 				bool tb;
1848 				switch (item) {
1849 					case MMP_IOBGBasisSet:
1850 					{
1851 						const char * v = child->getValue();
1852 						if (v) SetBasis(v);
1853 					}
1854 						break;
1855 					case MMP_IOBGNumGauss:
1856 					{
1857 						long temp;
1858 						if (child->getLongValue(temp)) SetNumGauss(temp);
1859 					}
1860 						break;
1861 					case MMP_IOBGNumDFuncs:
1862 					{
1863 						long temp;
1864 						if (child->getLongValue(temp)) SetNumDFuncs(temp);
1865 					}
1866 						break;
1867 					case MMP_IOBGNumFFuncs:
1868 					{
1869 						long temp;
1870 						if (child->getLongValue(temp)) SetNumFFuncs(temp);
1871 					}
1872 						break;
1873 					case MMP_IOBGNumPFuncs:
1874 					{
1875 						long temp;
1876 						if (child->getLongValue(temp)) SetNumPFuncs(temp);
1877 					}
1878 						break;
1879 					case MMP_IOBGPolar:
1880 					{
1881 						const char * v = child->getValue();
1882 						if (v) SetPolar(v);
1883 					}
1884 						break;
1885 					case MMP_IOBGECPPotential:
1886 					{
1887 						const char * v = child->getValue();
1888 						if (v) SetECPPotential(v);
1889 					}
1890 						break;
1891 					case MMP_IOBGDiffuseSP:
1892 						if (child->getBoolValue(tb))
1893 							SetDiffuseSP(tb);
1894 						break;
1895 					case MMP_IOBGDiffuseS:
1896 						if (child->getBoolValue(tb))
1897 							SetDiffuseS(tb);
1898 						break;
1899 					case MMP_IOBGDisableBS:
1900 						if (child->getBoolValue(tb))
1901 							CheckBasis(tb);
1902 						break;
1903 					default:
1904 					{
1905 						wxString msg;
1906 						msg.Printf(_T("Unknown Basis group CML element: %s"), child->getName());
1907 						wxLogMessage(msg);
1908 					}
1909 				}
1910 			}
1911 		}
1912 		delete children;
1913 	}
1914 }
WriteToFile(BufferFile * File,MoleculeData * lData)1915 long BasisGroup::WriteToFile(BufferFile *File, MoleculeData * lData) {
1916 	char	Out[133];
1917 		//if a general basis set is present don't punch the $Basis group
1918 	if (lData->GetBasisSet() && (GetBasis() == 0)) return 1;
1919 		//Punch the group label
1920 	File->WriteLine(" $BASIS ", false);
1921 		//Basis Set
1922 	sprintf(Out,"GBASIS=%s ", GetBasisText());
1923 	File->WriteLine(Out, false);
1924 		//Number of Gaussians
1925 	if (NumGauss) {
1926 		sprintf(Out, "NGAUSS=%d ", NumGauss);
1927 		File->WriteLine(Out, false);
1928 	}	//number of heavy atom polarization functions
1929 	if (GetNumDFuncs()) {
1930 		sprintf(Out, "NDFUNC=%d ", GetNumDFuncs());
1931 		File->WriteLine(Out, false);
1932 	}	//number of heavy atom f type polarization functions
1933 	if (GetNumFFuncs()) {
1934 		sprintf(Out, "NFFUNC=%d ", GetNumFFuncs());
1935 		File->WriteLine(Out, false);
1936 	}	//number of light atom polarization functions
1937 	if (NumPFuncs) {
1938 		sprintf(Out, "NPFUNC=%d ", NumPFuncs);
1939 		File->WriteLine(Out, false);
1940 	}	//type of Polarization functions
1941 	if ((Polar)&&((NumHeavyFuncs)||(NumPFuncs))) {
1942 		sprintf(Out, "POLAR=%s ", GetPolarText());
1943 		File->WriteLine(Out, false);
1944 	}
1945 	if (GetDiffuseSP()) {
1946 		sprintf(Out, "DIFFSP=.TRUE. ");
1947 		File->WriteLine(Out, false);
1948 	}
1949 	if (GetDiffuseS()) {
1950 		sprintf(Out, "DIFFS=.TRUE. ");
1951 		File->WriteLine(Out, false);
1952 	}
1953 	File->WriteLine("$END", true);
1954 	return 0;
1955 }
1956 #pragma mark DataGroup
1957 		// Data Group member functions
DataGroup(void)1958 DataGroup::DataGroup(void) {
1959 	InitData();
1960 }
DataGroup(DataGroup * Copy)1961 DataGroup::DataGroup(DataGroup *Copy) {
1962 	if (Copy) {
1963 		*this = *Copy;
1964 		Title = NULL;
1965 		if (Copy->Title) {
1966 			Title = new char[1+strlen(Copy->Title)];
1967 			if (Title) strcpy(Title, Copy->Title);
1968 		}
1969 	}
1970 }
~DataGroup(void)1971 DataGroup::~DataGroup(void) {
1972 	if (Title) delete [] Title;
1973 }
InitData(void)1974 void DataGroup::InitData(void) {
1975 	Title = 0;
1976 	Coord = NumZVar = 0;
1977 	PointGroup = 1;
1978 	PGroupOrder = Options = 0;
1979 	SetUseSym(true);
1980 }
SetPointGroup(GAMESSPointGroup NewPGroup)1981 short DataGroup::SetPointGroup(GAMESSPointGroup NewPGroup) {
1982 	if ((NewPGroup<invalidPGroup)||(NewPGroup>NumberGAMESSPointGroups)) return -1;
1983 
1984 	PointGroup = NewPGroup;
1985 	return PointGroup;
1986 }
GetGAMESSPointGroupText(GAMESSPointGroup p)1987 const char * DataGroup::GetGAMESSPointGroupText(GAMESSPointGroup p) {
1988 	switch (p) {
1989 		case GAMESS_C1:
1990 			return "C1";
1991 		case GAMESS_CS:
1992 			return "CS";
1993 		case GAMESS_CI:
1994 			return "CI";
1995 		case GAMESS_CNH:
1996 			return "CNH";
1997 		case GAMESS_CNV:
1998 			return "CNV";
1999 		case GAMESS_CN:
2000 			return "CN";
2001 		case GAMESS_S2N:
2002 			return "S2N";
2003 		case GAMESS_DND:
2004 			return "DND";
2005 		case GAMESS_DNH:
2006 			return "DNH";
2007 		case GAMESS_DN:
2008 			return "DN";
2009 		case GAMESS_TD:
2010 			return "TD";
2011 		case GAMESS_TH:
2012 			return "TH";
2013 		case GAMESS_T:
2014 			return "T";
2015 		case GAMESS_OH:
2016 			return "OH";
2017 		case GAMESS_O:
2018 			return "O";
2019 		default:
2020 			wxLogMessage(_T("Unknown point group in GetGAMESSPointGroupText"));
2021 	}
2022 	return "invalid";
2023 }
SetPointGroup(char * GroupText)2024 short DataGroup::SetPointGroup(char *GroupText) {
2025 	GAMESSPointGroup NewPGroup=invalidPGroup;
2026 
2027 	for (int i=0; i<5; i++) {
2028 		if (!GroupText[i]) break;
2029 		if ((GroupText[i]>96)&&(GroupText[i]<123)) GroupText[i] = GroupText[i] - 32;
2030 	}
2031 	if (std::toupper(GroupText[0]) == 'S') {
2032 		PGroupOrder = GroupText[2] - 48;
2033 		GroupText[2]='N';
2034 	} else {
2035 		int i=0;
2036 		while (GroupText[i]&&(GroupText[i]!=' ')) {
2037 			if (isdigit(GroupText[i])&&(GroupText[i]!='1')) {
2038 				PGroupOrder = GroupText[i] - 48;	//single digit coverted to decimal digit
2039 				GroupText[i]='N';
2040 			}
2041 			i++;
2042 		}
2043 	}
2044 
2045 	for (int i=1; i<NumberGAMESSPointGroups; i++) {
2046 		if (strcasecmp(GroupText, GetGAMESSPointGroupText((GAMESSPointGroup) i))==0) {
2047 			NewPGroup = (GAMESSPointGroup) i;
2048 			break;
2049 		}
2050 	}
2051 	if (NewPGroup<=invalidPGroup) return invalidPGroup;
2052 
2053 	if (NewPGroup<0) return -1;
2054 
2055 	PointGroup = NewPGroup;
2056 	return PointGroup;
2057 }
SetPointGroupOrder(short NewOrder)2058 short DataGroup::SetPointGroupOrder(short NewOrder) {
2059 	if (NewOrder > 0) PGroupOrder = NewOrder;
2060 	return PGroupOrder;
2061 }
SetTitle(const char * NewTitle,long length)2062 short DataGroup::SetTitle(const char *NewTitle, long length) {
2063 	if (Title) delete[] Title;
2064 	Title = NULL;
2065 
2066 	if (length == -1) length = strlen(NewTitle);
2067 
2068 		long TitleStart=0, TitleEnd=length-1, i, j;
2069 		//Strip blanks of both ends of title
2070 	while ((NewTitle[TitleStart] <= ' ')&&(TitleStart<length)) TitleStart ++;
2071 	while ((NewTitle[TitleEnd] <= ' ')&&(TitleEnd>0)) TitleEnd --;
2072 	length = TitleEnd - TitleStart + 1;
2073 
2074 	if (length <= 0) return 0;
2075 	if (length > 132) return -1;	//Title card is limited to one line
2076 
2077 	Title = new char[length + 1];
2078 	if (Title == NULL) throw MemoryError();
2079 	j=0;
2080 	for (i=TitleStart; i<=TitleEnd; i++) {
2081 		if ((NewTitle[i] == '\n')||(NewTitle[i] == '\r')) {
2082 			Title[j] = 0;
2083 			break;
2084 		}
2085 		Title[j] = NewTitle[i];
2086 		j++;
2087 	}
2088 	Title[j]=0;
2089 	return j;
2090 }
GetTitle(void) const2091 const char * DataGroup::GetTitle(void) const {
2092 	return Title;
2093 }
GetCoordType(void) const2094 CoordinateType DataGroup::GetCoordType(void) const {
2095 	return (CoordinateType) Coord;
2096 }
GetCoordTypeText(CoordinateType t)2097 const char * DataGroup::GetCoordTypeText(CoordinateType t) {
2098 	switch (t) {
2099 		case UniqueCoordType:
2100 			return "UNIQUE";
2101 		case HINTCoordType:
2102 			return "HINT";
2103 		case CartesianCoordType:
2104 			return "CART";
2105 		case ZMTCoordType:
2106 			return "ZMT";
2107 		case ZMTMPCCoordType:
2108 			return "ZMTMPC";
2109 		default:
2110 			wxLogMessage(_T("Unknown coord type in GetCoordTypeText"));
2111 	}
2112 	return "invalid";
2113 }
SetCoordType(const char * CoordText)2114 CoordinateType DataGroup::SetCoordType(const char * CoordText) {
2115 	CoordinateType NewCoord = invalidCoordinateType;
2116 	for (int i=1; i<NumberCoordinateTypes; i++) {
2117 		if (strcasecmp(CoordText, GetCoordTypeText((CoordinateType) i))==0) {
2118 			NewCoord = (CoordinateType) i;
2119 			break;
2120 		}
2121 	}
2122 	if (NewCoord<=invalidCoordinateType) return invalidCoordinateType;
2123 	Coord = NewCoord;
2124 	return (CoordinateType) Coord;
2125 }
SetCoordType(CoordinateType NewType)2126 CoordinateType DataGroup::SetCoordType(CoordinateType NewType) {
2127 	if ((NewType<UniqueCoordType)&&(NewType>NumberCoordinateTypes)) return invalidCoordinateType;
2128 	Coord = NewType;
2129 	return (CoordinateType) Coord;
2130 }
SetUnits(bool NewType)2131 bool DataGroup::SetUnits(bool NewType) {
2132 	if (Options & 1) Options -= 1;
2133 	if (NewType) Options += 1;
2134 	return GetUnits();
2135 }
SetUnits(const char * u)2136 int DataGroup::SetUnits(const char * u) {
2137 	int rval = -1;
2138 	if (!strcasecmp(u, "ANGS")) {
2139 		SetUnits(false);
2140 		rval = 0;
2141 	} else if (!strcasecmp(u, "BOHR")) {
2142 		SetUnits(true);
2143 		rval = 1;
2144 	}
2145 	return rval;
2146 }
SetUseSym(bool State)2147 bool DataGroup::SetUseSym(bool State) {
2148 	if (Options & (1<<1)) Options -= (1<<1);
2149 	if (State) Options += (1<<1);
2150 	return GetUseSym();
2151 }
SetNumZVar(short NewNum)2152 short DataGroup::SetNumZVar(short NewNum) {
2153 	if (NewNum<0) return -1;	//bad number
2154 	NumZVar = NewNum;
2155 	return NumZVar;
2156 }
WriteToFile(BufferFile * File,MoleculeData * MainData,WinPrefs * Prefs,long BasisTest)2157 void DataGroup::WriteToFile(BufferFile *File, MoleculeData * MainData, WinPrefs * Prefs, long BasisTest) {
2158 	char	Out[133];
2159 
2160 	Frame * cFrame = MainData->GetCurrentFramePtr();
2161 	BasisSet * lBasis = MainData->GetBasisSet();
2162 	BasisTest = BasisTest && lBasis;	//Make sure there really is a basis set defined
2163 	float unitConversion = 1.0f;
2164 	if (MainData->InputOptions->Data->GetUnits()) unitConversion = kAng2BohrConversion;
2165 		//Punch the group label
2166 	//Check the number of ab initio atoms. If zero and we have effective fragments force
2167 	//Coord = fragonly
2168 	long abInitioCount=0, fragAtomCount=0;
2169 	for (long iatom=0; iatom<cFrame->NumAtoms; iatom++) {
2170 		if (cFrame->Atoms[iatom].IsEffectiveFragment()) fragAtomCount++;
2171 		else abInitioCount++;
2172 	}
2173 	if ((abInitioCount==0)&&(fragAtomCount>0))
2174 		File->WriteLine(" $CONTRL COORD=FRAGONLY $END", true);
2175 	File->WriteLine(" $DATA ", true);
2176 		//title
2177 	if (Title == NULL) File->WriteLine("Title goes here", true);
2178 	else File->WriteLine(Title, true);
2179 		//Point Group
2180 	if (((int) PointGroup > GAMESS_CI) && ((int) PointGroup < GAMESS_TD)) {
2181 		sprintf(Out, "%s %d", GetPointGroupText(), PGroupOrder);
2182 	} else sprintf(Out, "%s", GetPointGroupText());
2183 	File->WriteLine(Out, true);
2184 	if ((PointGroup!=0)&&(PointGroup!=1)) File->WriteLine("", true);
2185 	if (! MainData->InputOptions->FMO.IsFMOActive()) {
2186 			//coordinates
2187 		if (Coord == ZMTCoordType) {	//"normal" style z-matrix
2188 			Internals * IntCoords = MainData->GetInternalCoordinates();
2189 			if (!IntCoords) {
2190 				MainData->InitializeInternals();
2191 				IntCoords = MainData->GetInternalCoordinates();
2192 			}
2193 			if (IntCoords) IntCoords->WriteCoordinatesToFile(File, MainData, Prefs);
2194 		} else if (Coord == ZMTMPCCoordType) {
2195 			Internals * IntCoords = MainData->GetInternalCoordinates();
2196 			if (!IntCoords) {
2197 				MainData->InitializeInternals();
2198 				IntCoords = MainData->GetInternalCoordinates();
2199 			}
2200 			if (IntCoords) IntCoords->WriteMPCZMatCoordinatesToFile(File, MainData, Prefs);
2201 		} else {
2202 			if (Coord <= UniqueCoordType) MainData->GenerateSymmetryUniqueAtoms(1.0E-3);
2203 			for (int iatom=0; iatom<cFrame->NumAtoms; iatom++) {
2204 				if (!cFrame->Atoms[iatom].IsEffectiveFragment()) {
2205 					if ((Coord > UniqueCoordType)||(cFrame->Atoms[iatom].IsSymmetryUnique())) {
2206 						Str255 AtomLabel;
2207 						Prefs->GetAtomLabel(cFrame->Atoms[iatom].GetType()-1, AtomLabel);
2208 						AtomLabel[AtomLabel[0]+1] = 0;
2209 						sprintf(Out, "%s   %5.1f  %10.5f  %10.5f  %10.5f",
2210 							(char *) &(AtomLabel[1]), (float) (cFrame->Atoms[iatom].GetType()),
2211 							cFrame->Atoms[iatom].Position.x*unitConversion,
2212 							cFrame->Atoms[iatom].Position.y*unitConversion,
2213 							cFrame->Atoms[iatom].Position.z*unitConversion);
2214 						File->WriteLine(Out, true);
2215 						if (BasisTest) lBasis->WriteBasis(File, iatom);
2216 					}
2217 				}
2218 			}
2219 		}
2220 	} else {
2221 		//For FMO runs instead of the coordinates emit one line per atom type
2222 		//First determine the list of unique atom types
2223 		std::vector<int>	atomTypes;
2224 		for (long i=0; i<cFrame->NumAtoms; i++) {
2225 			bool unique=true;
2226 			int atomT = cFrame->Atoms[i].GetType();
2227 			for (int j=0; j<atomTypes.size(); j++) {
2228 				if (atomTypes[j] == atomT) {
2229 					unique = false;
2230 					break;
2231 				}
2232 			}
2233 			if (unique) atomTypes.push_back(atomT);
2234 		}
2235 		for (int i=0; i<atomTypes.size(); i++) {
2236 			Str255 AtomLabel;
2237 			Prefs->GetAtomLabel(atomTypes[i]-1, AtomLabel);
2238 			AtomLabel[AtomLabel[0]+1] = 0;
2239 			// the position is unnescessary, these are here to generate the basis set only.
2240 			sprintf(Out, "%s   %d", (char *) &(AtomLabel[1]), atomTypes[i]);
2241 			File->WriteLine(Out, true);
2242 		}
2243 	}
2244 
2245 	File->WriteLine(" $END", true);
2246 	if (NumZVar) {	//punch out the current connectivity in a $ZMAT group
2247 		Internals * IntCoords = MainData->GetInternalCoordinates();
2248 		if (IntCoords) IntCoords->WriteZMATToFile(File);
2249 	}
2250 	if (fragAtomCount > 0) {	//Now add on any effective fragments
2251 		File->WriteLine(" $EFRAG ", true);
2252 		File->WriteLine("COORD=CART", true);
2253 
2254 		long last_frag = 0;
2255 		long curr_frag;
2256 		long atomsWritten=0, HydrogenIndex;
2257 		const char *frag_name;
2258 		for (int iatom=0; iatom<cFrame->NumAtoms; iatom++) {
2259 			if (cFrame->Atoms[iatom].IsEffectiveFragment()) {
2260 				curr_frag = cFrame->Atoms[iatom].GetFragmentNumber();
2261 				frag_name = MainData->GetFragmentName(curr_frag - 1);
2262 				if (curr_frag != last_frag) {
2263 					//start of a new fragment, punch FRAGNAME
2264 					last_frag = curr_frag;
2265 					File->WriteLine("FRAGNAME=", false);
2266 					File->WriteLine(frag_name, true);
2267 					atomsWritten=0;
2268 					HydrogenIndex=2;
2269 				}
2270 				EFrag *frag = NULL;
2271 				if (strcmp(frag_name, "H2ORHF") != 0 &&
2272 					strcmp(frag_name, "H2ODHT") != 0) {
2273 					std::map<std::string, EFrag>::iterator frag_entry;
2274 					frag_entry = MainData->efrags.find(std::string(frag_name));
2275 					if (frag_entry != MainData->efrags.end()) {
2276 						frag = &(frag_entry->second);
2277 					}
2278 				}
2279 				if (atomsWritten < 3) {	//the EFRAG group only punchs the first three atoms
2280 					//special case the atom labels for now. Eventually I think this should
2281 					//be done via a FRAGNAME database.
2282 					if (!frag) {
2283 						if (cFrame->Atoms[iatom].GetType() == 8)
2284 							File->WriteLine("O1 ", false);
2285 						else {
2286 							sprintf(Out, "H%ld ", HydrogenIndex);
2287 							File->WriteLine(Out, false);
2288 							HydrogenIndex++;
2289 						}
2290 					} else {
2291 						File->WriteLine(frag->GetAtoms()[atomsWritten].GetLabel().c_str(), false);
2292 					}
2293 					sprintf(Out, "%10.5f  %10.5f  %10.5f",
2294 							cFrame->Atoms[iatom].Position.x, cFrame->Atoms[iatom].Position.y,
2295 							cFrame->Atoms[iatom].Position.z);
2296 					File->WriteLine(Out, true);
2297 					atomsWritten++;
2298 				}
2299 			}
2300 		}
2301 		File->WriteLine(" $END", true);
2302 
2303 		std::map<std::string, EFrag>::const_iterator frag;
2304 		for (frag = MainData->efrags.begin();
2305 			 frag != MainData->efrags.end();
2306 			 ++frag) {
2307 			const std::string& text = frag->second.GetText();
2308 			File->Write(text.c_str(), text.size());
2309 			File->WriteLine("", true);
2310 		}
2311 	}
2312 	if (MainData->InputOptions->FMO.IsFMOActive()) {
2313 		//FMO runs place all the coordinates in the FMOXYZ group
2314 		File->WriteLine(" $FMOXYZ ", true);
2315 		for (int iatom=0; iatom<cFrame->NumAtoms; iatom++) {
2316 			if (!cFrame->Atoms[iatom].IsEffectiveFragment()) {
2317 				Str255 AtomLabel;
2318 				Prefs->GetAtomLabel(cFrame->Atoms[iatom].GetType()-1, AtomLabel);
2319 				AtomLabel[AtomLabel[0]+1] = 0;
2320 				sprintf(Out, "%s   %5.1f  %10.5f  %10.5f  %10.5f",
2321 						(char *) &(AtomLabel[1]), (float) (cFrame->Atoms[iatom].GetType()),
2322 						cFrame->Atoms[iatom].Position.x*unitConversion,
2323 						cFrame->Atoms[iatom].Position.y*unitConversion,
2324 						cFrame->Atoms[iatom].Position.z*unitConversion);
2325 				File->WriteLine(Out, true);
2326 			}
2327 		}
2328 		File->WriteLine(" $END", true);
2329 	}
2330 }
WriteXML(XMLElement * parent) const2331 void DataGroup::WriteXML(XMLElement * parent) const {
2332 	char line[kMaxLineLength];
2333 	XMLElement * Ele = parent->addChildElement(CML_convert(MMP_IODataGroupElement));
2334 	if (Title) Ele->addChildElement(CML_convert(MMP_IODGTitle), Title);
2335 	if (PointGroup) {
2336 		snprintf(line, kMaxLineLength, "%d", PointGroup);
2337 		XMLElement * t = Ele->addChildElement(CML_convert(MMP_IODGPointGroup), line);
2338 		if (PGroupOrder) {
2339 			snprintf(line, kMaxLineLength, "%d", PGroupOrder);
2340 			t->addAttribute(CML_convert(MMP_IODGPointGroupOrder), line);
2341 		}
2342 	}
2343 	if (Coord) Ele->addChildElement(CML_convert(MMP_IODGCoordType), GetCoordTypeText((CoordinateType) Coord));
2344 	if (GetNumZVar()) {
2345 		snprintf(line, kMaxLineLength, "%d", GetNumZVar());
2346 		Ele->addChildElement(CML_convert(MMP_IODGNumZVars), line);
2347 	}
2348 	if (GetUnits()) Ele->addChildElement(CML_convert(MMP_IODGUnits), trueXML);
2349 	if (GetUseSym()) Ele->addChildElement(CML_convert(MMP_IODGNoSymFlag), trueXML);
2350 }
ReadXML(XMLElement * parent)2351 void DataGroup::ReadXML(XMLElement * parent) {
2352 	XMLElementList * children = parent->getChildren();
2353 	if (children) {
2354 		for (int i=0; i<children->length(); i++) {
2355 			XMLElement * child = children->item(i);
2356 			MMP_IODataGroupNS item;
2357 			if (child && CML_convert(child->getName(), item)) {
2358 				bool tb;
2359 				switch (item) {
2360 					case MMP_IODGTitle:
2361 					{
2362 						const char * v = child->getValue();
2363 						if (v) SetTitle(v);
2364 					}
2365 						break;
2366 					case MMP_IODGPointGroup:
2367 					{
2368 						long temp;
2369 						if (child->getLongValue(temp)) {
2370 							SetPointGroup((GAMESSPointGroup)temp);
2371 							if (child->getAttributeValue(CML_convert(MMP_IODGPointGroupOrder), temp))
2372 								SetPointGroupOrder(temp);
2373 						}
2374 					}
2375 						break;
2376 					case MMP_IODGCoordType:
2377 					{
2378 						const char * v = child->getValue();
2379 						if (v) SetCoordType(v);
2380 					}
2381 						break;
2382 					case MMP_IODGNumZVars:
2383 					{
2384 						long temp;
2385 						if (child->getLongValue(temp)) SetNumZVar(temp);
2386 					}
2387 						break;
2388 					case MMP_IODGUnits:
2389 						if (child->getBoolValue(tb))
2390 							SetUnits(tb);
2391 						break;
2392 					case MMP_IODGNoSymFlag:
2393 						if (child->getBoolValue(tb))
2394 							SetUseSym(tb);
2395 						break;
2396 					default:
2397 					{
2398 						wxString msg;
2399 						msg.Printf(_T("Unknown data group CML element: %s"), child->getName());
2400 						wxLogMessage(msg);
2401 					}
2402 				}
2403 			}
2404 		}
2405 		delete children;
2406 	}
2407 }
2408 #pragma mark GuessGroup
2409 	//Guess Group functions
2410 //This function is here to provide a default value before returning the string
GetGuessText(void) const2411 const char * GuessGroup::GetGuessText(void) const {
2412 	short value = GetGuess();
2413 	if (value == 0) value = 1;
2414 
2415 	return ConvertGuessType(value);
2416 }
SetGuess(const char * GuessText)2417 short GuessGroup::SetGuess(const char * GuessText) {
2418 	short NewGuess = -1;
2419 
2420 	for (int i=1; i<NumberGuessTypes; i++) {
2421 		const char * val = ConvertGuessType(i);
2422 		if (-1<LocateKeyWord(GuessText, val, strlen(val), 7)) {
2423 			NewGuess = i;
2424 			break;
2425 		}
2426 	}
2427 	if (NewGuess<0) return -1;
2428 	NewGuess = SetGuess(NewGuess);
2429 	return NewGuess;
2430 }
ConvertGuessType(const int & type)2431 const char * GuessGroup::ConvertGuessType(const int & type) {
2432 	switch (type) {
2433 		case HUCKELGuessType:
2434 			return "HUCKEL";
2435 		case HCOREGuessType:
2436 			return "HCORE";
2437 		case MOREADGuessType:
2438 			return "MOREAD";
2439 		case MOSAVEDGuessType:
2440 			return "MOSAVED";
2441 		case SkipGuessType:
2442 			return "SKIP";	//By hand later?
2443 		default:
2444 			return "invalid";
2445 	}
2446 	return NULL;
2447 }
GuessGroup(void)2448 GuessGroup::GuessGroup(void) {
2449 	InitData();
2450 }
GuessGroup(GuessGroup * Copy)2451 GuessGroup::GuessGroup(GuessGroup *Copy) {	//copy constructor
2452 	if (Copy) {
2453 		*this = *Copy;
2454 		IOrder = JOrder = NULL;
2455 			//check and copy I & J order here
2456 	}
2457 }
InitData(void)2458 void GuessGroup::InitData(void) {
2459 	MOTolZ = MOTolEquil = 0.0f;
2460 	IOrder = JOrder = NULL;
2461 	NumOrbs = 0;
2462 	VecSource = 0;
2463 	GuessType = 0;
2464 	Options = 0;
2465 }
WriteToFile(BufferFile * File,InputData * IData,MoleculeData * MainData)2466 void GuessGroup::WriteToFile(BufferFile *File, InputData *IData, MoleculeData * MainData) {
2467 	long	test=false;
2468 	char	Out[133];
2469 
2470 	Frame * lFrame = MainData->GetCurrentFramePtr();
2471 		//first determine wether or not the Guess group needs to be punched
2472 	if (GetGuess()) test = true;
2473 	if (GetPrintMO()) test = true;
2474 	if (GetMix()&&IData->Control->GetMultiplicity()&&
2475 		(IData->Control->GetSCFType()==2)) test = true;
2476 
2477 	if (!test) return;
2478 
2479 		//Punch the group label
2480 	File->WriteLine(" $GUESS ", false);
2481 		//Guess Type
2482 	if (GetGuess()) {
2483 		sprintf(Out,"GUESS=%s ", GetGuessText());
2484 		File->WriteLine(Out, false);
2485 	}
2486 		//NumOrbs
2487 	if (GetGuess()==3) {
2488 		long nOrbs = GetNumOrbs();
2489 		if (!nOrbs) {	//Make a guess if the guess comes from local orbs
2490 			short tempVec = GetVecSource();
2491 			const std::vector<OrbitalRec *> * Orbs = lFrame->GetOrbitalSetVector();
2492 			if (Orbs->size() > 0) {
2493 				if ((tempVec<=0)||(tempVec>Orbs->size() + 2)) tempVec = 2;
2494 				if (tempVec > 1) {
2495 					OrbitalRec * OrbSet = (*Orbs)[tempVec-2];
2496 					nOrbs = OrbSet->getNumOccupiedAlphaOrbitals();
2497 					if (nOrbs <= 0) nOrbs = OrbSet->getNumAlphaOrbitals();
2498 				}
2499 			}
2500 		}
2501 		sprintf(Out, "NORB=%ld ", nOrbs);
2502 		File->WriteLine(Out, false);
2503 	}	//PrintMO
2504 	if (GetPrintMO()) {
2505 		sprintf(Out, "PRTMO=.TRUE. ");
2506 		File->WriteLine(Out, false);
2507 	}	//Mix
2508 	if (GetMix()&&((IData->Control->GetMultiplicity()==1)||
2509 			(IData->Control->GetMultiplicity()==0))&&(IData->Control->GetSCFType()==2)) {
2510 		sprintf(Out, "MIX=.TRUE. ");
2511 		File->WriteLine(Out, false);
2512 	}
2513 	File->WriteLine("$END", true);
2514 }
WriteVecGroup(BufferFile * File,MoleculeData * lData)2515 void GuessGroup::WriteVecGroup(BufferFile *File, MoleculeData * lData) {
2516 		//prepare to punch out $Vec information if Guess=MORead
2517 	if (GetGuess() == 3) {
2518 		Frame * lFrame = lData->GetCurrentFramePtr();
2519 		BasisSet * lBasis = lData->GetBasisSet();
2520 		long NumBasisFuncs = lBasis->GetNumBasisFuncs(false);
2521 		short tempVec = GetVecSource();
2522 		const std::vector<OrbitalRec *> * Orbs = lFrame->GetOrbitalSetVector();
2523 		if ((tempVec != 1)&&(Orbs->size() > 0)) {
2524 			if ((tempVec<=0)||(tempVec > (Orbs->size() + 2))) tempVec = 2;
2525 			if (tempVec > 1) {
2526 				OrbitalRec * OrbSet = (*Orbs)[tempVec-2];
2527 				long nOrbs = GetNumOrbs();
2528 				if (nOrbs <= 0) {	//Setup the default value for the orbital count
2529 					nOrbs = OrbSet->getNumOccupiedAlphaOrbitals();
2530 					if (nOrbs <= 0) nOrbs = OrbSet->getNumAlphaOrbitals();
2531 				}
2532 				OrbSet->WriteVecGroup(File, NumBasisFuncs, nOrbs);
2533 			}
2534 		} else {
2535 			File->WriteLine("You must provide a $VEC group here!", true);
2536 		}
2537 	}
2538 }
WriteXML(XMLElement * parent) const2539 void GuessGroup::WriteXML(XMLElement * parent) const {
2540 	char line[kMaxLineLength];
2541 	XMLElement * Ele = parent->addChildElement(CML_convert(MMP_IOGuessGroupElement));
2542 	if (GuessType) Ele->addChildElement(CML_convert(MMP_IOGGGuessType), ConvertGuessType(GuessType));
2543 	if (NumOrbs) {
2544 		snprintf(line, kMaxLineLength, "%ld", NumOrbs);
2545 		Ele->addChildElement(CML_convert(MMP_IOGGNumOrbs), line);
2546 	}
2547 	if (VecSource) {
2548 		snprintf(line, kMaxLineLength, "%d", VecSource);
2549 		Ele->addChildElement(CML_convert(MMP_IOGGVecSource), line);
2550 	}
2551 	if (GetPrintMO()) Ele->addChildElement(CML_convert(MMP_IOGGPrintMO), trueXML);
2552 	if (GetNOrder()) Ele->addChildElement(CML_convert(MMP_IOGGOrbReorder), trueXML);
2553 	if (GetMix()) Ele->addChildElement(CML_convert(MMP_IOGGOrbMix), trueXML);
2554 	if (MOTolZ) {
2555 		snprintf(line, kMaxLineLength, "%f", MOTolZ);
2556 		Ele->addChildElement(CML_convert(MMP_IOGGMOTolZ), line);
2557 	}
2558 	if (MOTolEquil) {
2559 		snprintf(line, kMaxLineLength, "%f", MOTolEquil);
2560 		Ele->addChildElement(CML_convert(MMP_IOGGMOTolEquil), line);
2561 	}
2562 }
ReadXML(XMLElement * parent)2563 void GuessGroup::ReadXML(XMLElement * parent) {
2564 	XMLElementList * children = parent->getChildren();
2565 	if (children) {
2566 		for (int i=0; i<children->length(); i++) {
2567 			XMLElement * child = children->item(i);
2568 			MMP_IOGuessGroupNS item;
2569 			if (child && CML_convert(child->getName(), item)) {
2570 				bool tb;
2571 				switch (item) {
2572 					case MMP_IOGGGuessType:
2573 					{
2574 						const char * v = child->getValue();
2575 						if (v) SetGuess(v);
2576 					}
2577 						break;
2578 					case MMP_IOGGNumOrbs:
2579 					{
2580 						long temp;
2581 						if (child->getLongValue(temp)) {
2582 							SetNumOrbs(temp);
2583 						}
2584 					}
2585 						break;
2586 					case MMP_IOGGVecSource:
2587 					{
2588 						long temp;
2589 						if (child->getLongValue(temp)) {
2590 							VecSource = temp;
2591 						}
2592 					}
2593 						break;
2594 					case MMP_IOGGPrintMO:
2595 						if (child->getBoolValue(tb))
2596 							SetPrintMO(tb);
2597 						break;
2598 					case MMP_IOGGOrbReorder:
2599 						if (child->getBoolValue(tb))
2600 							SetNOrder(tb);
2601 						break;
2602 					case MMP_IOGGOrbMix:
2603 						if (child->getBoolValue(tb))
2604 							SetMix(tb);
2605 						break;
2606 					case MMP_IOGGMOTolZ:
2607 					{
2608 						double temp;
2609 						if (child->getDoubleValue(temp)) MOTolZ = temp;
2610 					}
2611 						break;
2612 					case MMP_IOGGMOTolEquil:
2613 					{
2614 						double temp;
2615 						if (child->getDoubleValue(temp)) MOTolEquil = temp;
2616 					}
2617 						break;
2618 					default:
2619 					{
2620 						wxString msg;
2621 						msg.Printf(_T("Unknown guess group CML element: %s"), child->getName());
2622 						wxLogMessage(msg);
2623 					}
2624 				}
2625 			}
2626 		}
2627 		delete children;
2628 	}
2629 }
2630 #pragma mark SCFGroup
SCFGroup(void)2631 SCFGroup::SCFGroup(void) {
2632 	InitData();
2633 }
SCFGroup(SCFGroup * Copy)2634 SCFGroup::SCFGroup(SCFGroup *Copy) {
2635 	if (Copy)
2636 		*this = *Copy;
2637 	else
2638 		SCFGroup();
2639 }
InitData(void)2640 void SCFGroup::InitData(void) {
2641 	SOGTolerance = EnErrThresh = DEMCutoff = DampCutoff = 0.0;
2642 	ConvCriteria = MaxDIISEq = MVOCharge = 0;
2643 	Punch = Options1 = ConverganceFlags = 0;
2644 	GVBNumCoreOrbs = GVBNumOpenShells = GVBNumPairs = 0;
2645 		//default Direct SCF to true. This is not the GAMESS default
2646 		//but is better in most cases.
2647 	SetDirectSCF(true);
2648 	SetFockDiff(true);
2649 }
SetDirectSCF(bool State)2650 bool SCFGroup::SetDirectSCF(bool State) {
2651 	if (Options1 & 1) Options1--;
2652 	if (State) Options1 ++;
2653 	return GetDirectSCF();
2654 }
SetFockDiff(bool State)2655 bool SCFGroup::SetFockDiff(bool State) {
2656 	if (Options1 & 2) Options1 -= 2;
2657 	if (State) Options1 += 2;
2658 	return GetFockDiff();
2659 }
SetUHFNO(bool State)2660 bool SCFGroup::SetUHFNO(bool State) {
2661 	if (Options1 & 4) Options1 -= 4;
2662 	if (State) Options1 += 4;
2663 	return GetUHFNO();
2664 }
SetConvergance(short NewConv)2665 short SCFGroup::SetConvergance(short NewConv) {
2666 	if (NewConv > 0) ConvCriteria = NewConv;
2667 	return ConvCriteria;
2668 }
WriteToFile(BufferFile * File,InputData * IData)2669 void SCFGroup::WriteToFile(BufferFile *File, InputData *IData) {
2670 	long	test=false;
2671 	char	Out[133];
2672 
2673 		//first determine wether or not the SCF group needs to be punched
2674 	if (IData->Control->GetSCFType() > 4) return;	//not relavent to the selected SCF type
2675 	if (ConvCriteria > 0) test = true;
2676 	if (GetDirectSCF()) test = true;
2677 	if (IData->Control->GetSCFType() == GAMESS_GVB) test = true;
2678 	if (NPREOVector.size() > 0) test = true;
2679 
2680 	if (!test) return;
2681 
2682 		//Punch the group label
2683 	File->WriteLine(" $SCF ", false);
2684 		//Direct SCF
2685 	if (GetDirectSCF()) {
2686 		sprintf(Out,"DIRSCF=.TRUE. ");
2687 		File->WriteLine(Out, false);
2688 		if (!GetFockDiff()) {	//Fock Differencing requires direct SCF
2689 			sprintf(Out,"FDIFF=.FALSE. ");
2690 			File->WriteLine(Out, false);
2691 		}
2692 	}
2693 		//convergance
2694 	if (ConvCriteria > 0) {
2695 		sprintf(Out, "NCONV=%d ", ConvCriteria);
2696 		File->WriteLine(Out, false);
2697 	}
2698 	if (GetDIIS()) File->WriteLine("DIIS=.T. ", false);
2699 	if (GetSOSCF()) File->WriteLine("SOSCF=.T. ", false);
2700 	if (GetExtrapolation()) File->WriteLine("EXTRAP=.T. ", false);
2701 	if (GetDamp()) File->WriteLine("DAMP=.T. ", false);
2702 	if (GetShift()) File->WriteLine("SHIFT=.T. ", false);
2703 	if (GetRestriction()) File->WriteLine("RSTRCT=.T. ", false);
2704 	if (GetDEM()) File->WriteLine("DEM=.T. ", false);
2705 		//reduced orbital printout, can either have two or four values
2706 	if (NPREOVector.size() > 0) {
2707 		if (NPREOVector.size() == 2) {
2708 			sprintf(Out, "NPREO(1)=%ld,%ld ", NPREOVector[0], NPREOVector[1]);
2709 		} else {
2710 			sprintf(Out, "NPREO(1)=%ld,%ld,%ld,%ld ", NPREOVector[0], NPREOVector[1], NPREOVector[2], NPREOVector[3]);
2711 		}
2712 		File->WriteLine(Out, false);
2713 	}
2714 		//UHF Natural Orbitals
2715 	if (GetUHFNO()) {
2716 		sprintf(Out, "UHFNOS=.TRUE. ");
2717 		File->WriteLine(Out, false);
2718 	}
2719 	//GVB related items if this is a GVB run
2720 	if (IData->Control->GetSCFType() == GAMESS_GVB) {
2721 		sprintf(Out, "NCO=%ld ", GVBNumCoreOrbs);
2722 		File->WriteLine(Out, false);
2723 		if (GVBNumPairs>0) {
2724 			sprintf(Out, "NPAIR=%ld ", GVBNumPairs);
2725 			File->WriteLine(Out, false);
2726 		}
2727 		if (GVBNumOpenShells>0) {
2728 			sprintf(Out, "NSETO=%ld ", GVBNumOpenShells);
2729 			File->WriteLine(Out, false);
2730 			File->WriteLine("NO=", false);
2731 			std::ostringstream temp;
2732 			for (long i=0; i< GVBNumOpenShells; i++) {
2733 				if (i != 0) temp << ",";
2734 				if (i < GVBOpenShellDeg.size()) {
2735 					temp << GVBOpenShellDeg[i];
2736 				} else {
2737 					temp << "0";	//default value
2738 				}
2739 			}
2740 			temp << " ";
2741 			File->WriteLine(temp.str().c_str(), false);
2742 		}
2743 	}
2744 
2745 	File->WriteLine("$END", true);
2746 }
WriteXML(XMLElement * parent) const2747 void SCFGroup::WriteXML(XMLElement * parent) const {
2748 	char line[kMaxLineLength];
2749 	XMLElement * Ele = parent->addChildElement(CML_convert(MMP_IOSCFGroupElement));
2750 	if (GetConvergance()) {
2751 		snprintf(line, kMaxLineLength, "%d", GetConvergance());
2752 		Ele->addChildElement(CML_convert(MMP_IOSGConvCriteria), line);
2753 	}
2754 	Ele->addBoolChildElement(CML_convert(MMP_IOSGDirectSCF), GetDirectSCF());
2755 	Ele->addBoolChildElement(CML_convert(MMP_IOSGFockDiff), GetFockDiff());
2756 	if (GetUHFNO()) Ele->addChildElement(CML_convert(MMP_IOSGUHFNauralOrbitals), trueXML);
2757 	if (GetExtrapolation()) Ele->addChildElement(CML_convert(MMP_IOSGExtrap), trueXML);
2758 	if (GetDamp()) Ele->addChildElement(CML_convert(MMP_IOSGDamp), trueXML);
2759 	if (GetShift()) Ele->addChildElement(CML_convert(MMP_IOSGShift), trueXML);
2760 	if (GetRestriction()) Ele->addChildElement(CML_convert(MMP_IOSGRestriction), trueXML);
2761 	if (GetDIIS()) Ele->addChildElement(CML_convert(MMP_IOSGDIIS), trueXML);
2762 	if (GetSOSCF()) Ele->addChildElement(CML_convert(MMP_IOSGSOSCF), trueXML);
2763 	if (GetDEM()) Ele->addChildElement(CML_convert(MMP_IOSGDEM), trueXML);
2764 	if (GetGVBNumCoreOrbs()>0) {
2765 		snprintf(line, kMaxLineLength, "%ld", GetGVBNumCoreOrbs());
2766 		Ele->addChildElement(CML_convert(MMP_IOSGGVBNumCoreOrbs), line);
2767 	}
2768 	if (GetGVBNumPairs()>0) {
2769 		snprintf(line, kMaxLineLength, "%ld", GetGVBNumPairs());
2770 		Ele->addChildElement(CML_convert(MMP_IOSGGVBNumPairs), line);
2771 	}
2772 	if (GetGVBNumOpenShells()>0) {
2773 		snprintf(line, kMaxLineLength, "%ld", GetGVBNumOpenShells());
2774 		Ele->addChildElement(CML_convert(MMP_IOSGGVBNumOpenShells), line);
2775 		Ele->AddLongArray(GVBOpenShellDeg, CML_convert(MMP_IOSCFArrayElement), CML_convert(MMP_IOSGGVBOpenShellDeg));
2776 	}
2777 	if (NPREOVector.size()>0) {
2778 		Ele->AddLongArray(NPREOVector, CML_convert(MMP_IOSCFArrayElement), CML_convert(MMP_IOSCFNPREOArrayElement));
2779 	}
2780 
2781 }
ReadXML(XMLElement * parent)2782 void SCFGroup::ReadXML(XMLElement * parent) {
2783 	XMLElementList * children = parent->getChildren();
2784 	if (children) {
2785 		for (int i=0; i<children->length(); i++) {
2786 			XMLElement * child = children->item(i);
2787 			MMP_IOSCFGroupNS item;
2788 			if (child && CML_convert(child->getName(), item)) {
2789 				bool tb;
2790 				long temp;
2791 				switch (item) {
2792 					case MMP_IOSGConvCriteria:
2793 					{
2794 						if (child->getLongValue(temp)) {
2795 							SetConvergance(temp);
2796 						}
2797 					}
2798 						break;
2799 					case MMP_IOSGDirectSCF:
2800 						if (child->getBoolValue(tb))
2801 							SetDirectSCF(tb);
2802 						break;
2803 					case MMP_IOSGFockDiff:
2804 						if (child->getBoolValue(tb))
2805 							SetFockDiff(tb);
2806 						break;
2807 					case MMP_IOSGUHFNauralOrbitals:
2808 						if (child->getBoolValue(tb))
2809 							SetUHFNO(tb);
2810 						break;
2811 					case MMP_IOSGExtrap:
2812 						if (child->getBoolValue(tb))
2813 							SetExtrapolation(tb);
2814 						break;
2815 					case MMP_IOSGDamp:
2816 						if (child->getBoolValue(tb))
2817 							SetDamp(tb);
2818 						break;
2819 					case MMP_IOSGShift:
2820 						if (child->getBoolValue(tb))
2821 							SetShift(tb);
2822 						break;
2823 					case MMP_IOSGRestriction:
2824 						if (child->getBoolValue(tb))
2825 							SetRestriction(tb);
2826 						break;
2827 					case MMP_IOSGDIIS:
2828 						if (child->getBoolValue(tb))
2829 							SetDIIS(tb);
2830 						break;
2831 					case MMP_IOSGSOSCF:
2832 						if (child->getBoolValue(tb))
2833 							SetSOSCF(tb);
2834 						break;
2835 					case MMP_IOSGDEM:
2836 						if (child->getBoolValue(tb))
2837 							SetDEM(tb);
2838 						break;
2839 					case MMP_IOSGGVBNumCoreOrbs:
2840 						if (child->getLongValue(temp))
2841 							SetGVBNumCoreOrbs(temp);
2842 						break;
2843 					case MMP_IOSGGVBNumPairs:
2844 						if (child->getLongValue(temp))
2845 							SetGVBNumPairs(temp);
2846 						break;
2847 					case MMP_IOSGGVBNumOpenShells:
2848 						if (child->getLongValue(temp))
2849 							SetGVBNumOpenShells(temp);
2850 						break;
2851 					case MMP_IOSCFArrayElement:
2852 						//Check the title attribute, but there should be only one array
2853 						CML_convert(child->getAttributeValue(CML_convert(titleAttr)),item);
2854 						if (item == MMP_IOSGGVBOpenShellDeg) {
2855 							GVBOpenShellDeg.clear();
2856 							//This implies that this item must follow the NumOpenShells item.
2857 							child->getLongArray(GVBNumOpenShells, GVBOpenShellDeg);
2858 						} else if (item == MMP_IOSCFNPREOArrayElement) {
2859 							NPREOVector.clear();
2860 							child->getLongArray(4, NPREOVector);
2861 						}
2862 						break;
2863 					default:
2864 					{
2865 						wxString msg;
2866 						msg.Printf(_("Skipping unknown XML Element: %s"), child->getName());
2867 						wxLogMessage(msg);
2868 					}
2869 				}
2870 			}
2871 		}
2872 		delete children;
2873 	}
2874 }
SetGVBNumOpenShells(const long & no)2875 void SCFGroup::SetGVBNumOpenShells(const long &no) {
2876 	if (no >= 0) {
2877 		GVBNumOpenShells = no;
2878 		for (int i=GVBOpenShellDeg.size(); i<GVBNumOpenShells; i++) {
2879 			GVBOpenShellDeg.push_back(0);	//The GAMESS default is 0, maybe 1 is a better default?
2880 		}
2881 	}
2882 }
SetGVBNODegValue(int index,long value)2883 void SCFGroup::SetGVBNODegValue(int index, long value) {
2884 	if ((index >= 0)&&(value >= 0)&&(index < GVBOpenShellDeg.size())) {
2885 		GVBOpenShellDeg[index] = value;
2886 	}
2887 }
2888 #pragma mark MP2Group
MP2Group(void)2889 MP2Group::MP2Group(void) {
2890 	InitData();
2891 }
MP2Group(MP2Group * Copy)2892 MP2Group::MP2Group(MP2Group *Copy) {
2893 	*this = *Copy;
2894 }
InitData(void)2895 void MP2Group::InitData(void) {
2896 	CutOff = 0.0;
2897 	NumCoreElectrons = -1;
2898 	Memory = 0;
2899 	Method = AOInts = LMOMP2 = 0;
2900 	MP2Prop = false;
2901 }
SetIntCutoff(double NewCutoff)2902 double MP2Group::SetIntCutoff(double NewCutoff) {
2903 	if (NewCutoff > 0.0) CutOff = NewCutoff;
2904 	return CutOff;
2905 }
SetNumCoreElectrons(long NewNum)2906 long MP2Group::SetNumCoreElectrons(long NewNum) {
2907 	if (NewNum>=0) NumCoreElectrons = NewNum;
2908 	return NumCoreElectrons;
2909 }
SetMemory(long NewMem)2910 long MP2Group::SetMemory(long NewMem) {
2911 	if (NewMem >= 0) Memory = NewMem;
2912 	return Memory;
2913 }
SetMethod(char NewMethod)2914 char MP2Group::SetMethod(char NewMethod) {
2915 	if ((NewMethod==2)||(NewMethod==3)) Method = NewMethod;
2916 	return Method;
2917 }
GetAOIntMethodText(void) const2918 const char * MP2Group::GetAOIntMethodText(void) const {
2919 	if (AOInts == 0) return NULL;
2920 	if (AOInts == 1) return "DUP";
2921 	return "DIST";
2922 }
SetAOIntMethod(const char * t)2923 void MP2Group::SetAOIntMethod(const char * t) {
2924 	if (!t) return;
2925 	if (!strcasecmp(t, "DUP")) AOInts = 1;
2926 	else if (!strcasecmp(t, "DIST")) AOInts = 2;
2927 }
SetAOIntMethod(char NewMethod)2928 char MP2Group::SetAOIntMethod(char NewMethod) {
2929 	if ((NewMethod == 1)||(NewMethod == 2)) AOInts = NewMethod;
2930 	return AOInts;
2931 }
GetLMOMP2(void) const2932 bool MP2Group::GetLMOMP2(void) const {
2933 	if (LMOMP2) return true;
2934 	return false;
2935 }
SetLMOMP2(bool State)2936 bool MP2Group::SetLMOMP2(bool State) {
2937 	if (State) LMOMP2 = true;
2938 	else LMOMP2 = false;
2939 	return LMOMP2;
2940 }
WriteToFile(BufferFile * File,InputData * IData)2941 void MP2Group::WriteToFile(BufferFile *File, InputData *IData) {
2942 	long	test=false;
2943 	char	Out[133];
2944 
2945 		//first determine wether or not the MP2 group needs to be punched
2946 	if (IData->Control->GetMPLevel() != 2) return;	//Don't punch if MP2 isn't active
2947 	if ((NumCoreElectrons>=0)||Memory||Method||AOInts) test = true;
2948 	if (GetLMOMP2()) test = true;
2949 	if (CutOff > 0.0) test = true;
2950 
2951 	if (!test) return;
2952 
2953 		//Punch the group label
2954 	File->WriteLine(" $MP2 ", false);
2955 		//core electrons
2956 	if (NumCoreElectrons >= 0) {
2957 		sprintf(Out,"NACORE=%ld ", NumCoreElectrons);
2958 		File->WriteLine(Out, false);
2959 		if (IData->Control->GetSCFType() == GAMESS_UHF) {
2960 			sprintf(Out,"NBCORE=%ld ", NumCoreElectrons);
2961 			File->WriteLine(Out, false);
2962 		}
2963 	}
2964 	//MP2Prop
2965 	if ((IData->Control->GetRunType() <= Energy) && GetMP2Prop()) {
2966 		sprintf(Out, "MP2PRP=.TRUE. ");
2967 		File->WriteLine(Out, false);
2968 	}
2969 		//LMOMP2
2970 	if (GetLMOMP2()) {
2971 		sprintf(Out, "LMOMP2=.TRUE. ");
2972 		File->WriteLine(Out, false);
2973 	}	//Memory
2974 	if (Memory) {
2975 		sprintf(Out, "NWORD=%ld ",Memory);
2976 		File->WriteLine(Out, false);
2977 	}	//CutOff
2978 	if (CutOff > 0.0) {
2979 		sprintf(Out, "CUTOFF=%.2e ", CutOff);
2980 		File->WriteLine(Out, false);
2981 	}	//Method
2982 	if (Method) {
2983 		sprintf(Out, "METHOD=%d ", Method);
2984 		File->WriteLine(Out, false);
2985 	}	//AO storage
2986 	if (AOInts) {
2987 		sprintf(Out, "AOINTS=%s ", GetAOIntMethodText());
2988 		File->WriteLine(Out, false);
2989 	}
2990 
2991 	File->WriteLine("$END", true);
2992 }
WriteXML(XMLElement * parent) const2993 void MP2Group::WriteXML(XMLElement * parent) const {
2994 	char line[kMaxLineLength];
2995 	XMLElement * Ele = parent->addChildElement(CML_convert(MMP_IOMP2GroupElement));
2996 	if (NumCoreElectrons) {
2997 		snprintf(line, kMaxLineLength, "%ld", NumCoreElectrons);
2998 		Ele->addChildElement(CML_convert(MMP_IOMGNumCoreElectrons), line);
2999 	}
3000 	if (CutOff > 0.0) {
3001 		snprintf(line, kMaxLineLength, "%lf", CutOff);
3002 		Ele->addChildElement(CML_convert(MMP_IOMGCutOff), line);
3003 	}
3004 	if (Memory) {
3005 		snprintf(line, kMaxLineLength, "%ld", Memory);
3006 		Ele->addChildElement(CML_convert(MMP_IOMGMemory), line);
3007 	}
3008 	if (Method) {
3009 		snprintf(line, kMaxLineLength, "%d", Method);
3010 		Ele->addChildElement(CML_convert(MMP_IOMGTransMethod), line);
3011 	}
3012 	if (AOInts) Ele->addChildElement(CML_convert(MMP_IOMGAOInts), GetAOIntMethodText());
3013 	if (GetLMOMP2()) Ele->addChildElement(CML_convert(MMP_IOMGLMOMP2), trueXML);
3014 	if (GetMP2Prop()) Ele->addChildElement(CML_convert(MMP_IOMP2MP2PRP), trueXML);
3015 }
ReadXML(XMLElement * parent)3016 void MP2Group::ReadXML(XMLElement * parent) {
3017 	XMLElementList * children = parent->getChildren();
3018 	if (children) {
3019 		for (int i=0; i<children->length(); i++) {
3020 			XMLElement * child = children->item(i);
3021 			MMP_IOMP2GroupNS item;
3022 			if (child && CML_convert(child->getName(), item)) {
3023 				switch (item) {
3024 					case MMP_IOMGNumCoreElectrons:
3025 					{
3026 						long temp;
3027 						if (child->getLongValue(temp)) {
3028 							SetNumCoreElectrons(temp);
3029 						}
3030 					}
3031 						break;
3032 					case MMP_IOMGCutOff:
3033 					{
3034 						double temp;
3035 						if (child->getDoubleValue(temp)) {
3036 							SetIntCutoff(temp);
3037 						}
3038 					}
3039 						break;
3040 					case MMP_IOMGMemory:
3041 					{
3042 						long temp;
3043 						if (child->getLongValue(temp)) {
3044 							SetMemory(temp);
3045 						}
3046 					}
3047 						break;
3048 					case MMP_IOMGTransMethod:
3049 					{
3050 						long temp;
3051 						if (child->getLongValue(temp)) {
3052 							Method = temp;
3053 						}
3054 					}
3055 						break;
3056 					case MMP_IOMGAOInts:
3057 					{
3058 						const char * v = child->getValue();
3059 						if (v) {
3060 							SetAOIntMethod(v);
3061 						}
3062 					}
3063 						break;
3064 					case MMP_IOMGLMOMP2:
3065 					{
3066 						bool tb;
3067 						if (child->getBoolValue(tb))
3068 							SetLMOMP2(tb);
3069 					}
3070 						break;
3071 					case MMP_IOMP2MP2PRP:
3072 					{
3073 						bool tb;
3074 						if (child->getBoolValue(tb))
3075 							SetMP2Prop(tb);
3076 					}
3077 						break;
3078 					default:
3079 					{
3080 						wxString msg;
3081 						msg.Printf(_T("Unknown MP2 group CML element: %s"), child->getName());
3082 						wxLogMessage(msg);
3083 					}
3084 				}
3085 			}
3086 		}
3087 		delete children;
3088 	}
3089 }
3090 #pragma mark HessianGroup
InitData(void)3091 void HessianGroup::InitData(void) {
3092 	DisplacementSize = 0.01f;
3093 	FrequencyScaleFactor = 1.0f;
3094 	BitOptions = 17;	//bit 1 + bit 5
3095 }
WriteToFile(BufferFile * File,InputData * IData)3096 void HessianGroup::WriteToFile(BufferFile *File, InputData *IData) {
3097 	Boolean	method=false;
3098 	char	Out[133];
3099 
3100 		//Only output a force group if it's relevant to the overall run options
3101 	if (! IsHessianGroupNeeded(IData)) return;
3102 
3103 	bool AnalyticPoss = IsAnalyticHessianPossible(IData);
3104 
3105 	method = GetAnalyticMethod() && AnalyticPoss;
3106 		//Punch the group label
3107 	File->WriteLine(" $FORCE ", false);
3108 		//Method
3109 	if (method) File->WriteLine("METHOD=ANALYTIC ", false);
3110 	else File->WriteLine("METHOD=SEMINUM ", false);
3111 	if (!method) {
3112 			//NVIB
3113 		if (GetDoubleDiff()) {
3114 			File->WriteLine("NVIB=2 ", false);
3115 		}	//Vib Size
3116 		if (DisplacementSize != 0.01) {
3117 			sprintf(Out, "VIBSIZ=%f ", DisplacementSize);
3118 			File->WriteLine(Out, false);
3119 		}
3120 	}	//Purify
3121 	if (GetPurify()) {
3122 		File->WriteLine("PURIFY=.TRUE. ", false);
3123 	}	//Print internal FC's
3124 	if (GetPrintFC()) {
3125 		File->WriteLine("PRTIFC=.TRUE. ", false);
3126 	}	//vib analysis
3127 	if (GetVibAnalysis()) {
3128 		File->WriteLine("VIBANL=.TRUE. ", false);
3129 		if (FrequencyScaleFactor != 1.0) {
3130 			sprintf(Out, "SCLFAC=%f ", FrequencyScaleFactor);
3131 			File->WriteLine(Out, false);
3132 		}
3133 	} else File->WriteLine("VIBANL=.FALSE. ", false);
3134 
3135 	File->WriteLine("$END", true);
3136 }
WriteXML(XMLElement * parent) const3137 void HessianGroup::WriteXML(XMLElement * parent) const {
3138 	char line[kMaxLineLength];
3139 	XMLElement * Ele = parent->addChildElement(CML_convert(MMP_IOHessianGroupElement));
3140 	if (DisplacementSize > 0.0) {
3141 		snprintf(line, kMaxLineLength, "%f", DisplacementSize);
3142 		Ele->addChildElement(CML_convert(MMP_IOHGDisplacementSize), line);
3143 	}
3144 	if (FrequencyScaleFactor > 0.0) {
3145 		snprintf(line, kMaxLineLength, "%lf", FrequencyScaleFactor);
3146 		Ele->addChildElement(CML_convert(MMP_IOHGFrequencyScaleFactor), line);
3147 	}
3148 	if (GetAnalyticMethod()) Ele->addChildElement(CML_convert(MMP_IOHGMethod), "analytic");
3149 	else Ele->addChildElement(CML_convert(MMP_IOHGMethod), "numeric");
3150 	if (GetPurify()) Ele->addChildElement(CML_convert(MMP_IOHGPurify), trueXML);
3151 	if (GetPrintFC()) Ele->addChildElement(CML_convert(MMP_IOHGInternalFC), trueXML);
3152 	if (GetVibAnalysis()) Ele->addChildElement(CML_convert(MMP_IOHGVibAnalysis), trueXML);
3153 }
ReadXML(XMLElement * parent)3154 void HessianGroup::ReadXML(XMLElement * parent) {
3155 	XMLElementList * children = parent->getChildren();
3156 	if (children) {
3157 		for (int i=0; i<children->length(); i++) {
3158 			XMLElement * child = children->item(i);
3159 			MMP_IOHessGroupNS item;
3160 			if (child && CML_convert(child->getName(), item)) {
3161 				bool tb;
3162 				switch (item) {
3163 					case MMP_IOHGDisplacementSize:
3164 					{
3165 						double temp;
3166 						if (child->getDoubleValue(temp)) {
3167 							SetDisplacementSize(temp);
3168 						}
3169 					}
3170 						break;
3171 					case MMP_IOHGFrequencyScaleFactor:
3172 					{
3173 						double temp;
3174 						if (child->getDoubleValue(temp)) {
3175 							SetFreqScale(temp);
3176 						}
3177 					}
3178 						break;
3179 					case MMP_IOHGMethod:
3180 					{
3181 						const char * v = child->getValue();
3182 						if (v) {
3183 							if (!strcasecmp(v, "analytic")) SetAnalyticMethod(true);
3184 							else if (!strcasecmp(v, "numeric")) SetAnalyticMethod(false);
3185 						}
3186 					}
3187 						break;
3188 					case MMP_IOHGPurify:
3189 						if (child->getBoolValue(tb))
3190 							SetPurify(tb);
3191 						break;
3192 					case MMP_IOHGInternalFC:
3193 						if (child->getBoolValue(tb))
3194 							SetPrintFC(tb);
3195 						break;
3196 					case MMP_IOHGVibAnalysis:
3197 						if (child->getBoolValue(tb))
3198 							SetVibAnalysis(tb);
3199 						break;
3200 					default:
3201 					{
3202 						wxString msg;
3203 						msg.Printf(_T("Unknown hessian group CML element: %s"), child->getName());
3204 						wxLogMessage(msg);
3205 					}
3206 				}
3207 			}
3208 		}
3209 		delete children;
3210 	}
3211 }
IsAnalyticHessianPossible(const InputData * IData)3212 bool HessianGroup::IsAnalyticHessianPossible(const InputData * IData) {
3213 	//Check based on the SCF type
3214 	//This is only part of the current rules. It probably covers the common cases though.
3215 	//ToDo: Match this test up more closely with the state of GAMESS.
3216 	bool result = (((IData->Control->GetSCFType() == 1)||(IData->Control->GetSCFType() == 3)||
3217 					(IData->Control->GetSCFType() == 4)||(IData->Control->GetSCFType() == 0))&&
3218 				   (IData->Control->GetMPLevel() <= 0)&&(!IData->Control->UseDFT()));
3219 	//Analytic hessians are not available for semi-emperical basis sets
3220 	if ((IData->Basis->GetBasis() == GAMESS_BS_MNDO)||(IData->Basis->GetBasis() == GAMESS_BS_AM1)||
3221 		(IData->Basis->GetBasis() == GAMESS_BS_PM3)) return false;
3222 
3223 	return result;
3224 }
IsHessianGroupNeeded(const InputData * IData)3225 bool HessianGroup::IsHessianGroupNeeded(const InputData * IData) {
3226 	bool result = false;
3227 	//Hessians are computed with runtyp of hessian, optimize or sadpoint
3228 	//optimize/sadpoint runs using Hess=Calc or hssend=.t.
3229 	if ((IData->Control->GetRunType() == HessianRun)||
3230 		(IData->Control->GetRunType() == G3MP2)) result = true;
3231 	else if ((IData->Control->GetRunType() == OptimizeRun)||(IData->Control->GetRunType() == SadPointRun)) {
3232 		if (IData->StatPt) {
3233 			if (IData->StatPt->GetHessMethod() == 3) result = true;
3234 			if (IData->StatPt->GetHessEndFlag()) result = true;
3235 		}
3236 	}
3237 	return result;
3238 }
3239 #pragma mark DFTGroup
InitData(void)3240 void DFTGroup::InitData(void) {
3241 	GridSwitch = 3.0e-4;
3242 	Threshold = 1.0e-4;
3243 	Functional = 0;
3244 /*	NumRadialGrids = 96;
3245 	NumThetaGrids = 12;
3246 	NumPhiGrids = 24;
3247 	NumRadialGridsInit = 24;
3248 	NumThetaGridsInit = 8;
3249 	NumPhiGridsInit = 16;
3250  */
3251 	BitFlags = 0;
3252 	SetAuxFunctions(true);
3253 	SetMethodGrid(true);
3254 }
WriteToFile(BufferFile * File,InputData * IData)3255 void DFTGroup::WriteToFile(BufferFile *File, InputData *IData) {
3256 	char	Out[kMaxLineLength];
3257 
3258 	short SCFType = IData->Control->GetSCFType();
3259 		//first determine wether or not the DFT group needs to be punched
3260 	if ((SCFType > 3)|| !IData->Control->UseDFT()) return;//only punch for HF runtypes (RHF, ROHF, UHF)
3261 	if (MethodGrid()) return; //Only need this group for gridfree method currently
3262 		//Punch the group label
3263 	File->WriteLine(" $DFT ", false);
3264 		//Write out the funtional, and any other optional parameters
3265 		//Method
3266 	if (!MethodGrid()) {	//punch method if it needs to be grid-free
3267 		sprintf(Out, "METHOD=GRIDFREE ");
3268 		File->WriteLine(Out, false);
3269 	}
3270 
3271 	File->WriteLine("$END", true);
3272 }
GetDFTGridFuncText(DFTFunctionalsGrid type)3273 const char * DFTGroup::GetDFTGridFuncText(DFTFunctionalsGrid type) {
3274 	switch (type) {
3275 		case DFT_Grid_Slater:
3276 			return "SLATER";
3277 		case DFT_Grid_Becke:
3278 			return "BECKE";
3279 		case DFT_Grid_GILL:
3280 			return "GILL";
3281 		case DFT_Grid_OPTX:
3282 			return "OPTX";
3283 		case DFT_Grid_PW91X:
3284 			return "PW91X";
3285 		case DFT_Grid_PBEX:
3286 			return "PBEX";
3287 		case DFT_Grid_VWN:
3288 			return "VWN";
3289 		case DFT_Grid_VWN1:
3290 			return "VWN1";
3291 		case DFT_Grid_PZ81:
3292 			return "PZ81";
3293 		case DFT_Grid_P86:
3294 			return "P86";
3295 		case DFT_Grid_LYP:
3296 			return "LYP";
3297 		case DFT_Grid_PW91C:
3298 			return "PW91C";
3299 		case DFT_Grid_PBEC:
3300 			return "PBEC";
3301 		case DFT_Grid_OP:
3302 			return "OP";
3303 		case DFT_Grid_SVWN:
3304 			return "SVWN";
3305 		case DFT_Grid_BLYP:
3306 			return "BLYP";
3307 		case DFT_Grid_BOP:
3308 			return "BOP";
3309 		case DFT_Grid_BP86:
3310 			return "BP86";
3311 		case DFT_Grid_GVWN:
3312 			return "GVWN";
3313 		case DFT_Grid_GPW91:
3314 			return "GPW91";
3315 		case DFT_Grid_PBEVWN:
3316 			return "PBEVWN";
3317 		case DFT_Grid_PBEOP:
3318 			return "PBEOP";
3319 		case DFT_Grid_OLYP:
3320 			return "OLYP";
3321 		case DFT_Grid_PW91:
3322 			return "PW91";
3323 		case DFT_Grid_PBE:
3324 			return "PBE";
3325 		case DFT_Grid_revPBE:
3326 			return "REVPBE";
3327 		case DFT_Grid_RPBE:
3328 			return "RPBE";
3329 		case DFT_Grid_PBEsol:
3330 			return "PBESOL";
3331 		case DFT_Grid_EDF1:
3332 			return "EDF1";
3333 		case DFT_Grid_HCTH93:
3334 			return "HCTH93";
3335 		case DFT_Grid_HCTH120:
3336 			return "HCTH120";
3337 		case DFT_Grid_HCTH147:
3338 			return "HCTH147";
3339 		case DFT_Grid_HCTH407:
3340 			return "HCTH407";
3341 		case DFT_Grid_SOGGA:
3342 			return "SOGGA";
3343 		case DFT_Grid_MOHLYP:
3344 			return "MOHLYP";
3345 		case DFT_Grid_B97_D:
3346 			return "B97-D";
3347 		case DFT_Grid_BHHLYP:
3348 			return "BHHLYP";
3349 		case DFT_Grid_B3PW91:
3350 			return "B3PW91";
3351 		case DFT_Grid_B3LYP:
3352 			return "B3LYP";
3353 		case DFT_Grid_B3LYP1:
3354 			return "B3LYP1";
3355 		case DFT_Grid_B97:
3356 			return "B97";
3357 		case DFT_Grid_B97_1:
3358 			return "B97-1";
3359 		case DFT_Grid_B97_2:
3360 			return "B97-2";
3361 		case DFT_Grid_B97_3:
3362 			return "B97-3";
3363 		case DFT_Grid_B97_K:
3364 			return "B97-K";
3365 		case DFT_Grid_B98:
3366 			return "B98";
3367 		case DFT_Grid_PBE0:
3368 			return "PBE0";
3369 		case DFT_Grid_X3LYP:
3370 			return "X3LYP";
3371 		case DFT_Grid_CAMB3LYP:
3372 			return "CAMB3LYP";
3373 		case DFT_Grid_wB97:
3374 			return "WB97";
3375 		case DFT_Grid_wB97X:
3376 			return "WB97X";
3377 		case DFT_Grid_wB97X_D:
3378 			return "WB97X-D";
3379 		case DFT_Grid_B2PLYP:
3380 			return "B2PLYP";
3381 		case DFT_Grid_xB97X_2:
3382 			return "XB97X-2";
3383 		case DFT_Grid_xB97X_2L:
3384 			return "XB97X-2L";
3385 		case DFT_Grid_VS98:
3386 			return "VS98";
3387 		case DFT_Grid_PKZB:
3388 			return "PKZB";
3389 		case DFT_Grid_tHCTH:
3390 			return "tHCTH";
3391 		case DFT_Grid_tHCTHhyb:
3392 			return "tHCTHhyb";
3393 		case DFT_Grid_BMK:
3394 			return "BMK";
3395 		case DFT_Grid_TPSS:
3396 			return "TPSS";
3397 		case DFT_Grid_TPSSh:
3398 			return "TPSSh";
3399 		case DFT_Grid_TPSSm:
3400 			return "TPSSm";
3401 		case DFT_Grid_revTPSS:
3402 			return "REVTPSS";
3403 		case DFT_Grid_M05:
3404 			return "M05";
3405 		case DFT_Grid_M05_2X:
3406 			return "M05-2X";
3407 		case DFT_Grid_M06:
3408 			return "M06";
3409 		case DFT_Grid_M06_L:
3410 			return "M06-L";
3411 		case DFT_Grid_M06_2X:
3412 			return "M06-2X";
3413 		case DFT_Grid_M06_HF:
3414 			return "M06-HF";
3415 		case DFT_Grid_M08_HX:
3416 			return "M08-HX";
3417 		case DFT_Grid_M08_SO:
3418 			return "M08-SO";
3419 		default:
3420 			wxLogMessage(_T("Invalid DFT Grid functional in GetDFTGridFuncText"));
3421 	}
3422 	return "invalid";
3423 }
GetDFTGridFreeFuncText(DFTFunctionalsGridFree type)3424 const char * DFTGroup::GetDFTGridFreeFuncText(DFTFunctionalsGridFree type) {
3425 	switch (type) {
3426 		case DFT_GridFree_XALPHA:
3427 			return "XALPHA";
3428 		case DFT_GridFree_Slater:
3429 			return "SLATER";
3430 		case DFT_GridFree_Becke:
3431 			return "BECKE";
3432 		case DFT_GridFree_Depristo:
3433 			return "DEPRISTO";
3434 		case DFT_GridFree_CAMA:
3435 			return "CAMA";
3436 		case DFT_GridFree_HALF:
3437 			return "HALF";
3438 		case DFT_GridFree_VWN:
3439 			return "VWN";
3440 		case DFT_GridFree_PWLOC:
3441 			return "PWLOC";
3442 		case DFT_GridFree_LYP:
3443 			return "LYP";
3444 		case DFT_GridFree_BVWN:
3445 			return "BVWN";
3446 		case DFT_GridFree_BLYP:
3447 			return "BLYP";
3448 		case DFT_GridFree_BPWLOC:
3449 			return "BPWLOC";
3450 		case DFT_GridFree_B3LYP:
3451 			return "B3LYP";
3452 		case DFT_GridFree_CAMB:
3453 			return "CAMB";
3454 		case DFT_GridFree_XVWN:
3455 			return "XVWN";
3456 		case DFT_GridFree_XPWLOC:
3457 			return "XPWLOC";
3458 		case DFT_GridFree_SVWN:
3459 			return "SVWN";
3460 		case DFT_GridFree_SPWLOC:
3461 			return "SPWLOC";
3462 		case DFT_GridFree_WIGNER:
3463 			return "WIGNER";
3464 		case DFT_GridFree_WS:
3465 			return "WS";
3466 		case DFT_GridFree_WIGEXP:
3467 			return "WIGEXP";
3468 		default:
3469 			wxLogMessage(_T("Invalid DFT func in GetDFTGridFreeText"));
3470 	}
3471 	return "invalid";
3472 }
3473 
GetFunctionalText(void) const3474 const char * DFTGroup::GetFunctionalText(void) const {
3475 	short temp = Functional;
3476 	if (temp <= 0) temp = 1;
3477 	if (MethodGrid()) {
3478 		return GetDFTGridFuncText((DFTFunctionalsGrid) temp);
3479 	} else {	//Grid-free functional list is fairly different
3480 		return GetDFTGridFreeFuncText((DFTFunctionalsGridFree) temp);
3481 	}
3482 	return NULL;
3483 }
SetFunctional(const char * DFT_Type)3484 short DFTGroup::SetFunctional(const char * DFT_Type) {
3485 	if (MethodGrid()) {
3486 		for (int i=invalidDFTGrid+1; i<NumberGRIDDFTFuncs; i++) {
3487 			if (!strcasecmp(DFT_Type, GetDFTGridFuncText((DFTFunctionalsGrid) i))) {
3488 				SetFunctional((DFTFunctionalsGrid) i);
3489 				break;
3490 			}
3491 		}
3492 	} else {
3493 		for (int i=invalidDFTGridFreeType+1; i<NumberDFTGridFreeFuncs; i++) {
3494 			if (!strcasecmp(DFT_Type, GetDFTGridFreeFuncText((DFTFunctionalsGridFree) i))) {
3495 				SetFunctional((DFTFunctionalsGridFree) i);
3496 				break;
3497 			}
3498 		}
3499 	}
3500 	return GetFunctional();
3501 }
SetFunctional(short newvalue)3502 short DFTGroup::SetFunctional(short newvalue) {
3503 	if (MethodGrid()) {
3504 		if ((newvalue > 0)&&(newvalue < NumberGRIDDFTFuncs))
3505 			Functional = newvalue;
3506 	} else
3507 		if ((newvalue > 0)&&(newvalue < NumberDFTGridFreeFuncs))
3508 			Functional = newvalue;
3509 	return Functional;
3510 }
WriteXML(XMLElement * parent) const3511 void DFTGroup::WriteXML(XMLElement * parent) const {
3512 	char line[kMaxLineLength];
3513 	XMLElement * Ele = parent->addChildElement(CML_convert(MMP_IODFTGroupElement));
3514 	Ele->addBoolAttribute(CML_convert(MMP_IODFTGridMethod), MethodGrid());
3515 	snprintf(line, kMaxLineLength, "%f", GridSwitch);
3516 	Ele->addChildElement(CML_convert(MMP_IODFTGGridSwitch), line);
3517 	snprintf(line, kMaxLineLength, "%f", Threshold);
3518 	Ele->addChildElement(CML_convert(MMP_IODFTThreshold), line);
3519 	Ele->addChildElement(CML_convert(MMP_IODFTFunctional), GetFunctionalText());
3520 /*	snprintf(line, kMaxLineLength, "%d", NumRadialGrids);
3521 	Ele->addChildElement(CML_convert(MMP_IODFTNumRadialGrids), line);
3522 	snprintf(line, kMaxLineLength, "%d", NumThetaGrids);
3523 	Ele->addChildElement(CML_convert(MMP_IODFTNumThetaGrids), line);
3524 	snprintf(line, kMaxLineLength, "%d", NumPhiGrids);
3525 	Ele->addChildElement(CML_convert(MMP_IODFTNumPhiGrids), line);
3526 	snprintf(line, kMaxLineLength, "%d", NumRadialGridsInit);
3527 	Ele->addChildElement(CML_convert(MMP_IODFTNumRadialGridsInit), line);
3528 	snprintf(line, kMaxLineLength, "%d", NumThetaGridsInit);
3529 	Ele->addChildElement(CML_convert(MMP_IODFTNumThetaGridsInit), line);
3530 	snprintf(line, kMaxLineLength, "%d", NumPhiGridsInit);
3531 	Ele->addChildElement(CML_convert(MMP_IODFTNumPhiGridsInit), line);
3532  */
3533 	if (GetAuxFunctions()) Ele->addChildElement(CML_convert(MMP_IODFTGetAuxFunctions), trueXML);
3534 	if (GetThree()) Ele->addChildElement(CML_convert(MMP_IODFTThree), trueXML);
3535 }
ReadXML(XMLElement * parent)3536 void DFTGroup::ReadXML(XMLElement * parent) {
3537 	bool boolResult;
3538 	if (parent->getAttributeValue(CML_convert(MMP_IODFTGridMethod), boolResult))
3539 		SetMethodGrid(boolResult);
3540 	XMLElementList * children = parent->getChildren();
3541 	if (children) {
3542 		for (int i=0; i<children->length(); i++) {
3543 			XMLElement * child = children->item(i);
3544 			MMP_IODFTGroupNS item;
3545 			if (child && CML_convert(child->getName(), item)) {
3546 				bool tb;
3547 				switch (item) {
3548 					case MMP_IODFTGGridSwitch:
3549 					{
3550 						double temp;
3551 						if (child->getDoubleValue(temp)) {
3552 							GridSwitch = temp;
3553 						}
3554 					}
3555 						break;
3556 					case MMP_IODFTThreshold:
3557 					{
3558 						double temp;
3559 						if (child->getDoubleValue(temp)) {
3560 							Threshold = temp;
3561 						}
3562 					}
3563 						break;
3564 					case MMP_IODFTFunctional:
3565 					{
3566 						const char * v = child->getValue();
3567 						if (v)
3568 							SetFunctional(v);
3569 					}
3570 						break;
3571 /*					case MMP_IODFTNumRadialGrids:
3572 					{
3573 						long temp;
3574 						if (child->getLongValue(temp)) {
3575 							NumRadialGrids = temp;
3576 						}
3577 					}
3578 						break;
3579 					case MMP_IODFTNumThetaGrids:
3580 					{
3581 						long temp;
3582 						if (child->getLongValue(temp)) {
3583 							NumThetaGrids = temp;
3584 						}
3585 					}
3586 						break;
3587 					case MMP_IODFTNumPhiGrids:
3588 					{
3589 						long temp;
3590 						if (child->getLongValue(temp)) {
3591 							NumPhiGrids = temp;
3592 						}
3593 					}
3594 						break;
3595 					case MMP_IODFTNumRadialGridsInit:
3596 					{
3597 						long temp;
3598 						if (child->getLongValue(temp)) {
3599 							NumRadialGridsInit = temp;
3600 						}
3601 					}
3602 						break;
3603 					case MMP_IODFTNumThetaGridsInit:
3604 					{
3605 						long temp;
3606 						if (child->getLongValue(temp)) {
3607 							NumThetaGridsInit = temp;
3608 						}
3609 					}
3610 						break;
3611 					case MMP_IODFTNumPhiGridsInit:
3612 					{
3613 						long temp;
3614 						if (child->getLongValue(temp)) {
3615 							NumPhiGridsInit = temp;
3616 						}
3617 					}
3618 						break;
3619  */
3620 					case MMP_IODFTGetAuxFunctions:
3621 						if (child->getBoolValue(tb))
3622 							SetAuxFunctions(tb);
3623 						break;
3624 					case MMP_IODFTThree:
3625 						if (child->getBoolValue(tb))
3626 							SetThree(tb);
3627 						break;
3628 					default:
3629 					{
3630 						wxString msg;
3631 						msg.Printf(_T("Unknown DFT group CML element: %s"), child->getName());
3632 						wxLogMessage(msg);
3633 					}
3634 				}
3635 			}
3636 		}
3637 		delete children;
3638 	}
3639 }
3640 #pragma mark EffectiveFragmentsGroup
ConvertCoordToText(int t)3641 const char * EffectiveFragmentsGroup::ConvertCoordToText(int t) {
3642 	switch (t) {
3643 		case 0:
3644 			return "CART";
3645 		case 1:
3646 			return "INT";
3647 	}
3648 	return "invalid";
3649 }
ConvertPolMethodToText(EFRAG_PolMethods t)3650 const char * EffectiveFragmentsGroup::ConvertPolMethodToText(EFRAG_PolMethods t) {
3651 	switch (t) {
3652 		case FRGSCF_PolMethod:
3653 			return "FRGSCF";
3654 		case SCF_PolMethod:
3655 			return "SCF";
3656 		default:
3657 			wxLogMessage(_T("Invalid Pol Method in ConvertPolMethodToText"));
3658 	}
3659 	return "invalid";
3660 }
ConvertPositionMethodToText(EFRAG_PositionTypes t)3661 const char * EffectiveFragmentsGroup::ConvertPositionMethodToText(EFRAG_PositionTypes t) {
3662 	switch (t) {
3663 		case Optimize_Position:
3664 			return "OPTIMIZE";
3665 		case Fixed_Position:
3666 			return "FIXED";
3667 		case EFOPT_Position:
3668 			return "EFOPT";
3669 		default:
3670 			wxLogMessage(_T("Invalid position method in ConvertPositionMethodToText"));
3671 	}
3672 	return "invalid";
3673 }
SetCoordinatesType(const char * tag)3674 bool EffectiveFragmentsGroup::SetCoordinatesType(const char * tag) {
3675 	if (!strcasecmp(tag, ConvertCoordToText(0))) {
3676 		UseCartesianCoordinates(true);
3677 		return true;
3678 	} else if (!strcasecmp(tag, ConvertCoordToText(1))) {
3679 		UseInternalCoordinates(true);
3680 		return true;
3681 	}
3682 	return false;
3683 }
SetPolMethod(const char * tag)3684 bool EffectiveFragmentsGroup::SetPolMethod(const char * tag) {
3685 	for (int i=FRGSCF_PolMethod; i<NumEFragPolMethods; i++) {
3686 		if (!strcasecmp(tag, ConvertPolMethodToText((EFRAG_PolMethods) i))) {
3687 			PolMethod((EFRAG_PolMethods) i);
3688 			return true;
3689 		}
3690 	}
3691 	return false;
3692 }
SetPositionType(const char * tag)3693 bool EffectiveFragmentsGroup::SetPositionType(const char * tag) {
3694 	for (int i=Optimize_Position; i<NumEFragPositionTypes; i++) {
3695 		if (!strcasecmp(tag, ConvertPositionMethodToText((EFRAG_PositionTypes) i))) {
3696 			PositionMethod((EFRAG_PositionTypes) i);
3697 			return true;
3698 		}
3699 	}
3700 	return false;
3701 }
WriteXML(XMLElement * parent) const3702 void EffectiveFragmentsGroup::WriteXML(XMLElement * parent) const {
3703 	//This group is only needed if there are non-default values
3704 	if (UseInternalCoordinates() || !PolMethodIsDefault() || !PositionIsDefault() ||
3705 		(MaxMOs >= 0) || (NumBufferMOs >= 0) || (MaxBasisFuncs>=0)) {
3706 
3707 		XMLElement * Ele = parent->addChildElement(CML_convert(MMP_IOEFPGroupElement));
3708 		if (UseInternalCoordinates())
3709 			Ele->addAttribute(CML_convert(MMP_IOEFPCoordType), GetGAMESSCoordText());
3710 		if (!PolMethodIsDefault())
3711 			Ele->addAttribute(CML_convert(MMP_IOEFPPolMethod), ConvertPolMethodToText(PolMethod()));
3712 		if (!PositionIsDefault())
3713 			Ele->addAttribute(CML_convert(MMP_IOEFPPosition), ConvertPositionMethodToText(PositionMethod()));
3714 		if (MaxMOs >= 0)
3715 			Ele->addAttribute(CML_convert(MMP_IOEFPMaxMOs), MaxMOs);
3716 		if (MaxBasisFuncs >= 0)
3717 			Ele->addAttribute(CML_convert(MMP_IOEFPMaxBasisFuncs), MaxBasisFuncs);
3718 		if (NumBufferMOs >= 0)
3719 			Ele->addAttribute(CML_convert(MMP_IOEFPNumBufferMOs), NumBufferMOs);
3720 	}
3721 }
ReadXML(XMLElement * parent)3722 void EffectiveFragmentsGroup::ReadXML(XMLElement * parent) {
3723 	const char * u = parent->getAttributeValue(CML_convert(MMP_IOEFPCoordType));
3724 	if (u) {
3725 		SetCoordinatesType(u);
3726 	}
3727 	u = parent->getAttributeValue(CML_convert(MMP_IOEFPPolMethod));
3728 	if (u) {
3729 		SetPolMethod(u);
3730 	}
3731 	u = parent->getAttributeValue(CML_convert(MMP_IOEFPPosition));
3732 	if (u) {
3733 		SetPositionType(u);
3734 	}
3735 	parent->getAttributeValue(CML_convert(MMP_IOEFPMaxMOs), MaxMOs);
3736 	parent->getAttributeValue(CML_convert(MMP_IOEFPMaxBasisFuncs), MaxBasisFuncs);
3737 	parent->getAttributeValue(CML_convert(MMP_IOEFPNumBufferMOs), NumBufferMOs);
3738 }
3739 
3740 #pragma mark FMOGroup
WriteToFile(BufferFile * File,MoleculeData * MainData)3741 void FMOGroup::WriteToFile(BufferFile *File, MoleculeData * MainData) {
3742 	char	Out[kMaxLineLength];
3743 
3744 	if (!IsFMOActive()) return;
3745 
3746 	//Punch the group label
3747 	File->WriteLine("!!!! Warning: FMO input is incomplete - you must complete by hand.", true);
3748 	File->WriteLine(" $FMO ", false);
3749 
3750 	sprintf(Out, "NFRAG=%ld ", GetNumberFragments());
3751 	File->WriteLine(Out, false);
3752 
3753 	//INDAT array
3754 	MainData->WriteINDAT(File);
3755 
3756 	File->WriteLine(" $END", true);
3757 }
WriteINDAT(BufferFile * Buffer)3758 void MoleculeData::WriteINDAT(BufferFile * Buffer) {
3759 	if (FMOFragmentIds.size() > 0) {
3760 		char	Out[kMaxLineLength];
3761 		Buffer->WriteLine("INDAT(1)=", false);
3762 		if (InputOptions->FMO.UseFragmentINDAT()) { //group by fragment
3763 			for (long ifrag=1; ifrag<=InputOptions->FMO.GetNumberFragments(); ifrag++) {
3764 				Buffer->WriteLine(" 0,",true);
3765 				Buffer->WriteLine("        ", false);
3766 				for (long iatom=0; iatom<FMOFragmentIds.size(); iatom++) {
3767 					if (FMOFragmentIds[iatom] == ifrag) {
3768 						sprintf(Out, " %ld,", iatom+1);
3769 						Buffer->WriteLine(Out, false);
3770 						//Now see how many atoms in a row are assigned to the same fragment
3771 						long jatom=0;
3772 						for (; (jatom+iatom)<FMOFragmentIds.size(); jatom++) {
3773 							if (FMOFragmentIds[iatom+jatom+1] != ifrag) break;
3774 						}
3775 						if (jatom>1) {
3776 							sprintf(Out, " -%ld,", iatom+jatom+1);
3777 							Buffer->WriteLine(Out, false);
3778 							iatom+=jatom;
3779 						}
3780 					}
3781 				}
3782 			}
3783 			Buffer->WriteLine(" 0",true);
3784 		} else {	//ordered by atom number
3785 			for (long iatom=0; iatom<(FMOFragmentIds.size() - 1); iatom++) {
3786 				sprintf(Out, " %ld,", FMOFragmentIds[iatom]);
3787 				Buffer->WriteLine(Out, false);
3788 			}
3789 			sprintf(Out, " %ld", FMOFragmentIds[FMOFragmentIds.size()-1]);
3790 			Buffer->WriteLine(Out, true);
3791 		}
3792 	}
3793 }
WriteXML(XMLElement * parent,MoleculeData * MainData) const3794 void FMOGroup::WriteXML(XMLElement * parent, MoleculeData * MainData) const {
3795 	//This group is only needed if there are non-default values
3796 	if (IsFMOActive() || (GetNumberFragments()>1)) {
3797 
3798 		XMLElement * Ele = parent->addChildElement(CML_convert(MMP_IOFMOGroupElement));
3799 		Ele->addBoolAttribute(CML_convert(MMP_IOFMOActiveFlag), IsFMOActive());
3800 		Ele->addBoolAttribute(CML_convert(MMP_IOFMOOutputStyleFlag), UseFragmentINDAT());
3801 		char line[kMaxLineLength];
3802 		snprintf(line, kMaxLineLength, "%ld", GetNumberFragments());
3803 		Ele->addChildElement(CML_convert(MMP_IOFMONumFragments), line);
3804 	//	snprintf(line, kMaxLineLength, "%ld", Newfunction());
3805 	//	Ele->addChildElement(CML_convert(MMP_IOFMONBODY), line);
3806 
3807 		MainData->WriteFMOIdsToXML(Ele);
3808 	}
3809 }
ReadXML(XMLElement * parent,MoleculeData * MainData)3810 void FMOGroup::ReadXML(XMLElement * parent, MoleculeData * MainData) {
3811 	bool tb;
3812 	if (parent->getAttributeValue(CML_convert(MMP_IOFMOActiveFlag), tb)) FMOActive(tb);
3813 	if (parent->getAttributeValue(CML_convert(MMP_IOFMOOutputStyleFlag), tb)) UseFragmentINDAT(tb);
3814 	XMLElementList * children = parent->getChildren();
3815 	if (children) {
3816 		for (int i=0; i<children->length(); i++) {
3817 			XMLElement * child = children->item(i);
3818 			MMP_IOFMOGroupNS item;
3819 			CML_Element cmlitem;
3820 			if (child && CML_convert(child->getName(), item)) {
3821 				switch (item) {
3822 					case MMP_IOFMONumFragments:
3823 					{
3824 						long temp;
3825 						if (child->getLongValue(temp)) {
3826 							SetNumberFragments(temp);
3827 						}
3828 					}
3829 						break;
3830 					default:
3831 					{
3832 						wxString msg;
3833 						msg.Printf(_T("Unknown FMO group CML element: %s"), child->getName());
3834 						wxLogMessage(msg);
3835 					}
3836 				}
3837 			} else if (child && CML_convert(child->getName(), cmlitem)) {
3838 				MainData->ReadFMOIdsFromXML(child);
3839 			}
3840 		}
3841 		delete children;
3842 	}
3843 }
WriteFMOIdsToXML(XMLElement * parent)3844 void MoleculeData::WriteFMOIdsToXML(XMLElement * parent) {
3845 	if (FMOFragmentIds.size() > 0) {
3846 		std::ostringstream buf;
3847 		for (unsigned int i=0; i<FMOFragmentIds.size(); i++) buf << FMOFragmentIds[i] << " ";
3848 		XMLElement * map = parent->addChildElement(CML_convert(ArrayElement),
3849 												   buf.str().c_str());
3850 		map->addAttribute(CML_convert(dataTypeAttr), "xsd:decimal"); //required for the matrix XML element
3851 		map->addAttribute(CML_convert(titleAttr), CML_convert(MMP_IOFMOFramentArray));
3852 		map->addAttribute(CML_convert(sizeAttr), FMOFragmentIds.size());
3853 	}
3854 }
ReadFMOIdsFromXML(XMLElement * item)3855 void MoleculeData::ReadFMOIdsFromXML(XMLElement * item) {
3856 	const char * attr = item->getAttributeValue(CML_convert(titleAttr));
3857 	MMP_IOFMOGroupNS title;
3858 	if (CML_convert(attr, title)) {
3859 		if (title == MMP_IOFMOFramentArray) {
3860 			long size;
3861 			if (item->getAttributeValue(CML_convert(sizeAttr), size)) {
3862 				FMOFragmentIds.reserve(size);
3863 				int nchar, pos=0;
3864 				const char * val = item->getValue();
3865 				for (int i=0; i<size; i++) {
3866 					long is;
3867 					if (sscanf(&(val[pos]), "%ld%n", &is, &nchar) != 1) throw DataError();
3868 					FMOFragmentIds.push_back(is);
3869 					pos += nchar;
3870 				}
3871 			}
3872 		}
3873 	}
3874 }
3875 
3876 #pragma mark StatPtGroup
InitData(void)3877 void StatPtGroup::InitData(void) {
3878 	OptConvergance = 0.0001f;
3879 	InitTrustRadius = 0.0f;
3880 	MaxTrustRadius = 0.0f;
3881 	MinTrustRadius = 0.05f;
3882 	StatJumpSize = 0.01f;
3883 	ModeFollow = 1;
3884 	BitOptions = 0;
3885 	method = 3;
3886 	MaxSteps = 20;
3887 	nRecalcHess = 0;
3888 	SetRadiusUpdate(true);
3889 }
GetMethodText(OptMethod type)3890 const char * StatPtGroup::GetMethodText(OptMethod type) {
3891 	switch (type) {
3892 		case StatPt_OptMethod_NR:
3893 			return "NR";
3894 		case StatPt_OptMethod_RFO:
3895 			return "RFO";
3896 		case StatPt_OptMethod_QA:
3897 			return "QA";
3898 		case StatPt_OptMethod_Schlegel:
3899 			return "SCHLEGEL";
3900 		case StatPt_OptMethod_ConOpt:
3901 			return "CONOPT";
3902 		default:
3903 			wxLogMessage(_T("Invalid method in GetMethodText"));
3904 	}
3905 	return "invalid";
3906 }
SetMethod(const char * text)3907 bool StatPtGroup::SetMethod(const char * text) {
3908 	for (int i=StatPt_OptMethod_NR; i<NumberStatPtOptMethods; i++) {
3909 		if (!strcasecmp(text, GetMethodText((OptMethod) i))) {
3910 			SetMethod(i);
3911 			return true;
3912 		}
3913 	}
3914 	return false;
3915 }
GetHessUpdateMethodText(HessUpdateMethod type)3916 const char * StatPtGroup::GetHessUpdateMethodText(HessUpdateMethod type) {
3917 	switch (type) {
3918 		case StatPt_HessUpdateMethod_Guess:
3919 			return "GUESS";
3920 		case StatPt_HessUpdateMethod_Read:
3921 			return "READ";
3922 		case StatPt_HessUpdateMethod_Calc:
3923 			return "CALC";
3924 		default:
3925 			wxLogMessage(_T("Invalid hess update in GetHessUpdateMethodText"));
3926 	}
3927 	return "invalid";
3928 }
SetHessMethod(const char * text)3929 bool StatPtGroup::SetHessMethod(const char * text) {
3930 	for (int i=StatPt_HessUpdateMethod_Guess; i<NumberStatPtHessUpdateMethods; i++) {
3931 		if (!strcasecmp(text, GetHessUpdateMethodText((HessUpdateMethod) i))) {
3932 			SetHessMethod(i);
3933 			return true;
3934 		}
3935 	}
3936 	return false;
3937 }
WriteToFile(BufferFile * File,InputData * IData)3938 void StatPtGroup::WriteToFile(BufferFile *File, InputData *IData) {
3939 	char	Out[133];
3940 
3941 	short runType = IData->Control->GetRunType();
3942 		//first determine wether or not the statpt group needs to be punched
3943 	if ((runType != OptimizeRun)&&(runType != SadPointRun)&&
3944 		(runType != G3MP2)) return;	//only punch for optimize and sadpoint runs
3945 
3946 		//Punch the group label
3947 	File->WriteLine(" $STATPT ", false);
3948 		//write out the convergance criteria and number of steps by default, just
3949 		//to remind the user of their values. Everything else is optional.
3950 	sprintf(Out, "OPTTOL=%g ", GetOptConvergance());
3951 	File->WriteLine(Out, false);
3952 	sprintf(Out, "NSTEP=%d ", GetMaxSteps());
3953 	File->WriteLine(Out, false);
3954 		//Method
3955 	if (GetMethod() != 3) {
3956 		sprintf(Out, "Method=%s ", GetMethodText((OptMethod) GetMethod()));
3957 		File->WriteLine(Out, false);
3958 	}	//DXMAX if non-default and method is not NR
3959 	if ((GetInitRadius() != 0.0)&&(GetMethod() !=1)) {
3960 		sprintf(Out, "DXMAX=%g ", GetInitRadius());
3961 		File->WriteLine(Out, false);
3962 	}
3963 	if ((GetMethod()==2)||(GetMethod()==3)) {
3964 		if (!GetRadiusUpdate()) File->WriteLine("TRUPD=.FALSE. ", false);
3965 		if (GetMaxRadius() != 0.0) {
3966 			sprintf(Out, "TRMAX=%g ", GetMaxRadius());
3967 			File->WriteLine(Out, false);
3968 		}
3969 		if (fabs(GetMinRadius() - 0.05)>1e-5) {
3970 			sprintf(Out, "TRMIN=%g ", GetMinRadius());
3971 			File->WriteLine(Out, false);
3972 		}
3973 	}
3974 	if ((runType == 6)&&(GetModeFollow() != 1)) {
3975 		sprintf(Out, "IFOLOW=%ld ", GetModeFollow());
3976 		File->WriteLine(Out, false);
3977 	}
3978 	if (GetStatPoint()) {
3979 		File->WriteLine("STPT=.TRUE. ", false);
3980 		if (fabs(GetStatJump() - 0.01)>1e-5) {
3981 			sprintf(Out, "STSTEP=%g ", GetStatJump());
3982 			File->WriteLine(Out, false);
3983 		}
3984 	}
3985 	if (GetHessMethod()) {
3986 		sprintf(Out, "HESS=%s ", GetHessUpdateMethodText((HessUpdateMethod) GetHessMethod()));
3987 		File->WriteLine(Out, false);
3988 	}
3989 	if (GetHessRecalcInterval()) {
3990 		sprintf(Out, "IHREP=%d ", GetHessRecalcInterval());
3991 		File->WriteLine(Out, false);
3992 	}
3993 	if (AlwaysPrintOrbs()) {
3994 		File->WriteLine("NPRT=1 ", false);
3995 	}
3996 	if (GetHessEndFlag())
3997 		File->WriteLine("HSSEND=.t. ", false);
3998 
3999 	File->WriteLine("$END", true);
4000 	//When HESS=READ emit a warning so the user knows they must manually add the $HESS group
4001 	if ((GetHessMethod() == StatPt_HessUpdateMethod_Read)||
4002 		((GetHessMethod()==0)&&(runType == SadPointRun))) {
4003 		MessageAlert("You must manually add a $HESS group to the input file!");
4004 		File->WriteLine("! A $HESS group must be manually added to this file!", true);
4005 	}
4006 }
WriteXML(XMLElement * parent) const4007 void StatPtGroup::WriteXML(XMLElement * parent) const {
4008 	char line[kMaxLineLength];
4009 	XMLElement * Ele = parent->addChildElement(CML_convert(MMP_IOStatPtGroupElement));
4010 	snprintf(line, kMaxLineLength, "%f", OptConvergance);
4011 	Ele->addChildElement(CML_convert(MMP_IOSPGOptConvergance), line);
4012 	snprintf(line, kMaxLineLength, "%f", InitTrustRadius);
4013 	Ele->addChildElement(CML_convert(MMP_IOSPGInitTrustRadius), line);
4014 	snprintf(line, kMaxLineLength, "%f", MaxTrustRadius);
4015 	Ele->addChildElement(CML_convert(MMP_IOSPGMaxTrustRadius), line);
4016 	snprintf(line, kMaxLineLength, "%f", MinTrustRadius);
4017 	Ele->addChildElement(CML_convert(MMP_IOSPGMinTrustRadius), line);
4018 	snprintf(line, kMaxLineLength, "%f", StatJumpSize);
4019 	Ele->addChildElement(CML_convert(MMP_IOSPGStatJumpSize), line);
4020 	snprintf(line, kMaxLineLength, "%ld", ModeFollow);
4021 	Ele->addChildElement(CML_convert(MMP_IOSPGModeFollow), line);
4022 	if (GetRadiusUpdate()) Ele->addChildElement(CML_convert(MMP_IOSPGRadiusUpdate), trueXML);
4023 	if (GetStatPoint()) Ele->addChildElement(CML_convert(MMP_IOSPGStatPoint), trueXML);
4024 	snprintf(line, kMaxLineLength, "%d", GetHessMethod());
4025 	Ele->addChildElement(CML_convert(MMP_IOSPGHessMethod), line);
4026 	snprintf(line, kMaxLineLength, "%d", method);
4027 	Ele->addChildElement(CML_convert(MMP_IOSPGMethod), line);
4028 	snprintf(line, kMaxLineLength, "%d", MaxSteps);
4029 	Ele->addChildElement(CML_convert(MMP_IOSPGMaxSteps), line);
4030 	snprintf(line, kMaxLineLength, "%d", nRecalcHess);
4031 	Ele->addChildElement(CML_convert(MMP_IOSPGnRecalcHess), line);
4032 	if (AlwaysPrintOrbs()) Ele->addChildElement(CML_convert(MMP_IOSPGAlwaysPrintOrbs), trueXML);
4033 	if (GetHessEndFlag()) Ele->addChildElement(CML_convert(MMP_IOSPGHessEnd), trueXML);
4034 }
ReadXML(XMLElement * parent)4035 void StatPtGroup::ReadXML(XMLElement * parent) {
4036 	XMLElementList * children = parent->getChildren();
4037 	if (children) {
4038 		for (int i=0; i<children->length(); i++) {
4039 			XMLElement * child = children->item(i);
4040 			MMP_IOStatPtGroupNS item;
4041 			if (child && CML_convert(child->getName(), item)) {
4042 				bool tb;
4043 				switch (item) {
4044 					case MMP_IOSPGOptConvergance:
4045 					{
4046 						double temp;
4047 						if (child->getDoubleValue(temp)) {
4048 							SetOptConvergance(temp);
4049 						}
4050 					}
4051 						break;
4052 					case MMP_IOSPGInitTrustRadius:
4053 					{
4054 						double temp;
4055 						if (child->getDoubleValue(temp)) {
4056 							SetInitRadius(temp);
4057 						}
4058 					}
4059 						break;
4060 					case MMP_IOSPGMaxTrustRadius:
4061 					{
4062 						double temp;
4063 						if (child->getDoubleValue(temp)) {
4064 							SetMaxRadius(temp);
4065 						}
4066 					}
4067 						break;
4068 					case MMP_IOSPGMinTrustRadius:
4069 					{
4070 						double temp;
4071 						if (child->getDoubleValue(temp)) {
4072 							SetMinRadius(temp);
4073 						}
4074 					}
4075 						break;
4076 					case MMP_IOSPGStatJumpSize:
4077 					{
4078 						double temp;
4079 						if (child->getDoubleValue(temp)) {
4080 							SetStatJump(temp);
4081 						}
4082 					}
4083 						break;
4084 					case MMP_IOSPGModeFollow:
4085 					{
4086 						long temp;
4087 						if (child->getLongValue(temp)) {
4088 							SetModeFollow(temp);
4089 						}
4090 					}
4091 						break;
4092 					case MMP_IOSPGRadiusUpdate:
4093 						if (child->getBoolValue(tb))
4094 							SetRadiusUpdate(tb);
4095 						break;
4096 					case MMP_IOSPGStatPoint:
4097 						if (child->getBoolValue(tb))
4098 							SetStatPoint(tb);
4099 						break;
4100 					case MMP_IOSPGHessMethod:
4101 					{
4102 						long temp;
4103 						if (child->getLongValue(temp)) {
4104 							SetHessMethod(temp);
4105 						}
4106 					}
4107 						break;
4108 					case MMP_IOSPGMethod:
4109 					{
4110 						long temp;
4111 						if (child->getLongValue(temp)) {
4112 							SetMethod(temp);
4113 						}
4114 					}
4115 						break;
4116 					case MMP_IOSPGMaxSteps:
4117 					{
4118 						long temp;
4119 						if (child->getLongValue(temp)) {
4120 							SetMaxSteps(temp);
4121 						}
4122 					}
4123 						break;
4124 					case MMP_IOSPGnRecalcHess:
4125 					{
4126 						long temp;
4127 						if (child->getLongValue(temp)) {
4128 							SetHessRecalcInterval(temp);
4129 						}
4130 					}
4131 						break;
4132 					case MMP_IOSPGAlwaysPrintOrbs:
4133 						if (child->getBoolValue(tb))
4134 							SetAlwaysPrintOrbs(tb);
4135 						break;
4136 					case MMP_IOSPGHessEnd:
4137 						if (child->getBoolValue(tb))
4138 							SetHessFlag(tb);
4139 						break;
4140 					default:
4141 					{
4142 						wxString msg;
4143 						msg.Printf(_T("Unknown StatPt group CML element: %s"), child->getName());
4144 						wxLogMessage(msg);
4145 					}
4146 				}
4147 			}
4148 		}
4149 		delete children;
4150 	}
4151 }
4152 
GetNumElectrons(void) const4153 long MoleculeData::GetNumElectrons(void) const {
4154 	long result=cFrame->GetNumElectrons();
4155 	if (InputOptions && InputOptions->Control) result -= InputOptions->Control->GetCharge();
4156 	return result;
4157 }
GetMultiplicity(void) const4158 short MoleculeData::GetMultiplicity(void) const {
4159 	short result=1;
4160 	if (InputOptions && InputOptions->Control) result = InputOptions->Control->GetMultiplicity();
4161 	return result;
4162 }
GetInputData(void)4163 InputData * MoleculeData::GetInputData(void) {
4164 	if (!InputOptions) InputOptions = new InputData;
4165 	if (!InputOptions) throw MemoryError();
4166 	return InputOptions;
4167 }
SetInputData(InputData * NewData)4168 InputData * MoleculeData::SetInputData(InputData * NewData) {
4169 	if (InputOptions) delete InputOptions;
4170 	InputOptions = new InputData(NewData);
4171 	return InputOptions;
4172 }
WriteInputFile(MolDisplayWin * owner)4173 void MoleculeData::WriteInputFile(MolDisplayWin * owner) {
4174 	if (InputOptions) {
4175 		InputOptions->WriteInputFile(this, owner);
4176 	}
4177 }
WriteEditInputFile(MolDisplayWin * owner)4178 void MoleculeData::WriteEditInputFile(MolDisplayWin * owner) {
4179 	if (InputOptions) {
4180 		InputOptions->WriteEditInputFile(this, owner);
4181 	}
4182 }
WriteZMATToFile(BufferFile * File)4183 void MOPacInternals::WriteZMATToFile(BufferFile * File) {
4184 	char	Out[133];
4185 
4186 	File->WriteLine(" $ZMAT IZMAT(1)=", false);
4187 	for (long i=3; i<Count; i+=3) {
4188 		if (i>9) File->WriteLine(", ", false);
4189 		sprintf(Out, "1,%ld,%ld, ", (i+3)/3, ConnectionAtoms[i]+1);
4190 		File->WriteLine(Out, false);
4191 		if (i>3) {
4192 			sprintf(Out, "2,%ld,%ld,%ld, ", (i+3)/3, ConnectionAtoms[i]+1, ConnectionAtoms[i+1]+1);
4193 			File->WriteLine(Out, false);
4194 			if (i>6) {
4195 				sprintf(Out, "3,%ld,%ld,%ld,%ld", (i+3)/3, ConnectionAtoms[i]+1,
4196 					ConnectionAtoms[i+1]+1, ConnectionAtoms[i+2]+1);
4197 				File->WriteLine(Out, false);
4198 			}
4199 		}
4200 	}
4201 	File->WriteLine(" $END", true);
4202 }
WriteCoordinatesToFile(BufferFile * File,MoleculeData * MainData,WinPrefs * Prefs)4203 void MOPacInternals::WriteCoordinatesToFile(BufferFile * File, MoleculeData * MainData, WinPrefs * Prefs) {
4204 	UpdateAtoms(MainData);	//First make sure the connectivity and values are up to date
4205 	CartesiansToInternals(MainData);
4206 	float unitConversion = 1.0f;
4207 	InputData * lOptions = MainData->GetInputData();
4208 	if (lOptions && lOptions->Data->GetUnits()) unitConversion = kAng2BohrConversion;
4209 		char	Out[133];
4210 		Str255	AtomLabel;
4211 		Frame *	cFrame = MainData->GetCurrentFramePtr();
4212 
4213 	for (int iatom=0; iatom<cFrame->NumAtoms; iatom++) {
4214 		Prefs->GetAtomLabel(cFrame->Atoms[iatom].GetType()-1, AtomLabel);
4215 		AtomLabel[AtomLabel[0]+1] = 0;
4216 		if (iatom==0) sprintf(Out, "%s", (char *) &(AtomLabel[1]));
4217 		else if (iatom == 1)
4218 			sprintf(Out, "%s  %ld %10.5f", (char *) &(AtomLabel[1]),
4219 				ConnectionAtoms[3*iatom]+1, Values[3*iatom]*unitConversion);
4220 		else if (iatom == 2)
4221 			sprintf(Out, "%s   %ld %10.5f  %ld %8.4f",
4222 				(char *) &(AtomLabel[1]), ConnectionAtoms[3*iatom]+1, Values[3*iatom]*unitConversion,
4223 				ConnectionAtoms[3*iatom+1]+1, Values[3*iatom+1]);
4224 		else
4225 			sprintf(Out, "%s   %ld %10.5f  %ld %8.4f  %ld %8.4f",
4226 				(char *) &(AtomLabel[1]), ConnectionAtoms[3*iatom]+1, Values[3*iatom]*unitConversion,
4227 				ConnectionAtoms[3*iatom+1]+1, Values[3*iatom+1],
4228 				ConnectionAtoms[3*iatom+2]+1, Values[3*iatom+2]);
4229 		File->WriteLine(Out, true);
4230 	}
4231 }
4232 //This if very similar to the prevous function, but the format is a little different
WriteMPCZMatCoordinatesToFile(BufferFile * File,MoleculeData * MainData,WinPrefs * Prefs)4233 void MOPacInternals::WriteMPCZMatCoordinatesToFile(BufferFile * File, MoleculeData * MainData, WinPrefs * Prefs) {
4234 	UpdateAtoms(MainData);	//First make sure the connectivity and values are up to date
4235 	CartesiansToInternals(MainData);
4236 	float unitConversion = 1.0f;
4237 	InputData * lOptions = MainData->GetInputData();
4238 	if (lOptions && lOptions->Data->GetUnits()) unitConversion = kAng2BohrConversion;
4239 	char	Out[133];
4240 	Str255	AtomLabel;
4241 	Frame *	cFrame = MainData->GetCurrentFramePtr();
4242 
4243 	for (int iatom=0; iatom<cFrame->NumAtoms; iatom++) {
4244 		Prefs->GetAtomLabel(cFrame->Atoms[iatom].GetType()-1, AtomLabel);
4245 		AtomLabel[AtomLabel[0]+1] = 0;
4246 		if (iatom==0) sprintf(Out, "%s", (char *) &(AtomLabel[1]));
4247 		else if (iatom == 1)
4248 			sprintf(Out, "%s   %10.5f", (char *) &(AtomLabel[1]),
4249 					Values[3*iatom]*unitConversion);
4250 		else if (iatom == 2)
4251 			sprintf(Out, "%s   %10.5f 0 %8.4f 0 %ld %ld",
4252 					(char *) &(AtomLabel[1]), Values[3*iatom]*unitConversion,
4253 					Values[3*iatom+1], ConnectionAtoms[3*iatom]+1, ConnectionAtoms[3*iatom+1]+1);
4254 		else
4255 			sprintf(Out, "%s   %10.5f 0 %8.4f 0 %8.4f 0 %ld %ld %ld",
4256 					(char *) &(AtomLabel[1]), Values[3*iatom]*unitConversion, Values[3*iatom+1],
4257 					Values[3*iatom+2], ConnectionAtoms[3*iatom]+1,
4258 					ConnectionAtoms[3*iatom+1]+1, ConnectionAtoms[3*iatom+2]+1);
4259 		File->WriteLine(Out, true);
4260 	}
4261 }
WriteVecGroup(BufferFile * File,const long & NumBasisFuncs,const long & OrbCount) const4262 void OrbitalRec::WriteVecGroup(BufferFile * File, const long & NumBasisFuncs, const long & OrbCount) const {
4263 //First check for and write out the vec label
4264 	if (Label) {	//The label should include any necessary linefeeds
4265 		File->WriteLine(Label, true);
4266 	}
4267 //Punch the Group title
4268 	File->WriteLine(" $VEC", true);
4269 //write out the vectors using the GAMESS format (I2,I3,5E15.8)
4270 #ifdef _MSC_VER
4271 	//Visual studio defaults to using 3 digit exponent output which doesn't fit in the field
4272 	//This function changes that behavior to 2 digits.
4273 	_set_output_format(_TWO_DIGIT_EXPONENT);
4274 #endif
4275 		long iline, nVec, nn, nOrbs, pOrb;
4276 	if ((OrbCount > 0) && (OrbCount <= NumAlphaOrbs)) nOrbs = OrbCount;
4277 	else nOrbs = NumAlphaOrbs;
4278 		char	Line[kMaxLineLength];
4279 		float * Vector=Vectors;
4280 	for (int ipass=0; ipass<2; ipass++) {
4281 		if (!Vector) {
4282 			File->WriteLine("Error in Vectors request!", true);
4283 			return;
4284 		}
4285 		nn = 0;	pOrb = 0;
4286 		for (long i=0; i<nOrbs; i++) {
4287 			iline = 1;	nVec = 0;
4288 			pOrb++;
4289 			if (pOrb>=100) pOrb -= 100;
4290 			sprintf(Line, "%2ld%3ld", pOrb, iline);
4291 			File->WriteLine(Line, false);
4292 			for (long ivec=0; ivec<NumBasisFuncs; ivec++) {
4293 				sprintf(Line, "%15.8E", Vector[nn]);
4294 				nn++;
4295 				File->WriteLine(Line, false);
4296 				nVec++;
4297 				if ((nVec>=5)&&(ivec+1<NumBasisFuncs)) {//wrap line and start the next line
4298 					File->WriteLine("", true);
4299 					iline ++;
4300 					sprintf(Line, "%2ld%3ld", pOrb, iline);
4301 					File->WriteLine(Line, false);
4302 					nVec = 0;
4303 				}
4304 			}
4305 			File->WriteLine("", true);
4306 		}
4307 		if (BaseWavefunction == UHF) {	//Repeat for beta set of orbitals for UHF wavefunctions
4308 			Vector = VectorsB;
4309 			if ((OrbCount > 0) && (OrbCount <= NumBetaOrbs)) nOrbs = OrbCount;
4310 			else nOrbs = NumBetaOrbs;
4311 		} else ipass++;
4312 	}
4313 //finish off the group
4314 	File->WriteLine(" $END", true);
4315 }
4316 
4317