3
* $Date: 2007-01-04 18:46:10 +0100 (Thu, 04 Jan 2007) $
6
* Copyright (C) 2003-2007 The Chemistry Development Kit (CDK) project
8
* Contact: cdk-devel@lists.sourceforge.net
10
* This library is free software; you can redistribute it and/or
11
* modify it under the terms of the GNU Lesser General Public
12
* License as published by the Free Software Foundation; either
13
* version 2.1 of the License, or (at your option) any later version.
15
* This library is distributed in the hope that it will be useful,
16
* but WITHOUT ANY WARRANTY; without even the implied warranty of
17
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18
* Lesser General Public License for more details.
20
* You should have received a copy of the GNU Lesser General Public
21
* License along with this library; if not, write to the Free Software
22
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
24
package org.openscience.cdk.io.program;
26
import java.io.BufferedWriter;
27
import java.io.IOException;
28
import java.io.OutputStream;
29
import java.io.OutputStreamWriter;
30
import java.io.StringWriter;
31
import java.io.Writer;
32
import java.util.Vector;
34
import javax.vecmath.Point3d;
36
import org.openscience.cdk.exception.CDKException;
37
import org.openscience.cdk.interfaces.IAtom;
38
import org.openscience.cdk.interfaces.IChemObject;
39
import org.openscience.cdk.interfaces.IMolecule;
40
import org.openscience.cdk.io.DefaultChemObjectWriter;
41
import org.openscience.cdk.io.formats.GaussianInputFormat;
42
import org.openscience.cdk.io.formats.IResourceFormat;
43
import org.openscience.cdk.io.setting.BooleanIOSetting;
44
import org.openscience.cdk.io.setting.IOSetting;
45
import org.openscience.cdk.io.setting.IntegerIOSetting;
46
import org.openscience.cdk.io.setting.OptionIOSetting;
47
import org.openscience.cdk.io.setting.StringIOSetting;
50
* File writer thats generates input files for Gaussian calculation
51
* jobs. It was tested with Gaussian98.
55
* @author Egon Willighagen <egonw@sci.kun.nl>
57
* @cdk.keyword Gaussian (tm), input file
59
public class GaussianInputWriter extends DefaultChemObjectWriter {
61
static BufferedWriter writer;
68
BooleanIOSetting shell;
69
IntegerIOSetting proccount;
70
BooleanIOSetting usecheckpoint;
73
* Constructs a new writer that produces input files to run a
76
public GaussianInputWriter(Writer out) {
78
if (out instanceof BufferedWriter) {
79
writer = (BufferedWriter)out;
81
writer = new BufferedWriter(out);
83
} catch (Exception exc) {
88
public GaussianInputWriter(OutputStream output) {
89
this(new OutputStreamWriter(output));
92
public GaussianInputWriter() {
93
this(new StringWriter());
96
public IResourceFormat getFormat() {
97
return GaussianInputFormat.getInstance();
100
public void setWriter(Writer out) throws CDKException {
101
if (out instanceof BufferedWriter) {
102
writer = (BufferedWriter)out;
104
writer = new BufferedWriter(out);
108
public void setWriter(OutputStream output) throws CDKException {
109
setWriter(new OutputStreamWriter(output));
112
public void close() throws IOException {
116
public boolean accepts(Class classObject) {
117
if (IMolecule.class.isInstance(classObject)) return true;
121
public void write(IChemObject object) throws CDKException {
122
if (object instanceof IMolecule) {
124
writeMolecule((IMolecule)object);
125
} catch(Exception ex) {
126
throw new CDKException("Error while writing Gaussian input file: " + ex.getMessage(), ex);
129
throw new CDKException("GaussianInputWriter only supports output of Molecule classes.");
134
* Writes a molecule for input for Gaussian.
136
public void writeMolecule(IMolecule mol) throws IOException {
140
// write extra statements
141
if (proccount.getSettingValue() > 1) {
142
writer.write("%nprocl=" + proccount.getSettingValue());
145
if (!memory.getSetting().equals("unset")) {
146
writer.write("%Mem=" + memory.getSetting());
149
if (usecheckpoint.isSet()) {
150
if (mol.getID() != null && mol.getID().length() > 0) {
151
writer.write("%chk=" + mol.getID() + ".chk");
153
// force different file names
154
writer.write("%chk=" + System.currentTimeMillis() + ".chk");
159
// write the command line
160
writer.write("# " + method.getSetting() +
161
"/" + basis.getSetting() +
163
String commandString = command.getSetting();
164
if (commandString.equals("energy calculation")) {
165
// ok, no special command needed
166
} else if (commandString.equals("geometry optimization")) {
168
} else if (commandString.equals("IR frequency calculation")) {
169
writer.write("freq");
170
} else if (commandString.equals("IR frequency calculation (with Raman)")) {
171
writer.write("freq=noraman");
173
// assume that user knows what he's doing
174
writer.write(commandString);
178
// next line is empty
181
// next line is comment
182
writer.write(comment.getSetting() + "\n");
184
// next line is empty
187
/* next line contains two digits
188
* the first is the total charge
189
* the second is boolean indicating:
193
writer.write("0 "); // FIXME: should write total charge of molecule
201
// then come all the atoms.
202
// Loop through the atoms and write them out:
203
java.util.Iterator atoms = mol.atoms();
204
while (atoms.hasNext()) {
205
IAtom a = (IAtom)atoms.next();
206
String st = a.getSymbol();
208
// export Eucledian coordinates (indicated by the 0)
211
// export the 3D coordinates
212
Point3d p3 = a.getPoint3d();
214
st = st + new Double(p3.x).toString() + " "
215
+ new Double(p3.y).toString() + " "
216
+ new Double(p3.z).toString();
219
writer.write(st, 0, st.length());
223
// G98 expects an empty line at the end
227
private void initIOSettings() {
228
Vector basisOptions = new Vector();
229
basisOptions.add("6-31g");
230
basisOptions.add("6-31g*");
231
basisOptions.add("6-31g(d)");
232
basisOptions.add("6-311g");
233
basisOptions.add("6-311+g**");
234
basis = new OptionIOSetting("Basis", IOSetting.MEDIUM,
235
"Which basis set do you want to use?", basisOptions, "6-31g");
237
Vector methodOptions = new Vector();
238
methodOptions.add("rb3lyp");
239
methodOptions.add("b3lyp");
240
methodOptions.add("rhf");
241
method = new OptionIOSetting("Method", IOSetting.MEDIUM,
242
"Which method do you want to use?", methodOptions, "b3lyp");
244
Vector commandOptions = new Vector();
245
commandOptions.add("energy calculation");
246
commandOptions.add("geometry optimization");
247
commandOptions.add("IR frequency calculation");
248
commandOptions.add("IR frequency calculation (with Raman)");
249
command = new OptionIOSetting("Command", IOSetting.HIGH,
250
"What kind of job do you want to perform?", commandOptions,
251
"energy calculation");
253
comment = new StringIOSetting("Comment", IOSetting.LOW,
254
"What comment should be put in the file?",
255
"Created with CDK (http://cdk.sf.net/)");
257
memory = new StringIOSetting("Memory", IOSetting.LOW,
258
"How much memory do you want to use?",
261
shell = new BooleanIOSetting("OpenShell", IOSetting.MEDIUM,
262
"Should the calculation be open shell?",
265
proccount = new IntegerIOSetting("ProcessorCount", IOSetting.LOW,
266
"How many processors should be used by Gaussian?",
269
usecheckpoint = new BooleanIOSetting("UseCheckPointFile", IOSetting.LOW,
270
"Should a check point file be saved?",
274
private void customizeJob() {
275
fireIOSettingQuestion(basis);
276
fireIOSettingQuestion(method);
277
fireIOSettingQuestion(command);
278
fireIOSettingQuestion(comment);
279
fireIOSettingQuestion(shell);
280
fireIOSettingQuestion(proccount);
281
fireIOSettingQuestion(memory);
282
fireIOSettingQuestion(usecheckpoint);
285
public IOSetting[] getIOSettings() {
286
IOSetting[] settings = new IOSetting[8];
288
settings[1] = method;
289
settings[2] = command;
290
settings[3] = comment;
292
settings[5] = proccount;
293
settings[6] = usecheckpoint;
294
settings[7] = memory;